From 36d48224b57436e0dc4c3a115f6bf9914e1da78f Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Wed, 26 Jun 2019 09:10:03 +0200 Subject: [PATCH 01/11] fix: error log message. --- pkg/provider/docker/config.go | 2 +- pkg/provider/marathon/config.go | 2 +- pkg/provider/rancher/config.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/provider/docker/config.go b/pkg/provider/docker/config.go index ccb293820..ac179b096 100644 --- a/pkg/provider/docker/config.go +++ b/pkg/provider/docker/config.go @@ -126,7 +126,7 @@ func (p *Provider) keepContainer(ctx context.Context, container dockerData) bool matches, err := constraints.Match(container.Labels, p.Constraints) if err != nil { - logger.Error("Error matching constraints expression: %v", err) + logger.Errorf("Error matching constraints expression: %v", err) return false } if !matches { diff --git a/pkg/provider/marathon/config.go b/pkg/provider/marathon/config.go index 84f98b256..1624390af 100644 --- a/pkg/provider/marathon/config.go +++ b/pkg/provider/marathon/config.go @@ -186,7 +186,7 @@ func (p *Provider) keepApplication(ctx context.Context, extraConf configuration, // Filter by constraints. matches, err := constraints.Match(labels, p.Constraints) if err != nil { - logger.Error("Error matching constraints expression: %v", err) + logger.Errorf("Error matching constraints expression: %v", err) return false } if !matches { diff --git a/pkg/provider/rancher/config.go b/pkg/provider/rancher/config.go index 3eeae9a37..3eb15ee69 100644 --- a/pkg/provider/rancher/config.go +++ b/pkg/provider/rancher/config.go @@ -123,7 +123,7 @@ func (p *Provider) keepService(ctx context.Context, service rancherData) bool { matches, err := constraints.Match(service.Labels, p.Constraints) if err != nil { - logger.Error("Error matching constraints expression: %v", err) + logger.Errorf("Error matching constraints expression: %v", err) return false } if !matches { From 96962dd21f14944fb5599985a8da8a1cdac5655f Mon Sep 17 00:00:00 2001 From: mpl Date: Wed, 26 Jun 2019 14:14:05 +0200 Subject: [PATCH 02/11] Handle cross-provider middleware in kubernetes CRD Co-authored-by: Julien Salleyron --- docs/content/middlewares/overview.md | 77 +++---- docs/content/providers/kubernetes-crd.md | 21 +- integration/testdata/rawdata-crd.json | 46 ++-- .../with_middleware_crossprovider.yml | 47 +++++ pkg/provider/kubernetes/crd/kubernetes.go | 30 ++- .../kubernetes/crd/kubernetes_test.go | 198 +++++++++++------- 6 files changed, 273 insertions(+), 146 deletions(-) create mode 100644 pkg/provider/kubernetes/crd/fixtures/with_middleware_crossprovider.yml diff --git a/docs/content/middlewares/overview.md b/docs/content/middlewares/overview.md index d359af96d..335a824ca 100644 --- a/docs/content/middlewares/overview.md +++ b/docs/content/middlewares/overview.md @@ -79,32 +79,6 @@ labels: - "traefik.http.router.router1.Middlewares=foo-add-prefix@rancher" ``` -```yaml tab="Kubernetes" -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: tlsoptions.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: TLSOption - plural: tlsoptions - singular: tlsoption - scope: Namespaced - ---- -apiVersion: traefik.containo.us/v1alpha1 -kind: TLSOption -metadata: - name: mytlsoption - namespace: default - -spec: - minversion: VersionTLS12 -``` - ```toml tab="File" # As Toml Configuration File [providers] @@ -133,35 +107,66 @@ spec: When you declare a middleware, it lives in its provider namespace. For example, if you declare a middleware using a Docker label, under the hoods, it will reside in the docker provider namespace. -If you use multiple providers and wish to reference a middleware declared in another provider, -then you'll have to prefix the middleware name with the provider name. +If you use multiple providers and wish to reference a middleware declared in another provider +(aka referencing a cross-provider middleware), +then you'll have to append to the middleware name, the `@` separator, followed by the provider name. ```text @ ``` +!!! important "Kubernetes Namespace" + + As Kubernetes also has its own notion of namespace, one should not confuse the "provider namespace" +with the "kubernetes namespace" of a resource when in the context of a cross-provider usage. +In this case, since the definition of the middleware is not in kubernetes, +specifying a "kubernetes namespace" when referring to the resource does not make any sense, +and therefore this specification would be ignored even if present. + !!! abstract "Referencing a Middleware from Another Provider" Declaring the add-foo-prefix in the file provider. ```toml [providers] - [providers.file] + [providers.file] [http.middlewares] - [http.middlewares.add-foo-prefix.AddPrefix] + [http.middlewares.add-foo-prefix.AddPrefix] prefix = "/foo" ``` - Using the add-foo-prefix middleware from docker. + Using the add-foo-prefix middleware from other providers: - ```yaml + ```yaml tab="Docker" your-container: # - image: your-docker-image + image: your-docker-image - labels: - # Attach add-foo-prefix@file middleware (declared in file) - - "traefik.http.routers.my-container.middlewares=add-foo-prefix@file" + labels: + # Attach add-foo-prefix@file middleware (declared in file) + - "traefik.http.routers.my-container.middlewares=add-foo-prefix@file" + ``` + + ```yaml tab="Kubernetes" + apiVersion: traefik.containo.us/v1alpha1 + kind: IngressRoute + metadata: + name: ingressroutestripprefix + + spec: + entryPoints: + - web + routes: + - match: Host(`bar.com`) + kind: Rule + services: + - name: whoami + port: 80 + middlewares: + - name: add-foo-prefix@file + # namespace: bar + # A namespace specification such as above is ignored + # when the cross-provider syntax is used. ``` ## Available Middlewares diff --git a/docs/content/providers/kubernetes-crd.md b/docs/content/providers/kubernetes-crd.md index 53f6617a2..95a2885e8 100644 --- a/docs/content/providers/kubernetes-crd.md +++ b/docs/content/providers/kubernetes-crd.md @@ -203,6 +203,7 @@ apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: stripprefix + namespace: foo spec: stripPrefix: @@ -226,13 +227,21 @@ spec: port: 80 middlewares: - name: stripprefix + namespace: foo ``` +!!! important "Cross-provider namespace" + + As Kubernetes also has its own notion of namespace, one should not confuse the kubernetes namespace of a resource +(in the reference to the middleware) with the [provider namespace](../middlewares/overview.md#provider-namespace), +when the definition of the middleware is from another provider. +In this context, specifying a namespace when referring to the resource does not make any sense, and will be ignored. + More information about available middlewares in the dedicated [middlewares section](../middlewares/overview.md). -### Traefik TLS Option Definition +### TLS Option -Additionally, to allow for the use of tls options in an IngressRoute, we defined the CRD below for the TLSOption kind. +Additionally, to allow for the use of TLS options in an IngressRoute, we defined the CRD below for the TLSOption kind. More information about TLS Options is available in the dedicated [TLS Configuration Options](../../https/tls/#tls-options). ```yaml @@ -272,9 +281,15 @@ spec: namespace: default ``` -!!! note "TLS Option reference and namespace" +!!! important "References and namespaces" + If the optional `namespace` attribute is not set, the configuration will be applied with the namespace of the IngressRoute. + Additionally, when the definition of the TLS option is from another provider, +the cross-provider syntax (`middlewarename@provider`) should be used to refer to the TLS option, +just as in the [middleware case](../middlewares/overview.md#provider-namespace). +Specifying a namespace attribute in this case would not make any sense, and will be ignored. + ### TLS To allow for TLS, we made use of the `Secret` kind, as it was already defined, and it can be directly used in an `IngressRoute`: diff --git a/integration/testdata/rawdata-crd.json b/integration/testdata/rawdata-crd.json index abab62087..3e09587f5 100644 --- a/integration/testdata/rawdata-crd.json +++ b/integration/testdata/rawdata-crd.json @@ -1,24 +1,24 @@ { "routers": { - "default/test-crd-6b204d94623b3df4370c@kubernetescrd": { + "default/test.crd-6b204d94623b3df4370c@kubernetescrd": { "entryPoints": [ "web" ], - "service": "default/test-crd-6b204d94623b3df4370c", + "service": "default/test.crd-6b204d94623b3df4370c", "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/bar`)", "priority": 12, "tls": { "options": "default/mytlsoption" } }, - "default/test2-crd-23c7f4c450289ee29016@kubernetescrd": { + "default/test2.crd-23c7f4c450289ee29016@kubernetescrd": { "entryPoints": [ "web" ], "middlewares": [ "default/stripprefix" ], - "service": "default/test2-crd-23c7f4c450289ee29016", + "service": "default/test2.crd-23c7f4c450289ee29016", "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/tobestripped`)" } }, @@ -30,58 +30,58 @@ ] }, "usedBy": [ - "default/test2-crd-23c7f4c450289ee29016@kubernetescrd" + "default/test2.crd-23c7f4c450289ee29016@kubernetescrd" ] } }, "services": { - "default/test-crd-6b204d94623b3df4370c@kubernetescrd": { + "default/test.crd-6b204d94623b3df4370c@kubernetescrd": { "loadbalancer": { "servers": [ { - "url": "http://10.42.0.2:80" + "url": "http://10.42.0.3:80" }, { - "url": "http://10.42.0.6:80" + "url": "http://10.42.0.5:80" } ], "passHostHeader": true }, "usedBy": [ - "default/test-crd-6b204d94623b3df4370c@kubernetescrd" + "default/test.crd-6b204d94623b3df4370c@kubernetescrd" ], "serverStatus": { - "http://10.42.0.2:80": "UP", - "http://10.42.0.6:80": "UP" + "http://10.42.0.3:80": "UP", + "http://10.42.0.5:80": "UP" } }, - "default/test2-crd-23c7f4c450289ee29016@kubernetescrd": { + "default/test2.crd-23c7f4c450289ee29016@kubernetescrd": { "loadbalancer": { "servers": [ { - "url": "http://10.42.0.2:80" + "url": "http://10.42.0.3:80" }, { - "url": "http://10.42.0.6:80" + "url": "http://10.42.0.5:80" } ], "passHostHeader": true }, "usedBy": [ - "default/test2-crd-23c7f4c450289ee29016@kubernetescrd" + "default/test2.crd-23c7f4c450289ee29016@kubernetescrd" ], "serverStatus": { - "http://10.42.0.2:80": "UP", - "http://10.42.0.6:80": "UP" + "http://10.42.0.3:80": "UP", + "http://10.42.0.5:80": "UP" } } }, "tcpRouters": { - "default/test3-crd-673acf455cb2dab0b43a@kubernetescrd": { + "default/test3.crd-673acf455cb2dab0b43a@kubernetescrd": { "entryPoints": [ "footcp" ], - "service": "default/test3-crd-673acf455cb2dab0b43a", + "service": "default/test3.crd-673acf455cb2dab0b43a", "rule": "HostSNI(`*`)", "tls": { "passthrough": false, @@ -90,19 +90,19 @@ } }, "tcpServices": { - "default/test3-crd-673acf455cb2dab0b43a@kubernetescrd": { + "default/test3.crd-673acf455cb2dab0b43a@kubernetescrd": { "loadbalancer": { "servers": [ { - "address": "10.42.0.3:8080" + "address": "10.42.0.4:8080" }, { - "address": "10.42.0.4:8080" + "address": "10.42.0.6:8080" } ] }, "usedBy": [ - "default/test3-crd-673acf455cb2dab0b43a@kubernetescrd" + "default/test3.crd-673acf455cb2dab0b43a@kubernetescrd" ] } } diff --git a/pkg/provider/kubernetes/crd/fixtures/with_middleware_crossprovider.yml b/pkg/provider/kubernetes/crd/fixtures/with_middleware_crossprovider.yml new file mode 100644 index 000000000..799953da8 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_middleware_crossprovider.yml @@ -0,0 +1,47 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: stripprefix + namespace: default + +spec: + stripPrefix: + prefixes: + - /tobestripped + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: addprefix + namespace: foo + +spec: + addPrefix: + prefix: /tobeadded + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: test2.crd + namespace: default + +spec: + entryPoints: + - web + + routes: + - match: Host(`foo.com`) && PathPrefix(`/tobestripped`) + priority: 12 + kind: Rule + services: + - name: whoami + port: 80 + middlewares: + - name: stripprefix + - name: addprefix + namespace: foo + - name: basicauth@file + - name: redirect@file + namespace: foo diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index c950b29ea..a18781d69 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -395,13 +395,18 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli allServers = append(allServers, servers...) } - // TODO: support middlewares from other providers. - // Mechanism: in the spec, prefix the name with the provider name, - // with dot as the separator. In which case. we ignore the - // namespace. - var mds []string for _, mi := range route.Middlewares { + if strings.Contains(mi.Name, "@") { + if len(mi.Namespace) > 0 { + logger. + WithField(log.MiddlewareName, mi.Name). + Warnf("namespace %q is ignored in cross-provider context", mi.Namespace) + } + mds = append(mds, mi.Name) + continue + } + ns := mi.Namespace if len(ns) == 0 { ns = ingressRoute.Namespace @@ -429,13 +434,17 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli tlsConf := &config.RouterTLSConfig{} if ingressRoute.Spec.TLS.Options != nil && len(ingressRoute.Spec.TLS.Options.Name) > 0 { tlsOptionsName := ingressRoute.Spec.TLS.Options.Name - // Is a Kubernetes CRD reference, (i.e. not a cross-provider default) + // Is a Kubernetes CRD reference, (i.e. not a cross-provider reference) + ns := ingressRoute.Spec.TLS.Options.Namespace if !strings.Contains(tlsOptionsName, "@") { - ns := ingressRoute.Spec.TLS.Options.Namespace if len(ns) == 0 { ns = ingressRoute.Namespace } tlsOptionsName = makeID(ns, tlsOptionsName) + } else if len(ns) > 0 { + logger. + WithField("TLSoptions", ingressRoute.Spec.TLS.Options.Name). + Warnf("namespace %q is ignored in cross-provider context", ns) } tlsConf.Options = tlsOptionsName @@ -527,12 +536,16 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client if ingressRouteTCP.Spec.TLS.Options != nil && len(ingressRouteTCP.Spec.TLS.Options.Name) > 0 { tlsOptionsName := ingressRouteTCP.Spec.TLS.Options.Name // Is a Kubernetes CRD reference (i.e. not a cross-provider reference) + ns := ingressRouteTCP.Spec.TLS.Options.Namespace if !strings.Contains(tlsOptionsName, "@") { - ns := ingressRouteTCP.Spec.TLS.Options.Namespace if len(ns) == 0 { ns = ingressRouteTCP.Namespace } tlsOptionsName = makeID(ns, tlsOptionsName) + } else if len(ns) > 0 { + logger. + WithField("TLSoptions", ingressRouteTCP.Spec.TLS.Options.Name). + Warnf("namespace %q is ignored in cross-provider context", ns) } conf.Routers[serviceName].TLS.Options = tlsOptionsName @@ -573,7 +586,6 @@ func makeServiceKey(rule, ingressName string) (string, error) { return "", err } - ingressName = strings.ReplaceAll(ingressName, ".", "-") key := fmt.Sprintf("%s-%.10x", ingressName, h.Sum(nil)) return key, nil diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 37ae2da3f..c8df41c86 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -44,14 +44,14 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -75,19 +75,19 @@ func TestLoadIngressRouteTCPs(t *testing.T) { expected: &config.Configuration{ TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", }, - "default/test-crd-f44ce589164e656d231c": { + "default/test.crd-f44ce589164e656d231c": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-f44ce589164e656d231c", + Service: "default/test.crd-f44ce589164e656d231c", Rule: "HostSNI(`bar.com`)", }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -101,7 +101,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, - "default/test-crd-f44ce589164e656d231c": { + "default/test.crd-f44ce589164e656d231c": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -130,14 +130,14 @@ func TestLoadIngressRouteTCPs(t *testing.T) { expected: &config.Configuration{ TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -227,15 +227,15 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", TLS: &config.RouterTCPTLSConfig{}, }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -264,9 +264,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) { expected: &config.Configuration{ TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", TLS: &config.RouterTCPTLSConfig{ Passthrough: true, @@ -274,7 +274,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -320,9 +320,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", TLS: &config.RouterTCPTLSConfig{ Options: "default/foo", @@ -330,7 +330,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -376,9 +376,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", TLS: &config.RouterTCPTLSConfig{ Options: "myns/foo", @@ -386,7 +386,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -431,9 +431,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", TLS: &config.RouterTCPTLSConfig{ Options: "default/foo", @@ -441,7 +441,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -475,9 +475,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", TLS: &config.RouterTCPTLSConfig{ Options: "default/unknown", @@ -485,7 +485,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -519,9 +519,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", TLS: &config.RouterTCPTLSConfig{ Options: "unknown/foo", @@ -529,7 +529,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -558,15 +558,15 @@ func TestLoadIngressRouteTCPs(t *testing.T) { expected: &config.Configuration{ TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-fdd3e9338e47a45efefc", + Service: "default/test.crd-fdd3e9338e47a45efefc", Rule: "HostSNI(`foo.com`)", TLS: &config.RouterTCPTLSConfig{}, }, }, Services: map[string]*config.TCPService{ - "default/test-crd-fdd3e9338e47a45efefc": { + "default/test.crd-fdd3e9338e47a45efefc": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { @@ -639,16 +639,16 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, }, }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -675,9 +675,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test2-crd-23c7f4c450289ee29016": { + "default/test2.crd-23c7f4c450289ee29016": { EntryPoints: []string{"web"}, - Service: "default/test2-crd-23c7f4c450289ee29016", + Service: "default/test2.crd-23c7f4c450289ee29016", Rule: "Host(`foo.com`) && PathPrefix(`/tobestripped`)", Priority: 12, Middlewares: []string{"default/stripprefix", "foo/addprefix"}, @@ -696,7 +696,55 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, Services: map[string]*config.Service{ - "default/test2-crd-23c7f4c450289ee29016": { + "default/test2.crd-23c7f4c450289ee29016": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://10.10.0.1:80", + }, + { + URL: "http://10.10.0.2:80", + }, + }, + PassHostHeader: true, + }, + }, + }, + }, + }, + }, + { + desc: "Simple Ingress Route with middleware crossprovider", + paths: []string{"services.yml", "with_middleware_crossprovider.yml"}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "default/test2.crd-23c7f4c450289ee29016": { + EntryPoints: []string{"web"}, + Service: "default/test2.crd-23c7f4c450289ee29016", + Rule: "Host(`foo.com`) && PathPrefix(`/tobestripped`)", + Priority: 12, + Middlewares: []string{"default/stripprefix", "foo/addprefix", "basicauth@file", "redirect@file"}, + }, + }, + Middlewares: map[string]*config.Middleware{ + "default/stripprefix": { + StripPrefix: &config.StripPrefix{ + Prefixes: []string{"/tobestripped"}, + }, + }, + "foo/addprefix": { + AddPrefix: &config.AddPrefix{ + Prefix: "/tobeadded", + }, + }, + }, + Services: map[string]*config.Service{ + "default/test2.crd-23c7f4c450289ee29016": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -723,22 +771,22 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Priority: 14, }, - "default/test-crd-77c62dfe9517144aeeaa": { + "default/test.crd-77c62dfe9517144aeeaa": { EntryPoints: []string{"web"}, - Service: "default/test-crd-77c62dfe9517144aeeaa", + Service: "default/test.crd-77c62dfe9517144aeeaa", Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", Priority: 12, }, }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -751,7 +799,7 @@ func TestLoadIngressRoutes(t *testing.T) { PassHostHeader: true, }, }, - "default/test-crd-77c62dfe9517144aeeaa": { + "default/test.crd-77c62dfe9517144aeeaa": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -778,16 +826,16 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-77c62dfe9517144aeeaa": { + "default/test.crd-77c62dfe9517144aeeaa": { EntryPoints: []string{"web"}, - Service: "default/test-crd-77c62dfe9517144aeeaa", + Service: "default/test.crd-77c62dfe9517144aeeaa", Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", Priority: 12, }, }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-77c62dfe9517144aeeaa": { + "default/test.crd-77c62dfe9517144aeeaa": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -889,9 +937,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{}, @@ -899,7 +947,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -943,9 +991,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{ @@ -955,7 +1003,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -999,9 +1047,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{ @@ -1011,7 +1059,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -1054,9 +1102,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{ @@ -1066,7 +1114,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -1098,9 +1146,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{ @@ -1110,7 +1158,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -1142,9 +1190,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{ @@ -1154,7 +1202,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -1181,9 +1229,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{}, @@ -1191,7 +1239,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { @@ -1218,16 +1266,16 @@ func TestLoadIngressRoutes(t *testing.T) { }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { EntryPoints: []string{"foo"}, - Service: "default/test-crd-6b204d94623b3df4370c", + Service: "default/test.crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, }, }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test-crd-6b204d94623b3df4370c": { + "default/test.crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { From e69d4cba880ecc070ba94ae08805d63ea6c94d71 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Wed, 26 Jun 2019 18:18:04 +0200 Subject: [PATCH 03/11] Support YAML for the dynamic configuration. --- .../getting-started/configuration-overview.md | 7 +- docs/content/providers/file.md | 122 +++++- .../reference/dynamic-configuration/file.md | 8 +- .../reference/dynamic-configuration/file.yaml | 294 ++++++++++++++ .../reference/static-configuration/file.md | 8 +- .../reference/static-configuration/file.toml | 6 +- .../reference/static-configuration/file.yaml | 240 +++++++++++ docs/content/routing/overview.md | 164 ++++++-- pkg/config/dyn_config.go | 2 +- pkg/config/file/file_node.go | 6 +- pkg/config/middlewares.go | 42 +- pkg/provider/file/file.go | 94 +++-- pkg/provider/file/file_test.go | 375 +++++++++--------- .../file/fixtures/toml/dir01_file01.toml | 7 + .../file/fixtures/toml/dir01_file02.toml | 13 + .../file/fixtures/toml/dir01_file03.toml | 16 + .../file/fixtures/toml/simple_file_01.toml | 55 +++ .../file/fixtures/toml/simple_file_02.toml | 62 +++ .../fixtures/toml/simple_traefik_file_01.toml | 3 + .../fixtures/toml/simple_traefik_file_02.toml | 38 ++ .../simple_traefik_file_with_templating.toml | 39 ++ .../file/fixtures/toml/template_file.toml | 6 + .../toml/template_in_directory_file01.toml | 5 + .../toml/template_in_directory_file02.toml | 6 + pkg/provider/file/fixtures/toml/tls_file.cert | 1 + .../file/fixtures/yaml/dir01_file01.yml | 6 + .../file/fixtures/yaml/dir01_file02.yml | 14 + .../file/fixtures/yaml/dir01_file03.yml | 13 + .../file/fixtures/yaml/simple_file_01.yml | 50 +++ .../file/fixtures/yaml/simple_file_02.yml | 58 +++ .../fixtures/yaml/simple_traefik_file_01.yml | 2 + .../fixtures/yaml/simple_traefik_file_02.yml | 35 ++ .../file/fixtures/yaml/template_file.yml | 6 + .../yaml/template_in_directory_file01.yml | 6 + .../yaml/template_in_directory_file02.yml | 8 + pkg/provider/file/fixtures/yaml/tls_file.cert | 1 + 36 files changed, 1529 insertions(+), 289 deletions(-) create mode 100644 docs/content/reference/dynamic-configuration/file.yaml create mode 100644 docs/content/reference/static-configuration/file.yaml create mode 100644 pkg/provider/file/fixtures/toml/dir01_file01.toml create mode 100644 pkg/provider/file/fixtures/toml/dir01_file02.toml create mode 100644 pkg/provider/file/fixtures/toml/dir01_file03.toml create mode 100644 pkg/provider/file/fixtures/toml/simple_file_01.toml create mode 100644 pkg/provider/file/fixtures/toml/simple_file_02.toml create mode 100644 pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml create mode 100644 pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml create mode 100644 pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml create mode 100644 pkg/provider/file/fixtures/toml/template_file.toml create mode 100644 pkg/provider/file/fixtures/toml/template_in_directory_file01.toml create mode 100644 pkg/provider/file/fixtures/toml/template_in_directory_file02.toml create mode 100644 pkg/provider/file/fixtures/toml/tls_file.cert create mode 100644 pkg/provider/file/fixtures/yaml/dir01_file01.yml create mode 100644 pkg/provider/file/fixtures/yaml/dir01_file02.yml create mode 100644 pkg/provider/file/fixtures/yaml/dir01_file03.yml create mode 100644 pkg/provider/file/fixtures/yaml/simple_file_01.yml create mode 100644 pkg/provider/file/fixtures/yaml/simple_file_02.yml create mode 100644 pkg/provider/file/fixtures/yaml/simple_traefik_file_01.yml create mode 100644 pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml create mode 100644 pkg/provider/file/fixtures/yaml/template_file.yml create mode 100644 pkg/provider/file/fixtures/yaml/template_in_directory_file01.yml create mode 100644 pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml create mode 100644 pkg/provider/file/fixtures/yaml/tls_file.cert diff --git a/docs/content/getting-started/configuration-overview.md b/docs/content/getting-started/configuration-overview.md index 864b5dc2c..2a8861488 100644 --- a/docs/content/getting-started/configuration-overview.md +++ b/docs/content/getting-started/configuration-overview.md @@ -49,7 +49,12 @@ Once positioned, this option sets (and resets) all the default values of the sub ### Configuration File -At startup, Traefik searches for a file named `traefik.toml` in `/etc/traefik/`, `$XDG_CONFIG_HOME/`, `$HOME/.config/`, and `.` (_the working directory_). +At startup, Traefik searches for a file named `traefik.toml` (or `traefik.yml` or `traefik.yaml`) in: + +- `/etc/traefik/` +- `$XDG_CONFIG_HOME/` +- `$HOME/.config/` +- `.` (_the working directory_). You can override this using the `configFile` argument. diff --git a/docs/content/providers/file.md b/docs/content/providers/file.md index 3740f5ba6..8c2033568 100644 --- a/docs/content/providers/file.md +++ b/docs/content/providers/file.md @@ -3,10 +3,10 @@ Good Old Configuration File {: .subtitle } -The file provider lets you define the [dynamic configuration](./overview.md) in a `toml` file. +The file provider lets you define the [dynamic configuration](./overview.md) in a TOML or YAML file. You can write these configuration elements: -* At the end of the main Traefik configuration file (by default: `traefik.toml`). +* At the end of the main Traefik configuration file (by default: `traefik.toml`/`traefik.yml`/`traefik.yaml`). * In [a dedicated file](#filename) * In [several dedicated files](#directory) @@ -20,10 +20,20 @@ You can write these configuration elements: ??? example "Declaring Routers, Middlewares & Services" - ``` toml - # Enabling the file provider - [providers.file] + Enabling the file provider: + ```toml tab="TOML" + [providers.file] + ``` + + ```yaml tab="YAML" + providers: + file: {} + ``` + + Declaring Routers, Middlewares & Services: + + ```toml tab="TOML" [http] # Add the router [http.routers] @@ -49,6 +59,32 @@ You can write these configuration elements: [[http.services.service-foo.LoadBalancer.Servers]] url = "http://bar/" ``` + + ```yaml tab="YAML" + http: + routers: + router0: + entrypoints: + - web + middlewares: + - my-basic-auth + service: service-foo + rule: Path(`foo`) + middlewares: + my-basic-auth: + basicAuth: + users: + - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ + - test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0 + usersfile: etc/traefik/.htpasswd + headerfield: "" + services: + service-foo: + loadbalancer: + servers: + - url: http://foo/ + - url: http://bar/ + ``` ## Provider Configuration Options @@ -61,24 +97,36 @@ _Optional_ Defines the path of the configuration file. -```toml +```toml tab="TOML" [providers] [providers.file] filename = "rules.toml" ``` +```yaml tab="YAML" +providers: + file: + filename: rules.yaml +``` + ### `directory` _Optional_ Defines the directory that contains the configuration files. -```toml +```toml tab="TOML" [providers] [providers.file] directory = "/path/to/config" ``` +```yaml tab="YAML" +providers: + file: + directory: /path/to/config +``` + ### `watch` _Optional_ @@ -86,24 +134,32 @@ _Optional_ Set the `watch` option to `true` to allow Traefik to automatically watch for file changes. It works with both the `filename` and the `directory` options. -```toml +```toml tab="TOML" [providers] [providers.file] filename = "rules.toml" watch = true ``` -### TOML Templating +```yaml tab="YAML" +providers: + file: + filename: rules.yml + watch: true +``` + +### Go Templating !!! warning - TOML templating only works along with dedicated configuration files. Templating does not work in the Traefik main configuration file. + Go Templating only works along with dedicated configuration files. + Templating does not work in the Traefik main configuration file. -Traefik allows using TOML templating. +Traefik allows using Go templating. Thus, it's possible to define easily lot of routers, services and TLS certificates as described in the file `template-rules.toml` : ??? example "Configuring Using Templating" - - ```toml + + ```toml tab="TOML" # template-rules.toml [http] @@ -149,3 +205,43 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat # ... {{ end }} ``` + + ```yaml tab="YAML" + http: + + {{range $i, $e := until 100 }} + routers: + router{{ $e }: + # ... + {{end}} + + {{range $i, $e := until 100 }} + services: + application{{ $e }}: + # ... + {{end}} + + tcp: + + {{range $i, $e := until 100 }} + routers: + router{{ $e }: + # ... + {{end}} + + {{range $i, $e := until 100 }} + services: + service{{ $e }}: + # ... + {{end}} + + {{ range $i, $e := until 10 }} + tls: + store: + - "my-store-foo-{{ $e }}" + - "my-store-bar-{{ $e }}" + certificate: + certfile: "/etc/traefik/cert-{{ $e }}.pem" + keyfile: "/etc/traefik/cert-{{ $e }}.key" + {{end}} + ``` diff --git a/docs/content/reference/dynamic-configuration/file.md b/docs/content/reference/dynamic-configuration/file.md index 8afa5796e..754e6d35d 100644 --- a/docs/content/reference/dynamic-configuration/file.md +++ b/docs/content/reference/dynamic-configuration/file.md @@ -1,8 +1,12 @@ # File Configuration Reference -Dynamic configuration with toml files +Dynamic configuration with files {: .subtitle } -```toml +```toml tab="TOML" --8<-- "content/reference/dynamic-configuration/file.toml" ``` + +```yml tab="YAML" +--8<-- "content/reference/dynamic-configuration/file.yaml" +``` diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml new file mode 100644 index 000000000..0587df582 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -0,0 +1,294 @@ +http: + routers: + Router0: + entrypoints: + - foobar + - foobar + middlewares: + - foobar + - foobar + service: foobar + rule: foobar + priority: 42 + tls: + options: TLS0 + middlewares: + Middleware0: + addPrefix: + prefix: foobar + Middleware1: + stripPrefix: + prefixes: + - foobar + - foobar + Middleware2: + stripPrefixRegex: + regex: + - foobar + - foobar + Middleware3: + replacePath: + path: foobar + Middleware4: + replacePathRegex: + regex: foobar + replacement: foobar + Middleware5: + chain: + middlewares: + - foobar + - foobar + Middleware6: + ipWhiteList: + sourcerange: + - foobar + - foobar + ipstrategy: null + Middleware7: + ipWhiteList: + sourcerange: [] + ipstrategy: + depth: 42 + excludedips: + - foobar + - foobar + Middleware8: + headers: + customrequestheaders: + name0: foobar + name1: foobar + customresponseheaders: + name0: foobar + name1: foobar + accesscontrolallowcredentials: true + accesscontrolallowheaders: + - foobar + - foobar + accesscontrolallowmethods: + - foobar + - foobar + accesscontrolalloworigin: foobar + accesscontrolexposeheaders: + - foobar + - foobar + accesscontrolmaxage: 42 + addvaryheader: true + allowedhosts: + - foobar + - foobar + hostsproxyheaders: + - foobar + - foobar + sslredirect: true + ssltemporaryredirect: true + sslhost: foobar + sslproxyheaders: + name0: foobar + name1: foobar + sslforcehost: true + stsseconds: 42 + stsincludesubdomains: true + stspreload: true + forcestsheader: true + framedeny: true + customframeoptionsvalue: foobar + contenttypenosniff: true + browserxssfilter: true + custombrowserxssvalue: foobar + contentsecuritypolicy: foobar + publickey: foobar + referrerpolicy: foobar + isdevelopment: true + Middleware9: + errors: + status: + - foobar + - foobar + service: foobar + query: foobar + Middleware10: + rateLimit: + rateset: + Rate0: + period: 42000000000 + average: 42 + burst: 42 + Rate1: + period: 42000000000 + average: 42 + burst: 42 + extractorfunc: foobar + Middleware11: + redirectRegex: + regex: foobar + replacement: foobar + permanent: true + Middleware12: + redirectScheme: + scheme: foobar + port: foobar + permanent: true + Middleware13: + basicAuth: + users: + - foobar + - foobar + usersfile: foobar + realm: foobar + removeheader: true + headerfield: foobar + Middleware14: + digestAuth: + users: + - foobar + - foobar + usersfile: foobar + removeheader: true + realm: foobar + headerfield: foobar + Middleware15: + forwardAuth: + address: foobar + tls: + ca: foobar + caoptional: true + cert: foobar + key: foobar + insecureskipverify: true + trustforwardheader: true + authresponseheaders: + - foobar + - foobar + Middleware16: + maxConn: + amount: 42 + extractorfunc: foobar + Middleware17: + buffering: + maxrequestbodybytes: 42 + memrequestbodybytes: 42 + maxresponsebodybytes: 42 + memresponsebodybytes: 42 + retryexpression: foobar + Middleware18: + circuitBreaker: + expression: foobar + Middleware19: + compress: {} + Middleware20: + passTLSClientCert: + pem: true + info: + notafter: true + notbefore: true + sans: true + subject: + country: true + province: true + locality: true + organization: true + commonname: true + serialnumber: true + domaincomponent: true + issuer: + country: true + province: true + locality: true + organization: true + commonname: true + serialnumber: true + domaincomponent: true + Middleware21: + retry: + attempts: 42 + services: + Service0: + loadbalancer: + stickiness: + cookiename: foobar + securecookie: false + httponlycookie: false + servers: + - url: foobar + scheme: "" + port: "" + - url: foobar + scheme: "" + port: "" + healthcheck: + scheme: foobar + path: foobar + port: 42 + interval: foobar + timeout: foobar + hostname: foobar + headers: + name0: foobar + name1: foobar + passhostheader: true + responseforwarding: + flushinterval: foobar +tcp: + routers: + TCPRouter0: + entrypoints: + - foobar + - foobar + service: foobar + rule: foobar + tls: + passthrough: true + options: TLS1 + services: + TCPService0: + loadbalancer: + servers: + - address: foobar + port: "" + - address: foobar + port: "" +tls: + - stores: + - foobar + - foobar + certificate: + certfile: foobar + keyfile: foobar + - stores: + - foobar + - foobar + certificate: + certfile: foobar + keyfile: foobar +tlsoptions: + TLS0: + minversion: foobar + ciphersuites: + - foobar + - foobar + clientca: + files: + - foobar + - foobar + optional: true + snistrict: true + TLS1: + minversion: foobar + ciphersuites: + - foobar + - foobar + clientca: + files: + - foobar + - foobar + optional: true + snistrict: true +tlsstores: + Store0: + defaultcertificate: + certfile: foobar + keyfile: foobar + Store1: + defaultcertificate: + certfile: foobar + keyfile: foobar diff --git a/docs/content/reference/static-configuration/file.md b/docs/content/reference/static-configuration/file.md index c103de7f7..6fa3daf4f 100644 --- a/docs/content/reference/static-configuration/file.md +++ b/docs/content/reference/static-configuration/file.md @@ -1,7 +1,9 @@ # Static Configuration: File -## TOML - -```toml +```toml tab="TOML" --8<-- "content/reference/static-configuration/file.toml" ``` + +```yml tab="YAML" +--8<-- "content/reference/static-configuration/file.yaml" +``` diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index da26229c5..b0ec36369 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -133,16 +133,16 @@ [Metrics.Datadog] Address = "foobar" - PushInterval = "foobar" + PushInterval = "10s" [Metrics.StatsD] Address = "foobar" - PushInterval = "foobar" + PushInterval = "10s" [Metrics.InfluxDB] Address = "foobar" Protocol = "foobar" - PushInterval = "foobar" + PushInterval = "10s" Database = "foobar" RetentionPolicy = "foobar" Username = "foobar" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml new file mode 100644 index 000000000..b616be96a --- /dev/null +++ b/docs/content/reference/static-configuration/file.yaml @@ -0,0 +1,240 @@ +global: + checknewversion: true + sendanonymoususage: true +serverstransport: + insecureskipverify: true + rootcas: + - foobar + - foobar + maxidleconnsperhost: 42 + forwardingtimeouts: + dialtimeout: 42000000000 + responseheadertimeout: 42000000000 +entrypoints: + EntryPoint0: + address: foobar + transport: + lifecycle: + requestacceptgracetimeout: 42000000000 + gracetimeout: 42000000000 + respondingtimeouts: + readtimeout: 42000000000 + writetimeout: 42000000000 + idletimeout: 42000000000 + proxyprotocol: + insecure: true + trustedips: + - foobar + - foobar + forwardedheaders: + insecure: true + trustedips: + - foobar + - foobar +providers: + providersthrottleduration: 42000000000 + docker: + constraints: foobar + watch: true + endpoint: foobar + defaultrule: foobar + tls: + ca: foobar + caoptional: true + cert: foobar + key: foobar + insecureskipverify: true + exposedbydefault: true + usebindportip: true + swarmmode: true + network: foobar + swarmmoderefreshseconds: 42000000000 + file: + directory: foobar + watch: true + filename: foobar + debugloggeneratedtemplate: true + traefikfile: foobar + marathon: + constraints: foobar + trace: true + watch: true + endpoint: foobar + defaultrule: foobar + exposedbydefault: true + dcostoken: foobar + tls: + ca: foobar + caoptional: true + cert: foobar + key: foobar + insecureskipverify: true + dialertimeout: 42000000000 + responseheadertimeout: 42000000000 + tlshandshaketimeout: 42000000000 + keepalive: 42000000000 + forcetaskhostname: true + basic: + httpbasicauthuser: foobar + httpbasicpassword: foobar + respectreadinesschecks: true + kubernetes: + endpoint: foobar + token: foobar + certauthfilepath: foobar + disablepasshostheaders: true + namespaces: + - foobar + - foobar + labelselector: foobar + ingressclass: foobar + ingressendpoint: + ip: foobar + hostname: foobar + publishedservice: foobar + kubernetescrd: + endpoint: foobar + token: foobar + certauthfilepath: foobar + disablepasshostheaders: true + namespaces: + - foobar + - foobar + labelselector: foobar + ingressclass: foobar + rest: + entrypoint: foobar + rancher: + constraints: foobar + watch: true + defaultrule: foobar + exposedbydefault: true + enableservicehealthfilter: true + refreshseconds: 42 + intervalpoll: true + prefix: foobar +api: + entrypoint: foobar + dashboard: true + debug: false + statistics: + recenterrors: 42 + middlewares: + - foobar + - foobar + dashboardassets: null +metrics: + prometheus: + buckets: + - 42 + - 42 + entrypoint: foobar + middlewares: + - foobar + - foobar + datadog: + address: foobar + pushinterval: 10000000000 + statsd: + address: foobar + pushinterval: 10000000000 + influxdb: + address: foobar + protocol: foobar + pushinterval: 10000000000 + database: foobar + retentionpolicy: foobar + username: foobar + password: foobar +ping: + entrypoint: foobar + middlewares: + - foobar + - foobar +log: + level: foobar + filepath: foobar + format: foobar +accesslog: + filepath: foobar + format: foobar + filters: + statuscodes: + - foobar + - foobar + retryattempts: true + minduration: 42000000000 + fields: + defaultmode: foobar + names: + name0: foobar + name1: foobar + headers: + defaultmode: foobar + names: + name0: foobar + name1: foobar + bufferingsize: 42 +tracing: + backend: foobar + servicename: foobar + spannamelimit: 42 + jaeger: + samplingserverurl: foobar + samplingtype: foobar + samplingparam: 42 + localagenthostport: foobar + gen128bit: true + propagation: foobar + tracecontextheadername: foobar + zipkin: + httpendpoint: foobar + samespan: true + id128bit: true + debug: true + samplerate: 42 + datadog: + localagenthostport: foobar + globaltag: foobar + debug: true + prioritysampling: true + traceidheadername: foobar + parentidheadername: foobar + samplingpriorityheadername: foobar + bagageprefixheadername: foobar + instana: + localagenthost: foobar + localagentport: 42 + loglevel: foobar + haystack: null +hostresolver: + cnameflattening: true + resolvconfig: foobar + resolvdepth: 42 +acme: + email: foobar + acmelogging: true + caserver: foobar + storage: foobar + entrypoint: foobar + keytype: foobar + onhostrule: true + dnschallenge: + provider: foobar + delaybeforecheck: 42000000000 + resolvers: + - foobar + - foobar + disablepropagationcheck: true + httpchallenge: + entrypoint: foobar + tlschallenge: {} + domains: + - main: foobar + sans: + - foobar + - foobar + - main: foobar + sans: + - foobar + - foobar diff --git a/docs/content/routing/overview.md b/docs/content/routing/overview.md index 8fbb01242..072b93f01 100644 --- a/docs/content/routing/overview.md +++ b/docs/content/routing/overview.md @@ -24,29 +24,79 @@ If they do, the router might transform the request using pieces of [middleware]( Below is an example of a full configuration file for the [file provider](../providers/file.md) that forwards `http://domain/whoami/` requests to a service reachable on `http://private/whoami-service/`. In the process, Traefik will make sure that the user is authenticated (using the [BasicAuth middleware](../middlewares/basicauth.md)). -```toml +Static configuration: + +```toml tab="TOML" [entryPoints] - [entryPoints.web] - address = ":8081" # Listen on port 8081 for incoming requests + [entryPoints.web] + # Listen on port 8081 for incoming requests + address = ":8081" [providers] - [providers.file] # Enable the file provider to define routers / middlewares / services in a file + # Enable the file provider to define routers / middlewares / services in a file + [providers.file] +``` -[http] # http routing section - [http.routers] - [http.routers.to-whoami] # Define a connection between requests and services - rule = "Host(domain) && PathPrefix(/whoami/)" - middlewares = ["test-user"] # If the rule matches, applies the middleware - service = "whoami" # If the rule matches, forward to the whoami service (declared below) +```yaml tab="YAML" +entrypoints: + web: + # Listen on port 8081 for incoming requests + address: :8081 +providers: + # Enable the file provider to define routers / middlewares / services in a file + file: {} +``` - [http.middlewares] - [http.middlewares.test-user.basicauth] # Define an authentication mechanism - users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] +Dynamic configuration: - [http.services] - [http.services.whoami.loadbalancer] # Define how to reach an existing service on our infrastructure - [[http.services.whoami.loadbalancer.servers]] - url = "http://private/whoami-service" +```toml tab="TOML" +# http routing section +[http] + [http.routers] + # Define a connection between requests and services + [http.routers.to-whoami] + rule = "Host(`domain`) && PathPrefix(`/whoami/`)" + # If the rule matches, applies the middleware + middlewares = ["test-user"] + # If the rule matches, forward to the whoami service (declared below) + service = "whoami" + + [http.middlewares] + # Define an authentication mechanism + [http.middlewares.test-user.basicauth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] + + [http.services] + # Define how to reach an existing service on our infrastructure + [http.services.whoami.loadbalancer] + [[http.services.whoami.loadbalancer.servers]] + url = "http://private/whoami-service" +``` + +```yaml tab="YAML" +# http routing section +http: + routers: + # Define a connection between requests and services + to-whoami: + rule: "Host(`domain`) && PathPrefix(`/whoami/`)" + # If the rule matches, applies the middleware + middlewares: + - test-user + # If the rule matches, forward to the whoami service (declared below) + service: whoami + middlewares: + # Define an authentication mechanism + test-user: + basicAuth: + users: + - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ + services: + # Define how to reach an existing service on our infrastructure + whoami: + loadbalancer: + servers: + - url: http://private/whoami-service ``` !!! note "The File Provider" @@ -61,27 +111,51 @@ In the process, Traefik will make sure that the user is authenticated (using the ??? example "Adding a TCP route for TLS requests on whoami.traefik.io" - ```toml + Static configuration: + + ```toml tab="TOML" [entryPoints] [entryPoints.web] - address = ":8081" # Listen on port 8081 for incoming requests + # Listen on port 8081 for incoming requests + address = ":8081" [providers] - [providers.file] # Enable the file provider to define routers / middlewares / services in a file + # Enable the file provider to define routers / middlewares / services in a file + [providers.file] + ``` + + ```yaml tab="YAML" + entrypoints: + web: + # Listen on port 8081 for incoming requests + address: :8081 + providers: + # Enable the file provider to define routers / middlewares / services in a file + file: {} + ``` + + Dynamic configuration: - [http] # http routing section + ```toml tab="TOML" + # http routing section + [http] [http.routers] - [http.routers.to-whoami] # Define a connection between requests and services - rule = "Host(`domain`) && PathPrefix(/whoami/)" - middlewares = ["test-user"] # If the rule matches, applies the middleware - service = "whoami" # If the rule matches, forward to the whoami service (declared below) + # Define a connection between requests and services + [http.routers.to-whoami] + rule = "Host(`domain`) && PathPrefix(`/whoami/`)" + # If the rule matches, applies the middleware + middlewares = ["test-user"] + # If the rule matches, forward to the whoami service (declared below) + service = "whoami" [http.middlewares] - [http.middlewares.test-user.basicauth] # Define an authentication mechanism + # Define an authentication mechanism + [http.middlewares.test-user.basicauth] users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] [http.services] - [http.services.whoami.loadbalancer] # Define how to reach an existing service on our infrastructure + # Define how to reach an existing service on our infrastructure + [http.services.whoami.loadbalancer] [[http.services.whoami.loadbalancer.servers]] url = "http://private/whoami-service" @@ -97,3 +171,39 @@ In the process, Traefik will make sure that the user is authenticated (using the [[tcp.services.whoami-tcp.loadbalancer.servers]] address = "xx.xx.xx.xx:xx" ``` + + ```yaml tab="YAML" + # http routing section + http: + routers: + # Define a connection between requests and services + to-whoami: + rule: Host(`domain`) && PathPrefix(`/whoami/`) + # If the rule matches, applies the middleware + middlewares: + - test-user + # If the rule matches, forward to the whoami service (declared below) + service: whoami + middlewares: + # Define an authentication mechanism + test-user: + basicAuth: + users: + - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ + services: + # Define how to reach an existing service on our infrastructure + whoami: + loadbalancer: + servers: + - url: http://private/whoami-service + tcp: + routers: + to-whoami-tcp: + service: whoami-tcp + rule: HostSNI(`whoami-tcp.traefik.io`) + services: + whoami-tcp: + loadbalancer: + servers: + - address: xx.xx.xx.xx:xx + ``` diff --git a/pkg/config/dyn_config.go b/pkg/config/dyn_config.go index b08ebd227..6b7577945 100644 --- a/pkg/config/dyn_config.go +++ b/pkg/config/dyn_config.go @@ -215,7 +215,7 @@ type Message struct { type Configuration struct { HTTP *HTTPConfiguration TCP *TCPConfiguration - TLS []*traefiktls.Configuration `json:"-" label:"-"` + TLS []*traefiktls.Configuration `json:"-" label:"-" yaml:"tls"` TLSOptions map[string]traefiktls.TLS TLSStores map[string]traefiktls.Store } diff --git a/pkg/config/file/file_node.go b/pkg/config/file/file_node.go index 33534d922..0c64f6e35 100644 --- a/pkg/config/file/file_node.go +++ b/pkg/config/file/file_node.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "path/filepath" "reflect" + "strings" "github.com/BurntSushi/toml" "github.com/containous/traefik/pkg/config/parser" @@ -22,7 +23,7 @@ func decodeFileToNode(filePath string, filters ...string) (*parser.Node, error) data := make(map[string]interface{}) - switch filepath.Ext(filePath) { + switch strings.ToLower(filepath.Ext(filePath)) { case ".toml": err = toml.Unmarshal(content, &data) if err != nil { @@ -30,14 +31,11 @@ func decodeFileToNode(filePath string, filters ...string) (*parser.Node, error) } case ".yml", ".yaml": - var err error err = yaml.Unmarshal(content, data) if err != nil { return nil, err } - return decodeRawToNode(data, parser.DefaultRootName, filters...) - default: return nil, fmt.Errorf("unsupported file extension: %s", filePath) } diff --git a/pkg/config/middlewares.go b/pkg/config/middlewares.go index 2caa868bb..05c36513a 100644 --- a/pkg/config/middlewares.go +++ b/pkg/config/middlewares.go @@ -9,27 +9,27 @@ import ( // Middleware holds the Middleware configuration. type Middleware struct { - AddPrefix *AddPrefix `json:"addPrefix,omitempty"` - StripPrefix *StripPrefix `json:"stripPrefix,omitempty"` - StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty"` - ReplacePath *ReplacePath `json:"replacePath,omitempty"` - ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty"` - Chain *Chain `json:"chain,omitempty"` - IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty"` - Headers *Headers `json:"headers,omitempty"` - Errors *ErrorPage `json:"errors,omitempty"` - RateLimit *RateLimit `json:"rateLimit,omitempty"` - RedirectRegex *RedirectRegex `json:"redirectRegex,omitempty"` - RedirectScheme *RedirectScheme `json:"redirectScheme,omitempty"` - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - DigestAuth *DigestAuth `json:"digestAuth,omitempty"` - ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty"` - MaxConn *MaxConn `json:"maxConn,omitempty"` - Buffering *Buffering `json:"buffering,omitempty"` - CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty"` - Compress *Compress `json:"compress,omitempty" label:"allowEmpty"` - PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty"` - Retry *Retry `json:"retry,omitempty"` + AddPrefix *AddPrefix `json:"addPrefix,omitempty" yaml:"addPrefix,omitempty"` + StripPrefix *StripPrefix `json:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty"` + StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty"` + ReplacePath *ReplacePath `json:"replacePath,omitempty" yaml:"replacePath,omitempty"` + ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty"` + Chain *Chain `json:"chain,omitempty" yaml:"chain,omitempty"` + IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty"` + Headers *Headers `json:"headers,omitempty" yaml:"headers,omitempty"` + Errors *ErrorPage `json:"errors,omitempty" yaml:"errors,omitempty"` + RateLimit *RateLimit `json:"rateLimit,omitempty" yaml:"rateLimit,omitempty"` + RedirectRegex *RedirectRegex `json:"redirectRegex,omitempty" yaml:"redirectRegex,omitempty"` + RedirectScheme *RedirectScheme `json:"redirectScheme,omitempty" yaml:"redirectScheme,omitempty"` + BasicAuth *BasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth,omitempty"` + DigestAuth *DigestAuth `json:"digestAuth,omitempty" yaml:"digestAuth,omitempty"` + ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty" yaml:"forwardAuth,omitempty"` + MaxConn *MaxConn `json:"maxConn,omitempty" yaml:"maxConn,omitempty"` + Buffering *Buffering `json:"buffering,omitempty" yaml:"buffering,omitempty"` + CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty" yaml:"circuitBreaker,omitempty"` + Compress *Compress `json:"compress,omitempty" label:"allowEmpty" yaml:"compress,omitempty" label:"allowEmpty"` + PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty"` + Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/file/file.go b/pkg/provider/file/file.go index 48c525032..57903ec3d 100644 --- a/pkg/provider/file/file.go +++ b/pkg/provider/file/file.go @@ -7,7 +7,6 @@ import ( "fmt" "io/ioutil" "os" - "path" "path/filepath" "strings" "text/template" @@ -20,6 +19,7 @@ import ( "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/tls" "gopkg.in/fsnotify.v1" + "gopkg.in/yaml.v2" ) const providerName = "file" @@ -170,28 +170,13 @@ func sendConfigToChannel(configurationChan chan<- config.Message, configuration } } -func readFile(filename string) (string, error) { - if len(filename) > 0 { - buf, err := ioutil.ReadFile(filename) - if err != nil { - return "", err - } - return string(buf), nil - } - return "", fmt.Errorf("invalid filename: %s", filename) -} - func (p *Provider) loadFileConfig(filename string, parseTemplate bool) (*config.Configuration, error) { - fileContent, err := readFile(filename) - if err != nil { - return nil, fmt.Errorf("error reading configuration file: %s - %s", filename, err) - } - + var err error var configuration *config.Configuration if parseTemplate { - configuration, err = p.CreateConfiguration(fileContent, template.FuncMap{}, false) + configuration, err = p.CreateConfiguration(filename, template.FuncMap{}, false) } else { - configuration, err = p.DecodeConfiguration(fileContent) + configuration, err = p.DecodeConfiguration(filename) } if err != nil { return nil, err @@ -223,7 +208,6 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st logger := log.FromContext(ctx) fileList, err := ioutil.ReadDir(directory) - if err != nil { return configuration, fmt.Errorf("unable to read directory %s: %v", directory, err) } @@ -243,6 +227,7 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st } configTLSMaps := make(map[*tls.Configuration]struct{}) + for _, item := range fileList { if item.IsDir() { @@ -251,13 +236,17 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st return configuration, fmt.Errorf("unable to load content configuration from subdirectory %s: %v", item, err) } continue - } else if !strings.HasSuffix(item.Name(), ".toml") && !strings.HasSuffix(item.Name(), ".tmpl") { + } + + switch strings.ToLower(filepath.Ext(item.Name())) { + case ".toml", ".yaml", ".yml": + // noop + default: continue } var c *config.Configuration - c, err = p.loadFileConfig(path.Join(directory, item.Name()), true) - + c, err = p.loadFileConfig(filepath.Join(directory, item.Name()), true) if err != nil { return configuration, err } @@ -318,7 +307,12 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st } // CreateConfiguration creates a provider configuration from content using templating. -func (p *Provider) CreateConfiguration(tmplContent string, funcMap template.FuncMap, templateObjects interface{}) (*config.Configuration, error) { +func (p *Provider) CreateConfiguration(filename string, funcMap template.FuncMap, templateObjects interface{}) (*config.Configuration, error) { + tmplContent, err := readFile(filename) + if err != nil { + return nil, fmt.Errorf("error reading configuration file: %s - %s", filename, err) + } + var defaultFuncMap = sprig.TxtFuncMap() defaultFuncMap["normalize"] = provider.Normalize defaultFuncMap["split"] = strings.Split @@ -328,7 +322,7 @@ func (p *Provider) CreateConfiguration(tmplContent string, funcMap template.Func tmpl := template.New(p.Filename).Funcs(defaultFuncMap) - _, err := tmpl.Parse(tmplContent) + _, err = tmpl.Parse(tmplContent) if err != nil { return nil, err } @@ -341,14 +335,25 @@ func (p *Provider) CreateConfiguration(tmplContent string, funcMap template.Func var renderedTemplate = buffer.String() if p.DebugLogGeneratedTemplate { - log.Debugf("Template content: %s", tmplContent) - log.Debugf("Rendering results: %s", renderedTemplate) + logger := log.WithoutContext().WithField(log.ProviderName, providerName) + logger.Debugf("Template content: %s", tmplContent) + logger.Debugf("Rendering results: %s", renderedTemplate) } - return p.DecodeConfiguration(renderedTemplate) + + return p.decodeConfiguration(filename, renderedTemplate) } // DecodeConfiguration Decodes a *types.Configuration from a content. -func (p *Provider) DecodeConfiguration(content string) (*config.Configuration, error) { +func (p *Provider) DecodeConfiguration(filename string) (*config.Configuration, error) { + content, err := readFile(filename) + if err != nil { + return nil, fmt.Errorf("error reading configuration file: %s - %s", filename, err) + } + + return p.decodeConfiguration(filename, content) +} + +func (p *Provider) decodeConfiguration(filePath string, content string) (*config.Configuration, error) { configuration := &config.Configuration{ HTTP: &config.HTTPConfiguration{ Routers: make(map[string]*config.Router), @@ -363,8 +368,35 @@ func (p *Provider) DecodeConfiguration(content string) (*config.Configuration, e TLSStores: make(map[string]tls.Store), TLSOptions: make(map[string]tls.TLS), } - if _, err := toml.Decode(content, configuration); err != nil { - return nil, err + + switch strings.ToLower(filepath.Ext(filePath)) { + case ".toml": + _, err := toml.Decode(content, configuration) + if err != nil { + return nil, err + } + + case ".yml", ".yaml": + var err error + err = yaml.Unmarshal([]byte(content), configuration) + if err != nil { + return nil, err + } + + default: + return nil, fmt.Errorf("unsupported file extension: %s", filePath) } + return configuration, nil } + +func readFile(filename string) (string, error) { + if len(filename) > 0 { + buf, err := ioutil.ReadFile(filename) + if err != nil { + return "", err + } + return string(buf), nil + } + return "", fmt.Errorf("invalid filename: %s", filename) +} diff --git a/pkg/provider/file/file_test.go b/pkg/provider/file/file_test.go index 95bbb26eb..46f28354b 100644 --- a/pkg/provider/file/file_test.go +++ b/pkg/provider/file/file_test.go @@ -2,10 +2,11 @@ package file import ( "context" - "fmt" + "io" "io/ioutil" "os" - "path" + "path/filepath" + "strconv" "testing" "time" @@ -17,14 +18,62 @@ import ( type ProvideTestCase struct { desc string - directoryContent []string - fileContent string - traefikFileContent string + directoryPaths []string + filePath string + traefikFilePath string expectedNumRouter int expectedNumService int expectedNumTLSConf int } +func TestTLSContent(t *testing.T) { + tempDir := createTempDir(t, "testdir") + defer os.RemoveAll(tempDir) + + fileTLS, err := createTempFile("./fixtures/toml/tls_file.cert", tempDir) + require.NoError(t, err) + + fileConfig, err := ioutil.TempFile(tempDir, "temp*.toml") + require.NoError(t, err) + + content := ` +[[tls]] + [tls.certificate] + certFile = "` + fileTLS.Name() + `" + keyFile = "` + fileTLS.Name() + `" +` + + _, err = fileConfig.Write([]byte(content)) + require.NoError(t, err) + + provider := &Provider{} + configuration, err := provider.loadFileConfig(fileConfig.Name(), true) + require.NoError(t, err) + + require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.CertFile.String()) + require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.KeyFile.String()) +} + +func TestErrorWhenEmptyConfig(t *testing.T) { + provider := &Provider{} + configChan := make(chan config.Message) + errorChan := make(chan struct{}) + go func() { + err := provider.Provide(configChan, safe.NewPool(context.Background())) + assert.Error(t, err) + close(errorChan) + }() + + timeout := time.After(time.Second) + select { + case <-configChan: + t.Fatal("We should not receive config message") + case <-timeout: + t.Fatal("timeout while waiting for config") + case <-errorChan: + } +} + func TestProvideWithoutWatch(t *testing.T) { for _, test := range getTestCases() { t.Run(test.desc+" without watch", func(t *testing.T) { @@ -74,21 +123,20 @@ func TestProvideWithWatch(t *testing.T) { t.Errorf("timeout while waiting for config") } - if len(test.fileContent) > 0 { - if err := ioutil.WriteFile(provider.Filename, []byte(test.fileContent), 0755); err != nil { - t.Error(err) - } + if len(test.filePath) > 0 { + err := copyFile(test.filePath, provider.Filename) + require.NoError(t, err) } - if len(test.traefikFileContent) > 0 { - if err := ioutil.WriteFile(provider.TraefikFile, []byte(test.traefikFileContent), 0755); err != nil { - t.Error(err) - } + if len(test.traefikFilePath) > 0 { + err := copyFile(test.traefikFilePath, provider.TraefikFile) + require.NoError(t, err) } - if len(test.directoryContent) > 0 { - for _, fileContent := range test.directoryContent { - createRandomFile(t, provider.Directory, fileContent) + if len(test.directoryPaths) > 0 { + for i, filePath := range test.directoryPaths { + err := copyFile(filePath, filepath.Join(provider.Directory, strconv.Itoa(i)+filepath.Ext(filePath))) + require.NoError(t, err) } } @@ -114,62 +162,86 @@ func TestProvideWithWatch(t *testing.T) { } } -func TestErrorWhenEmptyConfig(t *testing.T) { - provider := &Provider{} - configChan := make(chan config.Message) - errorChan := make(chan struct{}) - go func() { - err := provider.Provide(configChan, safe.NewPool(context.Background())) - assert.Error(t, err) - close(errorChan) - }() - - timeout := time.After(time.Second) - select { - case <-configChan: - t.Fatal("We should not receive config message") - case <-timeout: - t.Fatal("timeout while waiting for config") - case <-errorChan: - } -} - func getTestCases() []ProvideTestCase { return []ProvideTestCase{ { desc: "simple file", - fileContent: createRoutersConfiguration(3) + createServicesConfiguration(6) + createTLS(5), + filePath: "./fixtures/toml/simple_file_01.toml", expectedNumRouter: 3, expectedNumService: 6, expectedNumTLSConf: 5, }, { - desc: "simple file and a traefik file", - fileContent: createRoutersConfiguration(4) + createServicesConfiguration(8) + createTLS(4), - traefikFileContent: ` - debug=true -`, + desc: "simple file yaml", + filePath: "./fixtures/yaml/simple_file_01.yml", + expectedNumRouter: 3, + expectedNumService: 6, + expectedNumTLSConf: 5, + }, + { + desc: "simple file and a traefik file", + filePath: "./fixtures/toml/simple_file_02.toml", + traefikFilePath: "./fixtures/toml/simple_traefik_file_01.toml", expectedNumRouter: 4, expectedNumService: 8, expectedNumTLSConf: 4, }, { - desc: "template file", - fileContent: ` -[http.routers] -{{ range $i, $e := until 20 }} - [http.routers.router{{ $e }}] - service = "application" -{{ end }} -`, + desc: "simple file and a traefik file yaml", + filePath: "./fixtures/yaml/simple_file_02.yml", + traefikFilePath: "./fixtures/yaml/simple_traefik_file_01.yml", + expectedNumRouter: 4, + expectedNumService: 8, + expectedNumTLSConf: 4, + }, + { + desc: "simple traefik file", + traefikFilePath: "./fixtures/toml/simple_traefik_file_02.toml", + expectedNumRouter: 2, + expectedNumService: 3, + expectedNumTLSConf: 4, + }, + { + desc: "simple traefik file yaml", + traefikFilePath: "./fixtures/yaml/simple_traefik_file_02.yml", + expectedNumRouter: 2, + expectedNumService: 3, + expectedNumTLSConf: 4, + }, + { + desc: "template file", + filePath: "./fixtures/toml/template_file.toml", expectedNumRouter: 20, }, + { + desc: "template file yaml", + filePath: "./fixtures/yaml/template_file.yml", + expectedNumRouter: 20, + }, + { + desc: "simple traefik file with templating", + traefikFilePath: "./fixtures/toml/simple_traefik_file_with_templating.toml", + expectedNumRouter: 2, + expectedNumService: 3, + expectedNumTLSConf: 4, + }, { desc: "simple directory", - directoryContent: []string{ - createRoutersConfiguration(2), - createServicesConfiguration(3), - createTLS(4), + directoryPaths: []string{ + "./fixtures/toml/dir01_file01.toml", + "./fixtures/toml/dir01_file02.toml", + "./fixtures/toml/dir01_file03.toml", + }, + expectedNumRouter: 2, + expectedNumService: 3, + expectedNumTLSConf: 4, + }, + { + desc: "simple directory yaml", + directoryPaths: []string{ + "./fixtures/yaml/dir01_file01.yml", + "./fixtures/yaml/dir01_file02.yml", + "./fixtures/yaml/dir01_file03.yml", }, expectedNumRouter: 2, expectedNumService: 3, @@ -177,45 +249,21 @@ func getTestCases() []ProvideTestCase { }, { desc: "template in directory", - directoryContent: []string{ - ` -[http.routers] -{{ range $i, $e := until 20 }} - [http.routers.router{{ $e }}] - service = "application" -{{ end }} -`, - ` -[http.services] -{{ range $i, $e := until 20 }} - [http.services.application-{{ $e }}] - [[http.services.application-{{ $e }}.servers]] - url="http://127.0.0.1" -{{ end }} -`, + directoryPaths: []string{ + "./fixtures/toml/template_in_directory_file01.toml", + "./fixtures/toml/template_in_directory_file02.toml", }, expectedNumRouter: 20, expectedNumService: 20, }, { - desc: "simple traefik file", - traefikFileContent: ` - debug=true - [providers.file] - ` + createRoutersConfiguration(2) + createServicesConfiguration(3) + createTLS(4), - expectedNumRouter: 2, - expectedNumService: 3, - expectedNumTLSConf: 4, - }, - { - desc: "simple traefik file with templating", - traefikFileContent: ` - temp="{{ getTag \"test\" }}" - [providers.file] - ` + createRoutersConfiguration(2) + createServicesConfiguration(3) + createTLS(4), - expectedNumRouter: 2, - expectedNumService: 3, - expectedNumTLSConf: 4, + desc: "template in directory yaml", + directoryPaths: []string{ + "./fixtures/yaml/template_in_directory_file01.yml", + "./fixtures/yaml/template_in_directory_file02.yml", + }, + expectedNumRouter: 20, + expectedNumService: 20, }, } } @@ -226,30 +274,46 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) (*Provider, provider := &Provider{} provider.Watch = true - if len(test.directoryContent) > 0 { + if len(test.directoryPaths) > 0 { if !watch { - for _, fileContent := range test.directoryContent { - createRandomFile(t, tempDir, fileContent) + for _, filePath := range test.directoryPaths { + var err error + _, err = createTempFile(filePath, tempDir) + require.NoError(t, err) } } provider.Directory = tempDir } - if len(test.fileContent) > 0 { - if watch { - test.fileContent = "" - } - filename := createRandomFile(t, tempDir, test.fileContent) - provider.Filename = filename.Name() + if len(test.filePath) > 0 { + var file *os.File + if watch { + var err error + file, err = ioutil.TempFile(tempDir, "temp*"+filepath.Ext(test.filePath)) + require.NoError(t, err) + } else { + var err error + file, err = createTempFile(test.filePath, tempDir) + require.NoError(t, err) + } + + provider.Filename = file.Name() } - if len(test.traefikFileContent) > 0 { + if len(test.traefikFilePath) > 0 { + var file *os.File if watch { - test.traefikFileContent = "" + var err error + file, err = ioutil.TempFile(tempDir, "temp*"+filepath.Ext(test.traefikFilePath)) + require.NoError(t, err) + } else { + var err error + file, err = createTempFile(test.traefikFilePath, tempDir) + require.NoError(t, err) } - filename := createRandomFile(t, tempDir, test.traefikFileContent) - provider.TraefikFile = filename.Name() + + provider.TraefikFile = file.Name() } return provider, func() { @@ -257,39 +321,10 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) (*Provider, } } -// createRandomFile Helper -func createRandomFile(t *testing.T, tempDir string, contents ...string) *os.File { - return createFile(t, tempDir, fmt.Sprintf("temp%d.toml", time.Now().UnixNano()), contents...) -} - -// createFile Helper -func createFile(t *testing.T, tempDir string, name string, contents ...string) *os.File { - t.Helper() - fileName := path.Join(tempDir, name) - - tempFile, err := os.Create(fileName) - if err != nil { - t.Fatal(err) - } - - for _, content := range contents { - _, err = tempFile.WriteString(content) - if err != nil { - t.Fatal(err) - } - } - - err = tempFile.Close() - if err != nil { - t.Fatal(err) - } - - return tempFile -} - // createTempDir Helper func createTempDir(t *testing.T, dir string) string { t.Helper() + d, err := ioutil.TempDir("", dir) if err != nil { t.Fatal(err) @@ -297,62 +332,36 @@ func createTempDir(t *testing.T, dir string) string { return d } -// createRoutersConfiguration Helper -func createRoutersConfiguration(n int) string { - conf := "[http.routers]\n" - for i := 1; i <= n; i++ { - conf += fmt.Sprintf(` -[http.routers."router%[1]d"] - service = "application-%[1]d" -`, i) +func copyFile(srcPath, dstPath string) error { + dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + return err } - return conf -} + defer dst.Close() -// createServicesConfiguration Helper -func createServicesConfiguration(n int) string { - conf := "[http.services]\n" - for i := 1; i <= n; i++ { - conf += fmt.Sprintf(` -[http.services.application-%[1]d.loadbalancer] - [[http.services.application-%[1]d.loadbalancer.servers]] - url = "http://172.17.0.%[1]d:80" -`, i) + src, err := os.Open(srcPath) + if err != nil { + return err } - return conf + defer src.Close() + + _, err = io.Copy(dst, src) + return err } -// createTLS Helper -func createTLS(n int) string { - var conf string - for i := 1; i <= n; i++ { - conf += fmt.Sprintf(`[[TLS]] - EntryPoints = ["https"] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest%[1]d.com.cert" - KeyFile = "integration/fixtures/https/snitest%[1]d.com.key" -`, i) +func createTempFile(srcPath, tempDir string) (*os.File, error) { + file, err := ioutil.TempFile(tempDir, "temp*"+filepath.Ext(srcPath)) + if err != nil { + return nil, err } - return conf -} - -func TestTLSContent(t *testing.T) { - tempDir := createTempDir(t, "testdir") - defer os.RemoveAll(tempDir) - - fileTLS := createRandomFile(t, tempDir, "CONTENT") - fileConfig := createRandomFile(t, tempDir, ` -[[tls]] -entryPoints = ["https"] - [tls.certificate] - certFile = "`+fileTLS.Name()+`" - keyFile = "`+fileTLS.Name()+`" -`) - - provider := &Provider{} - configuration, err := provider.loadFileConfig(fileConfig.Name(), true) - require.NoError(t, err) - - require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.CertFile.String()) - require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.KeyFile.String()) + defer file.Close() + + src, err := os.Open(srcPath) + if err != nil { + return nil, err + } + defer src.Close() + + _, err = io.Copy(file, src) + return file, err } diff --git a/pkg/provider/file/fixtures/toml/dir01_file01.toml b/pkg/provider/file/fixtures/toml/dir01_file01.toml new file mode 100644 index 000000000..64f84722a --- /dev/null +++ b/pkg/provider/file/fixtures/toml/dir01_file01.toml @@ -0,0 +1,7 @@ +[http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" diff --git a/pkg/provider/file/fixtures/toml/dir01_file02.toml b/pkg/provider/file/fixtures/toml/dir01_file02.toml new file mode 100644 index 000000000..6eb6d31d5 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/dir01_file02.toml @@ -0,0 +1,13 @@ +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" diff --git a/pkg/provider/file/fixtures/toml/dir01_file03.toml b/pkg/provider/file/fixtures/toml/dir01_file03.toml new file mode 100644 index 000000000..498a19b91 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/dir01_file03.toml @@ -0,0 +1,16 @@ +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_file_01.toml b/pkg/provider/file/fixtures/toml/simple_file_01.toml new file mode 100644 index 000000000..e3af6f686 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_file_01.toml @@ -0,0 +1,55 @@ +[http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" + +[http.routers."router3"] + service = "application-3" +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" + +[http.services.application-4.loadbalancer] + [[http.services.application-4.loadbalancer.servers]] + url = "http://172.17.0.4:80" + +[http.services.application-5.loadbalancer] + [[http.services.application-5.loadbalancer.servers]] + url = "http://172.17.0.5:80" + +[http.services.application-6.loadbalancer] + [[http.services.application-6.loadbalancer.servers]] + url = "http://172.17.0.6:80" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest5.com.cert" + KeyFile = "integration/fixtures/https/snitest5.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_file_02.toml b/pkg/provider/file/fixtures/toml/simple_file_02.toml new file mode 100644 index 000000000..e614160d3 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_file_02.toml @@ -0,0 +1,62 @@ +[http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" + +[http.routers."router3"] + service = "application-3" + +[http.routers."router4"] + service = "application-4" +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" + +[http.services.application-4.loadbalancer] + [[http.services.application-4.loadbalancer.servers]] + url = "http://172.17.0.4:80" + +[http.services.application-5.loadbalancer] + [[http.services.application-5.loadbalancer.servers]] + url = "http://172.17.0.5:80" + +[http.services.application-6.loadbalancer] + [[http.services.application-6.loadbalancer.servers]] + url = "http://172.17.0.6:80" + +[http.services.application-7.loadbalancer] + [[http.services.application-7.loadbalancer.servers]] + url = "http://172.17.0.7:80" + +[http.services.application-8.loadbalancer] + [[http.services.application-8.loadbalancer.servers]] + url = "http://172.17.0.8:80" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml new file mode 100644 index 000000000..2aa73ad54 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml @@ -0,0 +1,3 @@ + +[log] + level = "DEBUG" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml new file mode 100644 index 000000000..4d9e472f5 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml @@ -0,0 +1,38 @@ +[providers.file] + +[http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml new file mode 100644 index 000000000..99bb1bc14 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml @@ -0,0 +1,39 @@ + + temp="{{ getTag \"test\" }}" + [providers.file] + [http.routers] + +[http.routers."router1"] + service = "application-1" + +[http.routers."router2"] + service = "application-2" +[http.services] + +[http.services.application-1.loadbalancer] + [[http.services.application-1.loadbalancer.servers]] + url = "http://172.17.0.1:80" + +[http.services.application-2.loadbalancer] + [[http.services.application-2.loadbalancer.servers]] + url = "http://172.17.0.2:80" + +[http.services.application-3.loadbalancer] + [[http.services.application-3.loadbalancer.servers]] + url = "http://172.17.0.3:80" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" +[[TLS]] + [TLS.Certificate] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/template_file.toml b/pkg/provider/file/fixtures/toml/template_file.toml new file mode 100644 index 000000000..1958d6387 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/template_file.toml @@ -0,0 +1,6 @@ + +[http.routers] +{{ range $i, $e := until 20 }} + [http.routers.router{{ $e }}] + service = "application" +{{ end }} diff --git a/pkg/provider/file/fixtures/toml/template_in_directory_file01.toml b/pkg/provider/file/fixtures/toml/template_in_directory_file01.toml new file mode 100644 index 000000000..3eccb8862 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/template_in_directory_file01.toml @@ -0,0 +1,5 @@ +[http.routers] +{{ range $i, $e := until 20 }} + [http.routers.router{{ $e }}] + service = "application" +{{ end }} \ No newline at end of file diff --git a/pkg/provider/file/fixtures/toml/template_in_directory_file02.toml b/pkg/provider/file/fixtures/toml/template_in_directory_file02.toml new file mode 100644 index 000000000..35c2d25f3 --- /dev/null +++ b/pkg/provider/file/fixtures/toml/template_in_directory_file02.toml @@ -0,0 +1,6 @@ +[http.services] +{{ range $i, $e := until 20 }} + [http.services.application-{{ $e }}] + [[http.services.application-{{ $e }}.servers]] + url="http://127.0.0.1" +{{ end }} \ No newline at end of file diff --git a/pkg/provider/file/fixtures/toml/tls_file.cert b/pkg/provider/file/fixtures/toml/tls_file.cert new file mode 100644 index 000000000..33840068c --- /dev/null +++ b/pkg/provider/file/fixtures/toml/tls_file.cert @@ -0,0 +1 @@ +CONTENT \ No newline at end of file diff --git a/pkg/provider/file/fixtures/yaml/dir01_file01.yml b/pkg/provider/file/fixtures/yaml/dir01_file01.yml new file mode 100644 index 000000000..621580524 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/dir01_file01.yml @@ -0,0 +1,6 @@ +http: + routers: + router1: + service: application-1 + router2: + service: application-2 diff --git a/pkg/provider/file/fixtures/yaml/dir01_file02.yml b/pkg/provider/file/fixtures/yaml/dir01_file02.yml new file mode 100644 index 000000000..65f706ff0 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/dir01_file02.yml @@ -0,0 +1,14 @@ +http: + services: + application-1: + loadbalancer: + servers: + - url: 'http://172.17.0.1:80' + application-2: + loadbalancer: + servers: + - url: 'http://172.17.0.2:80' + application-3: + loadbalancer: + servers: + - url: 'http://172.17.0.3:80' diff --git a/pkg/provider/file/fixtures/yaml/dir01_file03.yml b/pkg/provider/file/fixtures/yaml/dir01_file03.yml new file mode 100644 index 000000000..e243d4fa8 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/dir01_file03.yml @@ -0,0 +1,13 @@ +tls: + - certificate: + certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certificate: + certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certificate: + certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certificate: + certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_file_01.yml b/pkg/provider/file/fixtures/yaml/simple_file_01.yml new file mode 100644 index 000000000..b2fc6e191 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/simple_file_01.yml @@ -0,0 +1,50 @@ +http: + routers: + router1: + service: application-1 + router2: + service: application-2 + router3: + service: application-3 + services: + application-1: + loadbalancer: + servers: + - url: 'http://172.17.0.1:80' + application-2: + loadbalancer: + servers: + - url: 'http://172.17.0.2:80' + application-3: + loadbalancer: + servers: + - url: 'http://172.17.0.3:80' + application-4: + loadbalancer: + servers: + - url: 'http://172.17.0.4:80' + application-5: + loadbalancer: + servers: + - url: 'http://172.17.0.5:80' + application-6: + loadbalancer: + servers: + - url: 'http://172.17.0.6:80' + +tls: + - certificate: + certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certificate: + certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certificate: + certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certificate: + certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key + - certificate: + certfile: integration/fixtures/https/snitest5.com.cert + keyfile: integration/fixtures/https/snitest5.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_file_02.yml b/pkg/provider/file/fixtures/yaml/simple_file_02.yml new file mode 100644 index 000000000..ae40b8789 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/simple_file_02.yml @@ -0,0 +1,58 @@ +http: + routers: + router1: + service: application-1 + router2: + service: application-2 + router3: + service: application-3 + router4: + service: application-4 + services: + application-1: + loadbalancer: + servers: + - url: 'http://172.17.0.1:80' + application-2: + loadbalancer: + servers: + - url: 'http://172.17.0.2:80' + application-3: + loadbalancer: + servers: + - url: 'http://172.17.0.3:80' + application-4: + loadbalancer: + servers: + - url: 'http://172.17.0.4:80' + application-5: + loadbalancer: + servers: + - url: 'http://172.17.0.5:80' + application-6: + loadbalancer: + servers: + - url: 'http://172.17.0.6:80' + application-7: + loadbalancer: + servers: + - url: 'http://172.17.0.7:80' + application-8: + loadbalancer: + servers: + - url: 'http://172.17.0.8:80' + +tls: + - certificate: + certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certificate: + certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certificate: + certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certificate: + certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key + diff --git a/pkg/provider/file/fixtures/yaml/simple_traefik_file_01.yml b/pkg/provider/file/fixtures/yaml/simple_traefik_file_01.yml new file mode 100644 index 000000000..b0e9cab54 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/simple_traefik_file_01.yml @@ -0,0 +1,2 @@ +log: + level: DEBUG diff --git a/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml b/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml new file mode 100644 index 000000000..f8733b514 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml @@ -0,0 +1,35 @@ +providers: + file: {} +http: + routers: + router1: + service: application-1 + router2: + service: application-2 + services: + application-1: + loadbalancer: + servers: + - url: 'http://172.17.0.1:80' + application-2: + loadbalancer: + servers: + - url: 'http://172.17.0.2:80' + application-3: + loadbalancer: + servers: + - url: 'http://172.17.0.3:80' + +tls: + - certificate: + certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certificate: + certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certificate: + certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certificate: + certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key diff --git a/pkg/provider/file/fixtures/yaml/template_file.yml b/pkg/provider/file/fixtures/yaml/template_file.yml new file mode 100644 index 000000000..66903fbc8 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/template_file.yml @@ -0,0 +1,6 @@ +http: +{{ range $i, $e := until 20 }} + routers: + router{{ $e }}: + service: application-1 +{{ end }} \ No newline at end of file diff --git a/pkg/provider/file/fixtures/yaml/template_in_directory_file01.yml b/pkg/provider/file/fixtures/yaml/template_in_directory_file01.yml new file mode 100644 index 000000000..908eed00c --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/template_in_directory_file01.yml @@ -0,0 +1,6 @@ +http: +{{ range $i, $e := until 20 }} + routers: + router{{ $e }}: + service: application-1 +{{ end }} diff --git a/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml b/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml new file mode 100644 index 000000000..8c2d94c03 --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml @@ -0,0 +1,8 @@ +http: + services: +{{ range $i, $e := until 20 }} + application-{{ $e }}: + loadbalancer: + servers: + - url: 'http://127.0.0.1' +{{ end }} diff --git a/pkg/provider/file/fixtures/yaml/tls_file.cert b/pkg/provider/file/fixtures/yaml/tls_file.cert new file mode 100644 index 000000000..33840068c --- /dev/null +++ b/pkg/provider/file/fixtures/yaml/tls_file.cert @@ -0,0 +1 @@ +CONTENT \ No newline at end of file From c9b2a07bc73c9adb4f9fe20d1d4728d247779c9c Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Thu, 27 Jun 2019 16:04:03 +0200 Subject: [PATCH 04/11] Drop headers by default in access logs. --- docs/content/observability/access-logs.md | 134 +++++++++++++--------- pkg/types/logs.go | 2 +- 2 files changed, 81 insertions(+), 55 deletions(-) diff --git a/docs/content/observability/access-logs.md b/docs/content/observability/access-logs.md index bb174567e..d3e8dfe4a 100644 --- a/docs/content/observability/access-logs.md +++ b/docs/content/observability/access-logs.md @@ -5,51 +5,57 @@ Who Calls Whom? By default, logs are written to stdout, in text format. -## Configuration Examples +## Configuration -??? example "Enabling Access Logs" +To enable the access logs: - ```toml - [accessLog] - ``` +```toml tab="File" +[accessLog] +``` -## Configuration Options +```bash tab="CLI" +--accesslog +``` -### filePath +### `filePath` By default access logs are written to the standard output. To write the logs into a log file, use the `filePath` option. in the Common Log Format (CLF), extended with additional fields. -### format +### `format` By default, logs are written using the Common Log Format (CLF). To write logs in JSON, use `json` in the `format` option. !!! note "Common Log Format" - -#### CLF - Common Log Format - + ```html - [] " " "" "" "" "" ms ``` -#### bufferingSize +### `bufferingSize` To write the logs in an asynchronous fashion, specify a `bufferingSize` option. This option represents the number of log lines Traefik will keep in memory before writing them to the selected output. In some cases, this option can greatly help performances. -??? example "Configuring a buffer of 100 lines" +```toml tab="File" +# Configuring a buffer of 100 lines +[accessLog] + filePath = "/path/to/access.log" + bufferingSize = 100 +``` - ```toml - [accessLog] - filePath = "/path/to/access.log" - bufferingSize = 100 - ``` +```bash tab="CLI" +# Configuring a buffer of 100 lines +--accesslog +--accesslog.filepath="/path/to/access.log" +--accesslog.bufferingsize=100 +``` -#### Filtering +### Filtering To filter logs, you can specify a set of filters which are logically "OR-connected". Thus, specifying multiple filters will keep more access logs than specifying only one. @@ -60,20 +66,29 @@ The available filters are: - `retryAttempts`, to keep the access logs when at least one retry has happened - `minDuration`, to keep access logs when requests take longer than the specified duration -??? example "Configuring Multiple Filters" +```toml tab="File" +# Configuring Multiple Filters +[accessLog] +filePath = "/path/to/access.log" +format = "json" - ```toml - [accessLog] - filePath = "/path/to/access.log" - format = "json" - - [accessLog.filters] - statusCodes = ["200", "300-302"] - retryAttempts = true - minDuration = "10ms" - ``` + [accessLog.filters] + statusCodes = ["200", "300-302"] + retryAttempts = true + minDuration = "10ms" +``` -#### Limiting the Fields +```bash tab="CLI" +# Configuring Multiple Filters +--accesslog +--accesslog.filepath="/path/to/access.log" +--accesslog.format="json" +--accesslog.filters.statuscodes="200, 300-302" +--accesslog.filters.retryattempts +--accesslog.filters.minduration="10ms" +``` + +### Limiting the Fields You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.header` options @@ -83,31 +98,42 @@ Each field can be set to: - `drop` to drop the value - `redact` to replace the value with "redacted" -??? example "Limiting the Logs to Specific Fields" +The `defaultMode` for `fields.header` is `drop`. - ```toml - [accessLog] - filePath = "/path/to/access.log" - format = "json" - - [accessLog.filters] - statusCodes = ["200", "300-302"] - - [accessLog.fields] - defaultMode = "keep" - - [accessLog.fields.names] - "ClientUsername" = "drop" +```toml tab="File" +# Limiting the Logs to Specific Fields +[accessLog] + filePath = "/path/to/access.log" + format = "json" + + [accessLog.fields] + defaultMode = "keep" + + [accessLog.fields.names] + "ClientUsername" = "drop" + + [accessLog.fields.headers] + defaultMode = "keep" + + [accessLog.fields.headers.names] + "User-Agent" = "redact" + "Authorization" = "drop" + "Content-Type" = "keep" +``` + +```bash tab="CLI" +# Limiting the Logs to Specific Fields +--accesslog +--accesslog.filepath="/path/to/access.log" +--accesslog.format="json" +--accesslog.fields.defaultmode="keep" +--accesslog.fields.names.ClientUsername="drop" +--accesslog.fields.headers.defaultmode="keep" +--accesslog.fields.headers.names.User-Agent="redact" +--accesslog.fields.headers.names.Authorization="drop" +--accesslog.fields.headers.names.Content-Type="keep" +``` - [accessLog.fields.headers] - defaultMode = "keep" - - [accessLog.fields.headers.names] - "User-Agent" = "redact" - "Authorization" = "drop" - "Content-Type" = "keep" - ``` - ??? list "Available Fields" | Field | Description | diff --git a/pkg/types/logs.go b/pkg/types/logs.go index fd1526e3c..716decf01 100644 --- a/pkg/types/logs.go +++ b/pkg/types/logs.go @@ -72,7 +72,7 @@ type AccessLogFields struct { func (f *AccessLogFields) SetDefaults() { f.DefaultMode = AccessLogKeep f.Headers = &FieldHeaders{ - DefaultMode: AccessLogKeep, + DefaultMode: AccessLogDrop, } } From 4245096be498000046f2167f3fa3d4071349eb8c Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Thu, 27 Jun 2019 23:58:03 +0200 Subject: [PATCH 05/11] Define a TLS section to group TLS, TLSOptions, and TLSStores. Co-authored-by: Jean-Baptiste Doumenjou --- docs/content/https/tls.md | 62 +++-- docs/content/providers/file.md | 21 +- .../reference/dynamic-configuration/file.toml | 62 +++-- docs/content/routing/routers/index.md | 12 +- integration/fixtures/acme/acme_tls.toml | 7 +- integration/fixtures/acme/certificates.toml | 15 +- integration/fixtures/grpc/config.toml | 3 +- .../fixtures/grpc/config_h2c_termination.toml | 3 +- .../fixtures/grpc/config_insecure.toml | 3 +- integration/fixtures/grpc/config_retry.toml | 3 +- .../https/clientca/https_1ca1config.toml | 17 +- .../https/clientca/https_2ca1config.toml | 18 +- .../https/clientca/https_2ca2config.toml | 17 +- integration/fixtures/https/dynamic_https.toml | 8 +- .../https/dynamic_https_sni_default_cert.toml | 13 +- integration/fixtures/https/https_sni.toml | 14 +- .../https_sni_case_insensitive_dynamic.toml | 10 +- .../https/https_sni_default_cert.toml | 17 +- .../fixtures/https/https_sni_strict.toml | 18 +- .../fixtures/https/https_tls_options.toml | 20 +- integration/fixtures/tcp/mixed.toml | 3 +- .../fixtures/tcp/multi-tls-options.toml | 6 +- .../fixtures/tlsclientheaders/simple.toml | 22 +- .../fixtures/websocket/config_https.toml | 3 +- integration/https_test.go | 12 +- pkg/config/dyn_config.go | 19 +- pkg/config/file/fixtures/sample.toml | 34 ++- pkg/provider/acme/provider.go | 12 +- pkg/provider/file/file.go | 67 +++-- pkg/provider/file/file_test.go | 21 +- .../file/fixtures/toml/dir01_file03.toml | 33 +-- .../file/fixtures/toml/simple_file_01.toml | 42 +-- .../file/fixtures/toml/simple_file_02.toml | 34 +-- .../fixtures/toml/simple_traefik_file_01.toml | 3 +- .../fixtures/toml/simple_traefik_file_02.toml | 34 +-- .../simple_traefik_file_with_templating.toml | 41 +-- .../file/fixtures/toml/template_file.toml | 1 - .../file/fixtures/yaml/dir01_file03.yml | 21 +- .../file/fixtures/yaml/simple_file_01.yml | 26 +- .../file/fixtures/yaml/simple_file_02.yml | 16 +- .../fixtures/yaml/simple_traefik_file_02.yml | 15 +- pkg/provider/kubernetes/crd/kubernetes.go | 38 +-- .../kubernetes/crd/kubernetes_test.go | 241 +++++++++++------- pkg/provider/kubernetes/ingress/kubernetes.go | 20 +- .../kubernetes/ingress/kubernetes_test.go | 24 +- pkg/server/aggregator.go | 33 ++- pkg/server/aggregator_test.go | 106 ++++---- pkg/server/router/tcp/router_test.go | 4 +- pkg/server/server_configuration.go | 4 +- pkg/tls/tls.go | 10 +- pkg/tls/tlsmanager.go | 8 +- pkg/tls/tlsmanager_test.go | 49 ++-- 52 files changed, 717 insertions(+), 628 deletions(-) diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index c67da5d95..541495ce2 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -11,18 +11,16 @@ See the [Let's Encrypt](./acme.md) page. ### User defined -To add / remove TLS certificates, even when Traefik is already running, their definition can be added to the [dynamic configuration](../getting-started/configuration-overview.md), in the `[[tls]]` section: +To add / remove TLS certificates, even when Traefik is already running, their definition can be added to the [dynamic configuration](../getting-started/configuration-overview.md), in the `[[tls.certificates]]` section: ```toml -[[tls]] - [tls.certificate] - certFile = "/path/to/domain.cert" - keyFile = "/path/to/domain.key" +[[tls.certificates]] + certFile = "/path/to/domain.cert" + keyFile = "/path/to/domain.key" -[[tls]] - [tls.certificate] - certFile = "/path/to/other-domain.cert" - keyFile = "/path/to/other-domain.key" +[[tls.certificates]] + certFile = "/path/to/other-domain.cert" + keyFile = "/path/to/other-domain.key" ``` !!! important "File Provider Only" @@ -35,8 +33,8 @@ To add / remove TLS certificates, even when Traefik is already running, their de In Traefik, certificates are grouped together in certificates stores, which are defined as such: ```toml -[tlsStores] - [tlsStores.default] +[tls.stores] + [tls.stores.default] ``` !!! important "Alpha restriction" @@ -44,21 +42,19 @@ In Traefik, certificates are grouped together in certificates stores, which are During the alpha version, any store definition other than the default one (named `default`) will be ignored, and there is thefore only one globally available TLS store. -In the `[[tls]]` section, a list of stores can then be specified to indicate where the certificates should be stored: +In the `[[tls.certificates]]` section, a list of stores can then be specified to indicate where the certificates should be stored: ```toml -[[tls]] +[[tls.certificates]] stores = ["default"] - [tls.certificate] - certFile = "/path/to/domain.cert" - keyFile = "/path/to/domain.key" + certFile = "/path/to/domain.cert" + keyFile = "/path/to/domain.key" -[[tls]] +[[tls.certificates]] # Note that since no store is defined, # the certificate below will be stored in the `default` store. - [tls.certificate] - certFile = "/path/to/other-domain.cert" - keyFile = "/path/to/other-domain.key" + certFile = "/path/to/other-domain.cert" + keyFile = "/path/to/other-domain.key" ``` !!! important "Alpha restriction" @@ -71,9 +67,9 @@ Traefik can use a default certificate for connections without a SNI, or without This default certificate should be defined in a TLS store: ```toml -[tlsStores] - [tlsStores.default] - [tlsStores.default.defaultCertificate] +[tls.stores] + [tls.stores.default] + [tls.stores.default.defaultCertificate] certFile = "path/to/cert.crt" keyFile = "path/to/cert.key" ``` @@ -87,12 +83,12 @@ The TLS options allow one to configure some parameters of the TLS connection. ### Minimum TLS Version ```toml -[tlsOptions] +[tls.options] - [tlsOptions.default] + [tls.options.default] minVersion = "VersionTLS12" - [tlsOptions.mintls13] + [tls.options.mintls13] minVersion = "VersionTLS13" ``` @@ -107,9 +103,9 @@ For clients with a certificate, the `optional` option governs the behaviour as f - When `optional = true`, Traefik authorizes connections from clients presenting a certificate signed by an unknown CA. ```toml -[tlsOptions] - [tlsOptions.default] - [tlsOptions.default.ClientCA] +[tls.options] + [tls.options.default] + [tls.options.default.ClientCA] # in PEM format. each file can contain multiple CAs. files = ["tests/clientca1.crt", "tests/clientca2.crt"] optional = false @@ -120,8 +116,8 @@ For clients with a certificate, the `optional` option governs the behaviour as f See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more information. ```toml -[tlsOptions] - [tlsOptions.default] +[tls.options] + [tls.options.default] cipherSuites = [ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_256_GCM_SHA384" @@ -134,7 +130,7 @@ With strict SNI checking, Traefik won't allow connections from clients connectio that do not specify a server_name extension. ```toml -[tlsOptions] - [tlsOptions.default] +[tls.options] + [tls.options.default] sniStrict = true ``` diff --git a/docs/content/providers/file.md b/docs/content/providers/file.md index 8c2033568..8a940b943 100644 --- a/docs/content/providers/file.md +++ b/docs/content/providers/file.md @@ -192,16 +192,15 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat {{ end }} {{ range $i, $e := until 10 }} - [[TLS]] + [[tls.certificates]] + CertFile = "/etc/traefik/cert-{{ $e }}.pem" + KeyFile = "/etc/traefik/cert-{{ $e }}.key" Store = ["my-store-foo-{{ $e }}", "my-store-bar-{{ $e }}"] - [TLS.Certificate] - CertFile = "/etc/traefik/cert-{{ $e }}.pem" - KeyFile = "/etc/traefik/cert-{{ $e }}.key" {{ end }} - [TLSConfig] + [tls.config] {{ range $i, $e := until 10 }} - [TLSConfig.TLS{{ $e }}] + [tls.config.TLS{{ $e }}] # ... {{ end }} ``` @@ -237,11 +236,11 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat {{ range $i, $e := until 10 }} tls: - store: - - "my-store-foo-{{ $e }}" - - "my-store-bar-{{ $e }}" - certificate: - certfile: "/etc/traefik/cert-{{ $e }}.pem" + certificates: + - certfile: "/etc/traefik/cert-{{ $e }}.pem" keyfile: "/etc/traefik/cert-{{ $e }}.key" + store: + - "my-store-foo-{{ $e }}" + - "my-store-bar-{{ $e }}" {{end}} ``` diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index 3f5b20af5..1879364b9 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -220,42 +220,40 @@ [[TCP.Services.TCPService0.LoadBalancer.Servers]] Address = "foobar" -[[TLS]] - Stores = ["foobar", "foobar"] - [TLS.Certificate] +[TLS] + + [[TLS.Certificates]] + Stores = ["foobar", "foobar"] CertFile = "foobar" KeyFile = "foobar" -[[TLS]] - Stores = ["foobar", "foobar"] - [TLS.Certificate] + [[TLS.Certificates]] + Stores = ["foobar", "foobar"] CertFile = "foobar" KeyFile = "foobar" -[TLSOptions] + [TLS.Options] + [TLS.Options.TLS0] + MinVersion = "foobar" + CipherSuites = ["foobar", "foobar"] + SniStrict = true + [TLS.Options.TLS0.ClientCA] + Files = ["foobar", "foobar"] + Optional = true + [TLS.Options.TLS1] + MinVersion = "foobar" + CipherSuites = ["foobar", "foobar"] + SniStrict = true + [TLS.Options.TLS1.ClientCA] + Files = ["foobar", "foobar"] + Optional = true - [TLSOptions.TLS0] - MinVersion = "foobar" - CipherSuites = ["foobar", "foobar"] - SniStrict = true - [TLSOptions.TLS0.ClientCA] - Files = ["foobar", "foobar"] - Optional = true - [TLSOptions.TLS1] - MinVersion = "foobar" - CipherSuites = ["foobar", "foobar"] - SniStrict = true - [TLSOptions.TLS1.ClientCA] - Files = ["foobar", "foobar"] - Optional = true - -[TLSStores] - - [TLSStores.Store0] - [TLSStores.Store0.DefaultCertificate] - CertFile = "foobar" - KeyFile = "foobar" - [TLSStores.Store1] - [TLSStores.Store1.DefaultCertificate] - CertFile = "foobar" - KeyFile = "foobar" + [TLS.Stores] + [TLS.Stores.Store0] + [TLS.Stores.Store0.DefaultCertificate] + CertFile = "foobar" + KeyFile = "foobar" + [TLS.Stores.Store1] + [TLS.Stores.Store1.DefaultCertificate] + CertFile = "foobar" + KeyFile = "foobar" diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index ac8990d32..b59513e75 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -207,7 +207,7 @@ Traefik will terminate the SSL connections (meaning that it will send decrypted #### `Options` The `Options` field enables fine-grained control of the TLS parameters. -It refers to a [tlsOptions](../../https/tls.md#tls-options) and will be applied only if a `Host` rule is defined. +It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied only if a `Host` rule is defined. ??? example "Configuring the tls options" @@ -219,8 +219,8 @@ It refers to a [tlsOptions](../../https/tls.md#tls-options) and will be applied [http.routers.Router-1.tls] # will terminate the TLS request options = "foo" - [tlsOptions] - [tlsOptions.foo] + [tls.options] + [tls.options.foo] minVersion = "VersionTLS12" cipherSuites = [ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", @@ -338,7 +338,7 @@ Services are the target for the router. #### `Options` The `Options` field enables fine-grained control of the TLS parameters. -It refers to a [tlsOptions](../../https/tls.md#tls-options) and will be applied only if a `HostSNI` rule is defined. +It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied only if a `HostSNI` rule is defined. ??? example "Configuring the tls options" @@ -350,8 +350,8 @@ It refers to a [tlsOptions](../../https/tls.md#tls-options) and will be applied [tcp.routers.Router-1.tls] # will terminate the TLS request options = "foo" - [tlsOptions] - [tlsOptions.foo] + [tls.options] + [tls.options.foo] minVersion = "VersionTLS12" cipherSuites = [ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", diff --git a/integration/fixtures/acme/acme_tls.toml b/integration/fixtures/acme/acme_tls.toml index 27280bd74..b7ffe5477 100644 --- a/integration/fixtures/acme/acme_tls.toml +++ b/integration/fixtures/acme/acme_tls.toml @@ -54,6 +54,7 @@ level = "DEBUG" service = "test" [http.routers.test.tls] -[tlsStores.default.defaultCertificate] - certFile = "fixtures/acme/ssl/wildcard.crt" - keyFile = "fixtures/acme/ssl/wildcard.key" +[tls.stores] + [tls.stores.default.defaultCertificate] + certFile = "fixtures/acme/ssl/wildcard.crt" + keyFile = "fixtures/acme/ssl/wildcard.key" diff --git a/integration/fixtures/acme/certificates.toml b/integration/fixtures/acme/certificates.toml index ff1653bfd..f0a2c8412 100644 --- a/integration/fixtures/acme/certificates.toml +++ b/integration/fixtures/acme/certificates.toml @@ -1,17 +1,16 @@ [http.services] [http.services.test.loadbalancer] - [[http.services.test.loadbalancer.servers]] - url = "http://127.0.0.1:9010" + [[http.services.test.loadbalancer.servers]] + url = "http://127.0.0.1:9010" [http.routers] [http.routers.test] - entryPoints = ["web-secure"] - rule = "Host(`traefik.acme.wtf`)" - service = "test" - [http.routers.test.tls] + entryPoints = ["web-secure"] + rule = "Host(`traefik.acme.wtf`)" + service = "test" + [http.routers.test.tls] -[[tls]] +[[tls.certificates]] store = ["default"] - [tls.certificate] certFile = "fixtures/acme/ssl/wildcard.crt" keyFile = "fixtures/acme/ssl/wildcard.key" diff --git a/integration/fixtures/grpc/config.toml b/integration/fixtures/grpc/config.toml index 2aa10f1c9..b38ab2ffa 100644 --- a/integration/fixtures/grpc/config.toml +++ b/integration/fixtures/grpc/config.toml @@ -28,6 +28,7 @@ rootCAs = [ """{{ .CertContent }}""" ] [[http.services.service1.loadbalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = """{{ .CertContent }}""" keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/grpc/config_h2c_termination.toml b/integration/fixtures/grpc/config_h2c_termination.toml index 2042816b5..71d3aec6b 100644 --- a/integration/fixtures/grpc/config_h2c_termination.toml +++ b/integration/fixtures/grpc/config_h2c_termination.toml @@ -26,6 +26,7 @@ level = "DEBUG" [[http.services.service1.loadbalancer.servers]] url = "h2c://127.0.0.1:{{ .GRPCServerPort }}" -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = """{{ .CertContent }}""" keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/grpc/config_insecure.toml b/integration/fixtures/grpc/config_insecure.toml index 406f4286a..ce4c7fb4b 100644 --- a/integration/fixtures/grpc/config_insecure.toml +++ b/integration/fixtures/grpc/config_insecure.toml @@ -28,6 +28,7 @@ insecureSkipVerify = true [[http.services.service1.loadbalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = """{{ .CertContent }}""" keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/grpc/config_retry.toml b/integration/fixtures/grpc/config_retry.toml index 0073ca393..f88706400 100644 --- a/integration/fixtures/grpc/config_retry.toml +++ b/integration/fixtures/grpc/config_retry.toml @@ -35,6 +35,7 @@ rootCAs = [ """{{ .CertContent }}""" ] [[http.services.service1.loadbalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = """{{ .CertContent }}""" keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/https/clientca/https_1ca1config.toml b/integration/fixtures/https/clientca/https_1ca1config.toml index 3ee74c690..063b4f22d 100644 --- a/integration/fixtures/https/clientca/https_1ca1config.toml +++ b/integration/fixtures/https/clientca/https_1ca1config.toml @@ -36,16 +36,15 @@ level = "DEBUG" [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.com.cert" - keyFile = "fixtures/https/snitest.com.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.org.cert" - keyFile = "fixtures/https/snitest.org.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.org.cert" + keyFile = "fixtures/https/snitest.org.key" -[tlsOptions.default.ClientCA] +[tls.options] + [tls.options.default.ClientCA] files = ["fixtures/https/clientca/ca1.crt"] optional = true diff --git a/integration/fixtures/https/clientca/https_2ca1config.toml b/integration/fixtures/https/clientca/https_2ca1config.toml index 5497da6cd..e09d2c006 100644 --- a/integration/fixtures/https/clientca/https_2ca1config.toml +++ b/integration/fixtures/https/clientca/https_2ca1config.toml @@ -36,14 +36,14 @@ level = "DEBUG" [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.com.cert" - keyFile = "fixtures/https/snitest.com.key" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.org.cert" - keyFile = "fixtures/https/snitest.org.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" -[tlsOptions.default.ClientCA] +[[tls.certificates]] + certFile = "fixtures/https/snitest.org.cert" + keyFile = "fixtures/https/snitest.org.key" + +[tls.options] + [tls.options.default.ClientCA] files = ["fixtures/https/clientca/ca1and2.crt"] \ No newline at end of file diff --git a/integration/fixtures/https/clientca/https_2ca2config.toml b/integration/fixtures/https/clientca/https_2ca2config.toml index 2b518170d..138ac2a18 100644 --- a/integration/fixtures/https/clientca/https_2ca2config.toml +++ b/integration/fixtures/https/clientca/https_2ca2config.toml @@ -35,16 +35,15 @@ level = "DEBUG" [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.com.cert" - keyFile = "fixtures/https/snitest.com.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.org.cert" - keyFile = "fixtures/https/snitest.org.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.org.cert" + keyFile = "fixtures/https/snitest.org.key" -[tlsOptions.default.ClientCA] +[tls.options] + [tls.options.default.ClientCA] files = ["fixtures/https/clientca/ca1.crt", "fixtures/https/clientca/ca2.crt"] optional = false diff --git a/integration/fixtures/https/dynamic_https.toml b/integration/fixtures/https/dynamic_https.toml index 949b3c4ed..65bfe163f 100644 --- a/integration/fixtures/https/dynamic_https.toml +++ b/integration/fixtures/https/dynamic_https.toml @@ -20,9 +20,8 @@ [[http.services.service2.LoadBalancer.Servers]] url = "http://127.0.0.1:9020" -[[tls]] - # bad certificates to validate the loop on the certificate appending - [tls.certificate] +# bad certificates to validate the loop on the certificate appending +[[tls.certificates]] # bad content certFile = """-----BEGIN CERTIFICATE----- MIIC/zCCAeegAwIBAgIJALAYHG/vGqWEMA0GCSqGSIb3DQEBBQUAMBYxFDASBgNV @@ -34,8 +33,7 @@ eRG3DaVpez4DQVupZDHMgxJUYqqKynUj6GD1YiaxGROj3TYCu6e7OxyhalhCllSu w/X5M802XqzLjeec5zHoZDfknnAkgR9MsxZYmZPFaDyL6GOKUB8= -----END RSA PRIVATE KEY-----""" -[[tls]] - [tls.certificate] +[[tls.certificates]] certFile = """-----BEGIN CERTIFICATE----- MIIC/zCCAeegAwIBAgIJALAYHG/vGqWEMA0GCSqGSIb3DQEBBQUAMBYxFDASBgNV BAMMC3NuaXRlc3Qub3JnMB4XDTE1MTEyMzIyMDU0NFoXDTI1MTEyMDIyMDU0NFow diff --git a/integration/fixtures/https/dynamic_https_sni_default_cert.toml b/integration/fixtures/https/dynamic_https_sni_default_cert.toml index cb0bd446a..50efab1f4 100644 --- a/integration/fixtures/https/dynamic_https_sni_default_cert.toml +++ b/integration/fixtures/https/dynamic_https_sni_default_cert.toml @@ -31,16 +31,15 @@ level = "DEBUG" [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" -[[tls]] - [tls.certificate] +[[tls.certificates]] certFile = "fixtures/https/wildcard.snitest.com.cert" keyFile = "fixtures/https/wildcard.snitest.com.key" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/www.snitest.com.cert" - keyFile = "fixtures/https/www.snitest.com.key" +[[tls.certificates]] + certFile = "fixtures/https/www.snitest.com.cert" + keyFile = "fixtures/https/www.snitest.com.key" -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = "fixtures/https/snitest.com.cert" keyFile = "fixtures/https/snitest.com.key" diff --git a/integration/fixtures/https/https_sni.toml b/integration/fixtures/https/https_sni.toml index 944f11e24..3c184436c 100644 --- a/integration/fixtures/https/https_sni.toml +++ b/integration/fixtures/https/https_sni.toml @@ -36,12 +36,10 @@ level = "DEBUG" [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.com.cert" - keyFile = "fixtures/https/snitest.com.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.org.cert" - keyFile = "fixtures/https/snitest.org.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.org.cert" + keyFile = "fixtures/https/snitest.org.key" diff --git a/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml b/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml index d6501c9cc..364d77816 100644 --- a/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml +++ b/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml @@ -31,11 +31,11 @@ level = "DEBUG" [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/uppercase_wildcard.www.snitest.com.cert" - keyFile = "fixtures/https/uppercase_wildcard.www.snitest.com.key" +[[tls.certificates]] + certFile = "fixtures/https/uppercase_wildcard.www.snitest.com.cert" + keyFile = "fixtures/https/uppercase_wildcard.www.snitest.com.key" -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = "fixtures/https/wildcard.snitest.com.cert" keyFile = "fixtures/https/wildcard.snitest.com.key" diff --git a/integration/fixtures/https/https_sni_default_cert.toml b/integration/fixtures/https/https_sni_default_cert.toml index b5034dcea..50efab1f4 100644 --- a/integration/fixtures/https/https_sni_default_cert.toml +++ b/integration/fixtures/https/https_sni_default_cert.toml @@ -31,16 +31,15 @@ level = "DEBUG" [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/wildcard.snitest.com.cert" - keyFile = "fixtures/https/wildcard.snitest.com.key" +[[tls.certificates]] + certFile = "fixtures/https/wildcard.snitest.com.cert" + keyFile = "fixtures/https/wildcard.snitest.com.key" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/www.snitest.com.cert" - keyFile = "fixtures/https/www.snitest.com.key" +[[tls.certificates]] + certFile = "fixtures/https/www.snitest.com.cert" + keyFile = "fixtures/https/www.snitest.com.key" -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = "fixtures/https/snitest.com.cert" keyFile = "fixtures/https/snitest.com.key" diff --git a/integration/fixtures/https/https_sni_strict.toml b/integration/fixtures/https/https_sni_strict.toml index 6cca5d576..dce7c13a2 100644 --- a/integration/fixtures/https/https_sni_strict.toml +++ b/integration/fixtures/https/https_sni_strict.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] @@ -26,11 +26,13 @@ level = "DEBUG" [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" -[tlsOptions.default] +[tls.options] + [tls.options.default] sniStrict = true -[tlsStores.default] - [tlsStores.default.DefaultCertificate] - certFile = "fixtures/https/snitest.com.cert" - keyFile = "fixtures/https/snitest.com.key" +[tls.stores] + [tls.stores.default] + [tls.stores.default.DefaultCertificate] + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" diff --git a/integration/fixtures/https/https_tls_options.toml b/integration/fixtures/https/https_tls_options.toml index 680db609c..aad21a2c4 100644 --- a/integration/fixtures/https/https_tls_options.toml +++ b/integration/fixtures/https/https_tls_options.toml @@ -44,18 +44,18 @@ level = "DEBUG" [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.com.cert" - keyFile = "fixtures/https/snitest.com.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" -[[tls]] - [tls.certificate] - certFile = "fixtures/https/snitest.org.cert" - keyFile = "fixtures/https/snitest.org.key" +[[tls.certificates]] + certFile = "fixtures/https/snitest.org.cert" + keyFile = "fixtures/https/snitest.org.key" -[tlsoptions.foo] +[tls.options] + + [tls.options.foo] minversion = "VersionTLS11" -[tlsoptions.bar] + [tls.options.bar] minversion = "VersionTLS12" diff --git a/integration/fixtures/tcp/mixed.toml b/integration/fixtures/tcp/mixed.toml index 8a73f837c..a94b7c640 100644 --- a/integration/fixtures/tcp/mixed.toml +++ b/integration/fixtures/tcp/mixed.toml @@ -64,7 +64,6 @@ level = "DEBUG" [[tcp.services.whoami-no-cert.loadbalancer.servers]] address = "localhost:8083" -[[tls]] - [tls.certificate] +[[tls.certificates]] certFile = "fixtures/tcp/whoami-c.crt" keyFile = "fixtures/tcp/whoami-c.key" diff --git a/integration/fixtures/tcp/multi-tls-options.toml b/integration/fixtures/tcp/multi-tls-options.toml index 36b75fc67..5551a4088 100644 --- a/integration/fixtures/tcp/multi-tls-options.toml +++ b/integration/fixtures/tcp/multi-tls-options.toml @@ -35,8 +35,10 @@ level = "DEBUG" [[tcp.services.whoami-no-cert.loadbalancer.servers]] address = "localhost:8083" -[tlsoptions.foo] +[tls.options] + + [tls.options.foo] minversion = "VersionTLS11" -[tlsoptions.bar] + [tls.options.bar] minversion = "VersionTLS12" diff --git a/integration/fixtures/tlsclientheaders/simple.toml b/integration/fixtures/tlsclientheaders/simple.toml index 609c4ef5f..26c2cbe7b 100644 --- a/integration/fixtures/tlsclientheaders/simple.toml +++ b/integration/fixtures/tlsclientheaders/simple.toml @@ -1,12 +1,12 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport] -rootCAs = [ """{{ .RootCertContent }}""" ] + rootCAs = [ """{{ .RootCertContent }}""" ] [entryPoints] [entryPoints.web-secure] @@ -15,16 +15,18 @@ rootCAs = [ """{{ .RootCertContent }}""" ] [api] [providers] - [providers.docker] - endpoint = "unix:///var/run/docker.sock" - watch = true + [providers.docker] + endpoint = "unix:///var/run/docker.sock" + watch = true - [providers.file] + [providers.file] -[tlsOptions.default.ClientCA] +[tls.options] + [tls.options.default.ClientCA] files = [ """{{ .RootCertContent }}""" ] optional = false -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = """{{ .ServerCertContent }}""" keyFile = """{{ .ServerKeyContent }}""" diff --git a/integration/fixtures/websocket/config_https.toml b/integration/fixtures/websocket/config_https.toml index a1e672c20..a1fa2f43a 100644 --- a/integration/fixtures/websocket/config_https.toml +++ b/integration/fixtures/websocket/config_https.toml @@ -30,6 +30,7 @@ insecureSkipVerify=true [[http.services.service1.LoadBalancer.Servers]] URL = "{{ .WebsocketServer }}" -[tlsStores.default.DefaultCertificate] +[tls.stores] + [tls.stores.default.DefaultCertificate] certFile = "resources/tls/local.cert" keyFile = "resources/tls/local.key" diff --git a/integration/https_test.go b/integration/https_test.go index 6923f076d..cdbc58489 100644 --- a/integration/https_test.go +++ b/integration/https_test.go @@ -799,12 +799,14 @@ func modifyCertificateConfFileContent(c *check.C, certFileName, confFileName, en // If certificate file is not provided, just truncate the configuration file if len(certFileName) > 0 { tlsConf := config.Configuration{ - TLS: []*traefiktls.Configuration{{ - Certificate: &traefiktls.Certificate{ - CertFile: traefiktls.FileOrContent("fixtures/https/" + certFileName + ".cert"), - KeyFile: traefiktls.FileOrContent("fixtures/https/" + certFileName + ".key"), + TLS: &config.TLSConfiguration{ + Certificates: []*traefiktls.CertAndStores{{ + Certificate: traefiktls.Certificate{ + CertFile: traefiktls.FileOrContent("fixtures/https/" + certFileName + ".cert"), + KeyFile: traefiktls.FileOrContent("fixtures/https/" + certFileName + ".key"), + }}, }, - }}, + }, } var confBuffer bytes.Buffer diff --git a/pkg/config/dyn_config.go b/pkg/config/dyn_config.go index 6b7577945..032cff288 100644 --- a/pkg/config/dyn_config.go +++ b/pkg/config/dyn_config.go @@ -213,24 +213,29 @@ type Message struct { // Configuration is the root of the dynamic configuration type Configuration struct { - HTTP *HTTPConfiguration - TCP *TCPConfiguration - TLS []*traefiktls.Configuration `json:"-" label:"-" yaml:"tls"` - TLSOptions map[string]traefiktls.TLS - TLSStores map[string]traefiktls.Store + HTTP *HTTPConfiguration + TCP *TCPConfiguration + TLS *TLSConfiguration +} + +// TLSConfiguration contains all the configuration parameters of a TLS connection. +type TLSConfiguration struct { + Certificates []*traefiktls.CertAndStores `json:"-" label:"-" yaml:"certificates"` + Options map[string]traefiktls.Options + Stores map[string]traefiktls.Store } // Configurations is for currentConfigurations Map. type Configurations map[string]*Configuration -// HTTPConfiguration FIXME better name? +// HTTPConfiguration contains all the HTTP configuration parameters. type HTTPConfiguration struct { Routers map[string]*Router `json:"routers,omitempty" toml:",omitempty"` Middlewares map[string]*Middleware `json:"middlewares,omitempty" toml:",omitempty"` Services map[string]*Service `json:"services,omitempty" toml:",omitempty"` } -// TCPConfiguration FIXME better name? +// TCPConfiguration contains all the TCP configuration parameters. type TCPConfiguration struct { Routers map[string]*TCPRouter `json:"routers,omitempty" toml:",omitempty"` Services map[string]*TCPService `json:"services,omitempty" toml:",omitempty"` diff --git a/pkg/config/file/fixtures/sample.toml b/pkg/config/file/fixtures/sample.toml index 04d8bc9c5..8ef1d61b8 100644 --- a/pkg/config/file/fixtures/sample.toml +++ b/pkg/config/file/fixtures/sample.toml @@ -497,42 +497,40 @@ [[TCP.Services.TCPService0.LoadBalancer.Servers]] Address = "foobar" -[[TLS]] +[[TLS.Certificates]] Stores = ["foobar", "foobar"] - [TLS.Certificate] - CertFile = "foobar" - KeyFile = "foobar" + CertFile = "foobar" + KeyFile = "foobar" -[[TLS]] +[[TLS.Certificates]] Stores = ["foobar", "foobar"] - [TLS.Certificate] - CertFile = "foobar" - KeyFile = "foobar" + CertFile = "foobar" + KeyFile = "foobar" -[TLSOptions] +[TLS.Options] - [TLSOptions.TLS0] + [TLS.Options.TLS0] MinVersion = "foobar" CipherSuites = ["foobar", "foobar"] SniStrict = true - [TLSOptions.TLS0.ClientCA] + [TLS.Options.TLS0.ClientCA] Files = ["foobar", "foobar"] Optional = true - [TLSOptions.TLS1] + [TLS.Options.TLS1] MinVersion = "foobar" CipherSuites = ["foobar", "foobar"] SniStrict = true - [TLSOptions.TLS1.ClientCA] + [TLS.Options.TLS1.ClientCA] Files = ["foobar", "foobar"] Optional = true -[TLSStores] +[TLS.Stores] - [TLSStores.Store0] - [TLSStores.Store0.DefaultCertificate] + [TLS.Stores.Store0] + [TLS.Stores.Store0.DefaultCertificate] CertFile = "foobar" KeyFile = "foobar" - [TLSStores.Store1] - [TLSStores.Store1.DefaultCertificate] + [TLS.Stores.Store1] + [TLS.Stores.Store1.DefaultCertificate] CertFile = "foobar" KeyFile = "foobar" diff --git a/pkg/provider/acme/provider.go b/pkg/provider/acme/provider.go index 8cdfd58b9..39e2ba072 100644 --- a/pkg/provider/acme/provider.go +++ b/pkg/provider/acme/provider.go @@ -589,14 +589,20 @@ func (p *Provider) refreshCertificates() { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, - TLS: []*traefiktls.Configuration{}, + TLS: &config.TLSConfiguration{}, }, } for _, cert := range p.certificates { - cert := &traefiktls.Certificate{CertFile: traefiktls.FileOrContent(cert.Certificate), KeyFile: traefiktls.FileOrContent(cert.Key)} - conf.Configuration.TLS = append(conf.Configuration.TLS, &traefiktls.Configuration{Certificate: cert}) + certConf := &traefiktls.CertAndStores{ + Certificate: traefiktls.Certificate{ + CertFile: traefiktls.FileOrContent(cert.Certificate), + KeyFile: traefiktls.FileOrContent(cert.Key), + }, + } + conf.Configuration.TLS.Certificates = append(conf.Configuration.TLS.Certificates, certConf) } + p.configurationChan <- conf } diff --git a/pkg/provider/file/file.go b/pkg/provider/file/file.go index 57903ec3d..cceb93fbb 100644 --- a/pkg/provider/file/file.go +++ b/pkg/provider/file/file.go @@ -182,28 +182,36 @@ func (p *Provider) loadFileConfig(filename string, parseTemplate bool) (*config. return nil, err } - var tlsConfigs []*tls.Configuration - for _, conf := range configuration.TLS { - bytes, err := conf.Certificate.CertFile.Read() - if err != nil { - log.Error(err) - continue - } - conf.Certificate.CertFile = tls.FileOrContent(string(bytes)) - - bytes, err = conf.Certificate.KeyFile.Read() - if err != nil { - log.Error(err) - continue - } - conf.Certificate.KeyFile = tls.FileOrContent(string(bytes)) - tlsConfigs = append(tlsConfigs, conf) + if configuration.TLS != nil { + configuration.TLS.Certificates = flattenCertificates(configuration.TLS) } - configuration.TLS = tlsConfigs return configuration, nil } +func flattenCertificates(tlsConfig *config.TLSConfiguration) []*tls.CertAndStores { + var certs []*tls.CertAndStores + for _, cert := range tlsConfig.Certificates { + content, err := cert.Certificate.CertFile.Read() + if err != nil { + log.Error(err) + continue + } + cert.Certificate.CertFile = tls.FileOrContent(string(content)) + + content, err = cert.Certificate.KeyFile.Read() + if err != nil { + log.Error(err) + continue + } + cert.Certificate.KeyFile = tls.FileOrContent(string(content)) + + certs = append(certs, cert) + } + + return certs +} + func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory string, configuration *config.Configuration) (*config.Configuration, error) { logger := log.FromContext(ctx) @@ -223,13 +231,16 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st Routers: make(map[string]*config.TCPRouter), Services: make(map[string]*config.TCPService), }, + TLS: &config.TLSConfiguration{ + Stores: make(map[string]tls.Store), + Options: make(map[string]tls.Options), + }, } } - configTLSMaps := make(map[*tls.Configuration]struct{}) + configTLSMaps := make(map[*tls.CertAndStores]struct{}) for _, item := range fileList { - if item.IsDir() { configuration, err = p.loadFileConfigFromDirectory(ctx, filepath.Join(directory, item.Name()), configuration) if err != nil { @@ -291,7 +302,7 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st } } - for _, conf := range c.TLS { + for _, conf := range c.TLS.Certificates { if _, exists := configTLSMaps[conf]; exists { logger.Warnf("TLS configuration %v already configured, skipping", conf) } else { @@ -300,9 +311,14 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st } } - for conf := range configTLSMaps { - configuration.TLS = append(configuration.TLS, conf) + if len(configTLSMaps) > 0 { + configuration.TLS = &config.TLSConfiguration{} } + + for conf := range configTLSMaps { + configuration.TLS.Certificates = append(configuration.TLS.Certificates, conf) + } + return configuration, nil } @@ -364,9 +380,10 @@ func (p *Provider) decodeConfiguration(filePath string, content string) (*config Routers: make(map[string]*config.TCPRouter), Services: make(map[string]*config.TCPService), }, - TLS: make([]*tls.Configuration, 0), - TLSStores: make(map[string]tls.Store), - TLSOptions: make(map[string]tls.TLS), + TLS: &config.TLSConfiguration{ + Stores: make(map[string]tls.Store), + Options: make(map[string]tls.Options), + }, } switch strings.ToLower(filepath.Ext(filePath)) { diff --git a/pkg/provider/file/file_test.go b/pkg/provider/file/file_test.go index 46f28354b..019e74036 100644 --- a/pkg/provider/file/file_test.go +++ b/pkg/provider/file/file_test.go @@ -37,10 +37,9 @@ func TestTLSContent(t *testing.T) { require.NoError(t, err) content := ` -[[tls]] - [tls.certificate] - certFile = "` + fileTLS.Name() + `" - keyFile = "` + fileTLS.Name() + `" +[[tls.certificates]] + certFile = "` + fileTLS.Name() + `" + keyFile = "` + fileTLS.Name() + `" ` _, err = fileConfig.Write([]byte(content)) @@ -50,8 +49,8 @@ func TestTLSContent(t *testing.T) { configuration, err := provider.loadFileConfig(fileConfig.Name(), true) require.NoError(t, err) - require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.CertFile.String()) - require.Equal(t, "CONTENT", configuration.TLS[0].Certificate.KeyFile.String()) + require.Equal(t, "CONTENT", configuration.TLS.Certificates[0].Certificate.CertFile.String()) + require.Equal(t, "CONTENT", configuration.TLS.Certificates[0].Certificate.KeyFile.String()) } func TestErrorWhenEmptyConfig(t *testing.T) { @@ -91,9 +90,11 @@ func TestProvideWithoutWatch(t *testing.T) { timeout := time.After(time.Second) select { case conf := <-configChan: + require.NotNil(t, conf.Configuration.HTTP) assert.Len(t, conf.Configuration.HTTP.Services, test.expectedNumService) assert.Len(t, conf.Configuration.HTTP.Routers, test.expectedNumRouter) - assert.Len(t, conf.Configuration.TLS, test.expectedNumTLSConf) + require.NotNil(t, conf.Configuration.TLS) + assert.Len(t, conf.Configuration.TLS.Certificates, test.expectedNumTLSConf) case <-timeout: t.Errorf("timeout while waiting for config") } @@ -116,9 +117,11 @@ func TestProvideWithWatch(t *testing.T) { timeout := time.After(time.Second) select { case conf := <-configChan: + require.NotNil(t, conf.Configuration.HTTP) assert.Len(t, conf.Configuration.HTTP.Services, 0) assert.Len(t, conf.Configuration.HTTP.Routers, 0) - assert.Len(t, conf.Configuration.TLS, 0) + require.NotNil(t, conf.Configuration.TLS) + assert.Len(t, conf.Configuration.TLS.Certificates, 0) case <-timeout: t.Errorf("timeout while waiting for config") } @@ -148,7 +151,7 @@ func TestProvideWithWatch(t *testing.T) { numUpdates++ numServices = len(conf.Configuration.HTTP.Services) numRouters = len(conf.Configuration.HTTP.Routers) - numTLSConfs = len(conf.Configuration.TLS) + numTLSConfs = len(conf.Configuration.TLS.Certificates) t.Logf("received update #%d: services %d/%d, routers %d/%d, TLS configs %d/%d", numUpdates, numServices, test.expectedNumService, numRouters, test.expectedNumRouter, numTLSConfs, test.expectedNumTLSConf) if numServices == test.expectedNumService && numRouters == test.expectedNumRouter && numTLSConfs == test.expectedNumTLSConf { diff --git a/pkg/provider/file/fixtures/toml/dir01_file03.toml b/pkg/provider/file/fixtures/toml/dir01_file03.toml index 498a19b91..7d5a35e0d 100644 --- a/pkg/provider/file/fixtures/toml/dir01_file03.toml +++ b/pkg/provider/file/fixtures/toml/dir01_file03.toml @@ -1,16 +1,17 @@ -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" +[TLS] + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_file_01.toml b/pkg/provider/file/fixtures/toml/simple_file_01.toml index e3af6f686..287597951 100644 --- a/pkg/provider/file/fixtures/toml/simple_file_01.toml +++ b/pkg/provider/file/fixtures/toml/simple_file_01.toml @@ -33,23 +33,25 @@ [http.services.application-6.loadbalancer] [[http.services.application-6.loadbalancer.servers]] url = "http://172.17.0.6:80" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest5.com.cert" - KeyFile = "integration/fixtures/https/snitest5.com.key" + +[TLS] + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest5.com.cert" + KeyFile = "integration/fixtures/https/snitest5.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_file_02.toml b/pkg/provider/file/fixtures/toml/simple_file_02.toml index e614160d3..2b4feb4a4 100644 --- a/pkg/provider/file/fixtures/toml/simple_file_02.toml +++ b/pkg/provider/file/fixtures/toml/simple_file_02.toml @@ -44,19 +44,21 @@ [http.services.application-8.loadbalancer] [[http.services.application-8.loadbalancer.servers]] url = "http://172.17.0.8:80" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" + +[TLS] + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml index 2aa73ad54..db2d68bfc 100644 --- a/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_01.toml @@ -1,3 +1,2 @@ - [log] - level = "DEBUG" + level = "DEBUG" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml index 4d9e472f5..dcc1c678d 100644 --- a/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml @@ -20,19 +20,21 @@ [http.services.application-3.loadbalancer] [[http.services.application-3.loadbalancer.servers]] url = "http://172.17.0.3:80" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" + +[TLS] + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml index 99bb1bc14..c07e8601c 100644 --- a/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml @@ -1,7 +1,8 @@ +temp="{{ getTag \"test\" }}" - temp="{{ getTag \"test\" }}" - [providers.file] - [http.routers] +[providers.file] + +[http.routers] [http.routers."router1"] service = "application-1" @@ -21,19 +22,21 @@ [http.services.application-3.loadbalancer] [[http.services.application-3.loadbalancer.servers]] url = "http://172.17.0.3:80" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS]] - [TLS.Certificate] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" + +[TLS] + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest1.com.cert" + KeyFile = "integration/fixtures/https/snitest1.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest2.com.cert" + KeyFile = "integration/fixtures/https/snitest2.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest3.com.cert" + KeyFile = "integration/fixtures/https/snitest3.com.key" + +[[TLS.Certificates]] + CertFile = "integration/fixtures/https/snitest4.com.cert" + KeyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/template_file.toml b/pkg/provider/file/fixtures/toml/template_file.toml index 1958d6387..062788f9d 100644 --- a/pkg/provider/file/fixtures/toml/template_file.toml +++ b/pkg/provider/file/fixtures/toml/template_file.toml @@ -1,4 +1,3 @@ - [http.routers] {{ range $i, $e := until 20 }} [http.routers.router{{ $e }}] diff --git a/pkg/provider/file/fixtures/yaml/dir01_file03.yml b/pkg/provider/file/fixtures/yaml/dir01_file03.yml index e243d4fa8..3bd36db08 100644 --- a/pkg/provider/file/fixtures/yaml/dir01_file03.yml +++ b/pkg/provider/file/fixtures/yaml/dir01_file03.yml @@ -1,13 +1,10 @@ tls: - - certificate: - certfile: integration/fixtures/https/snitest1.com.cert - keyfile: integration/fixtures/https/snitest1.com.key - - certificate: - certfile: integration/fixtures/https/snitest2.com.cert - keyfile: integration/fixtures/https/snitest2.com.key - - certificate: - certfile: integration/fixtures/https/snitest3.com.cert - keyfile: integration/fixtures/https/snitest3.com.key - - certificate: - certfile: integration/fixtures/https/snitest4.com.cert - keyfile: integration/fixtures/https/snitest4.com.key + certificates: + - certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_file_01.yml b/pkg/provider/file/fixtures/yaml/simple_file_01.yml index b2fc6e191..e1cd1cb5b 100644 --- a/pkg/provider/file/fixtures/yaml/simple_file_01.yml +++ b/pkg/provider/file/fixtures/yaml/simple_file_01.yml @@ -33,18 +33,14 @@ http: - url: 'http://172.17.0.6:80' tls: - - certificate: - certfile: integration/fixtures/https/snitest1.com.cert - keyfile: integration/fixtures/https/snitest1.com.key - - certificate: - certfile: integration/fixtures/https/snitest2.com.cert - keyfile: integration/fixtures/https/snitest2.com.key - - certificate: - certfile: integration/fixtures/https/snitest3.com.cert - keyfile: integration/fixtures/https/snitest3.com.key - - certificate: - certfile: integration/fixtures/https/snitest4.com.cert - keyfile: integration/fixtures/https/snitest4.com.key - - certificate: - certfile: integration/fixtures/https/snitest5.com.cert - keyfile: integration/fixtures/https/snitest5.com.key + certificates: + - certfile: integration/fixtures/https/snitest1.com.cert + keyfile: integration/fixtures/https/snitest1.com.key + - certfile: integration/fixtures/https/snitest2.com.cert + keyfile: integration/fixtures/https/snitest2.com.key + - certfile: integration/fixtures/https/snitest3.com.cert + keyfile: integration/fixtures/https/snitest3.com.key + - certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key + - certfile: integration/fixtures/https/snitest5.com.cert + keyfile: integration/fixtures/https/snitest5.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_file_02.yml b/pkg/provider/file/fixtures/yaml/simple_file_02.yml index ae40b8789..6066f9a57 100644 --- a/pkg/provider/file/fixtures/yaml/simple_file_02.yml +++ b/pkg/provider/file/fixtures/yaml/simple_file_02.yml @@ -43,16 +43,12 @@ http: - url: 'http://172.17.0.8:80' tls: - - certificate: - certfile: integration/fixtures/https/snitest1.com.cert + certificates: + - certfile: integration/fixtures/https/snitest1.com.cert keyfile: integration/fixtures/https/snitest1.com.key - - certificate: - certfile: integration/fixtures/https/snitest2.com.cert + - certfile: integration/fixtures/https/snitest2.com.cert keyfile: integration/fixtures/https/snitest2.com.key - - certificate: - certfile: integration/fixtures/https/snitest3.com.cert + - certfile: integration/fixtures/https/snitest3.com.cert keyfile: integration/fixtures/https/snitest3.com.key - - certificate: - certfile: integration/fixtures/https/snitest4.com.cert - keyfile: integration/fixtures/https/snitest4.com.key - + - certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key \ No newline at end of file diff --git a/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml b/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml index f8733b514..4d6f87160 100644 --- a/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml +++ b/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml @@ -21,15 +21,12 @@ http: - url: 'http://172.17.0.3:80' tls: - - certificate: - certfile: integration/fixtures/https/snitest1.com.cert + certificates: + - certfile: integration/fixtures/https/snitest1.com.cert keyfile: integration/fixtures/https/snitest1.com.key - - certificate: - certfile: integration/fixtures/https/snitest2.com.cert + - certfile: integration/fixtures/https/snitest2.com.cert keyfile: integration/fixtures/https/snitest2.com.key - - certificate: - certfile: integration/fixtures/https/snitest3.com.cert + - certfile: integration/fixtures/https/snitest3.com.cert keyfile: integration/fixtures/https/snitest3.com.key - - certificate: - certfile: integration/fixtures/https/snitest4.com.cert - keyfile: integration/fixtures/https/snitest4.com.key + - certfile: integration/fixtures/https/snitest4.com.cert + keyfile: integration/fixtures/https/snitest4.com.key \ No newline at end of file diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index a18781d69..07c3e7610 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -293,14 +293,14 @@ func loadServers(client Client, namespace string, svc v1alpha1.Service) ([]confi return servers, nil } -func buildTLSOptions(ctx context.Context, client Client) map[string]tls.TLS { +func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options { tlsOptionsCRD := client.GetTLSOptions() - var tlsOptions map[string]tls.TLS + var tlsOptions map[string]tls.Options if len(tlsOptionsCRD) == 0 { return tlsOptions } - tlsOptions = make(map[string]tls.TLS) + tlsOptions = make(map[string]tls.Options) for _, tlsOption := range tlsOptionsCRD { logger := log.FromContext(log.With(ctx, log.Str("tlsOption", tlsOption.Name), log.Str("namespace", tlsOption.Namespace))) @@ -327,7 +327,7 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.TLS { clientCAs = append(clientCAs, tls.FileOrContent(cert)) } - tlsOptions[makeID(tlsOption.Namespace, tlsOption.Name)] = tls.TLS{ + tlsOptions[makeID(tlsOption.Namespace, tlsOption.Name)] = tls.Options{ MinVersion: tlsOption.Spec.MinVersion, CipherSuites: tlsOption.Spec.CipherSuites, ClientCA: tls.ClientCA{ @@ -340,7 +340,7 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.TLS { return tlsOptions } -func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.Configuration) *config.HTTPConfiguration { +func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores) *config.HTTPConfiguration { conf := &config.HTTPConfiguration{ Routers: map[string]*config.Router{}, Middlewares: map[string]*config.Middleware{}, @@ -465,7 +465,7 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli return conf } -func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.Configuration) *config.TCPConfiguration { +func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores) *config.TCPConfiguration { conf := &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, @@ -565,12 +565,14 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client } func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) *config.Configuration { - tlsConfigs := make(map[string]*tls.Configuration) + tlsConfigs := make(map[string]*tls.CertAndStores) conf := &config.Configuration{ - HTTP: p.loadIngressRouteConfiguration(ctx, client, tlsConfigs), - TCP: p.loadIngressRouteTCPConfiguration(ctx, client, tlsConfigs), - TLSOptions: buildTLSOptions(ctx, client), - TLS: getTLSConfig(tlsConfigs), + HTTP: p.loadIngressRouteConfiguration(ctx, client, tlsConfigs), + TCP: p.loadIngressRouteTCPConfiguration(ctx, client, tlsConfigs), + TLS: &config.TLSConfiguration{ + Certificates: getTLSConfig(tlsConfigs), + Options: buildTLSOptions(ctx, client), + }, } for _, middleware := range client.GetMiddlewares() { @@ -604,7 +606,7 @@ func shouldProcessIngress(ingressClass string, ingressClassAnnotation string) bo (len(ingressClass) == 0 && ingressClassAnnotation == traefikDefaultIngressClass) } -func getTLSHTTP(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sClient Client, tlsConfigs map[string]*tls.Configuration) error { +func getTLSHTTP(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { if ingressRoute.Spec.TLS == nil { return nil } @@ -626,7 +628,7 @@ func getTLSHTTP(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sCli return nil } -func getTLSTCP(ctx context.Context, ingressRoute *v1alpha1.IngressRouteTCP, k8sClient Client, tlsConfigs map[string]*tls.Configuration) error { +func getTLSTCP(ctx context.Context, ingressRoute *v1alpha1.IngressRouteTCP, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { if ingressRoute.Spec.TLS == nil { return nil } @@ -648,7 +650,7 @@ func getTLSTCP(ctx context.Context, ingressRoute *v1alpha1.IngressRouteTCP, k8sC return nil } -func getTLS(k8sClient Client, secretName, namespace string) (*tls.Configuration, error) { +func getTLS(k8sClient Client, secretName, namespace string) (*tls.CertAndStores, error) { secret, exists, err := k8sClient.GetSecret(namespace, secretName) if err != nil { return nil, fmt.Errorf("failed to fetch secret %s/%s: %v", namespace, secretName, err) @@ -662,22 +664,22 @@ func getTLS(k8sClient Client, secretName, namespace string) (*tls.Configuration, return nil, err } - return &tls.Configuration{ - Certificate: &tls.Certificate{ + return &tls.CertAndStores{ + Certificate: tls.Certificate{ CertFile: tls.FileOrContent(cert), KeyFile: tls.FileOrContent(key), }, }, nil } -func getTLSConfig(tlsConfigs map[string]*tls.Configuration) []*tls.Configuration { +func getTLSConfig(tlsConfigs map[string]*tls.CertAndStores) []*tls.CertAndStores { var secretNames []string for secretName := range tlsConfigs { secretNames = append(secretNames, secretName) } sort.Strings(secretNames) - var configs []*tls.Configuration + var configs []*tls.CertAndStores for _, secretName := range secretNames { configs = append(configs, tlsConfigs[secretName]) } diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index c8df41c86..8e48e71d3 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -31,6 +31,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, { @@ -67,6 +68,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + TLS: &config.TLSConfiguration{}, }, }, { @@ -122,6 +124,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, { @@ -165,6 +168,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, { @@ -181,6 +185,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, { @@ -196,6 +201,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, { @@ -211,17 +217,20 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, { desc: "TLS", paths: []string{"tcp/services.yml", "tcp/with_tls.yml"}, expected: &config.Configuration{ - TLS: []*tls.Configuration{ - { - Certificate: &tls.Certificate{ - CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), - KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"), + TLS: &config.TLSConfiguration{ + Certificates: []*tls.CertAndStores{ + { + Certificate: tls.Certificate{ + CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"), + }, }, }, }, @@ -295,27 +304,30 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, { desc: "TLS with tls options", paths: []string{"tcp/services.yml", "tcp/with_tls_options.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "default/foo": { - MinVersion: "VersionTLS12", - CipherSuites: []string{ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - }, - ClientCA: tls.ClientCA{ - Files: []tls.FileOrContent{ - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "default/foo": { + MinVersion: "VersionTLS12", + CipherSuites: []string{ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", }, - Optional: true, + ClientCA: tls.ClientCA{ + Files: []tls.FileOrContent{ + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + }, + Optional: true, + }, + SniStrict: true, }, - SniStrict: true, }, }, TCP: &config.TCPConfiguration{ @@ -357,21 +369,23 @@ func TestLoadIngressRouteTCPs(t *testing.T) { desc: "TLS with tls options and specific namespace", paths: []string{"tcp/services.yml", "tcp/with_tls_options_and_specific_namespace.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "myns/foo": { - MinVersion: "VersionTLS12", - CipherSuites: []string{ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - }, - ClientCA: tls.ClientCA{ - Files: []tls.FileOrContent{ - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "myns/foo": { + MinVersion: "VersionTLS12", + CipherSuites: []string{ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", }, - Optional: true, + ClientCA: tls.ClientCA{ + Files: []tls.FileOrContent{ + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + }, + Optional: true, + }, + SniStrict: true, }, - SniStrict: true, }, }, TCP: &config.TCPConfiguration{ @@ -413,20 +427,22 @@ func TestLoadIngressRouteTCPs(t *testing.T) { desc: "TLS with bad tls options", paths: []string{"tcp/services.yml", "tcp/with_bad_tls_options.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "default/foo": { - MinVersion: "VersionTLS12", - CipherSuites: []string{ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - }, - ClientCA: tls.ClientCA{ - Files: []tls.FileOrContent{ - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "default/foo": { + MinVersion: "VersionTLS12", + CipherSuites: []string{ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", }, - Optional: true, + ClientCA: tls.ClientCA{ + Files: []tls.FileOrContent{ + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + }, + Optional: true, + }, + SniStrict: true, }, - SniStrict: true, }, }, TCP: &config.TCPConfiguration{ @@ -468,9 +484,11 @@ func TestLoadIngressRouteTCPs(t *testing.T) { desc: "TLS with unknown tls options", paths: []string{"tcp/services.yml", "tcp/with_unknown_tls_options.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "default/foo": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "default/foo": { + MinVersion: "VersionTLS12", + }, }, }, TCP: &config.TCPConfiguration{ @@ -512,9 +530,11 @@ func TestLoadIngressRouteTCPs(t *testing.T) { desc: "TLS with unknown tls options namespace", paths: []string{"tcp/services.yml", "tcp/with_unknown_tls_options_namespace.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "default/foo": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "default/foo": { + MinVersion: "VersionTLS12", + }, }, }, TCP: &config.TCPConfiguration{ @@ -587,6 +607,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, } @@ -627,6 +648,7 @@ func TestLoadIngressRoutes(t *testing.T) { Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, + TLS: &config.TLSConfiguration{}, }, }, { @@ -663,6 +685,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, }, + TLS: &config.TLSConfiguration{}, }, }, { @@ -711,12 +734,14 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, }, + TLS: &config.TLSConfiguration{}, }, }, { desc: "Simple Ingress Route with middleware crossprovider", paths: []string{"services.yml", "with_middleware_crossprovider.yml"}, expected: &config.Configuration{ + TLS: &config.TLSConfiguration{}, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, @@ -814,12 +839,14 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, }, + TLS: &config.TLSConfiguration{}, }, }, { desc: "One ingress Route with two different services, their servers will merge", paths: []string{"services.yml", "with_two_services.yml"}, expected: &config.Configuration{ + TLS: &config.TLSConfiguration{}, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, @@ -863,6 +890,7 @@ func TestLoadIngressRoutes(t *testing.T) { paths: []string{"services.yml", "simple.yml"}, ingressClass: "tchouk", expected: &config.Configuration{ + TLS: &config.TLSConfiguration{}, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, @@ -878,6 +906,7 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "Route with empty rule value is ignored", paths: []string{"services.yml", "with_no_rule_value.yml"}, expected: &config.Configuration{ + TLS: &config.TLSConfiguration{}, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, @@ -893,6 +922,7 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "Route with kind not of a rule type (empty kind) is ignored", paths: []string{"services.yml", "with_wrong_rule_kind.yml"}, expected: &config.Configuration{ + TLS: &config.TLSConfiguration{}, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, @@ -908,6 +938,7 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "check rule quoting validity", paths: []string{"services.yml", "with_bad_host_rule.yml"}, expected: &config.Configuration{ + TLS: &config.TLSConfiguration{}, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, @@ -923,11 +954,13 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "TLS", paths: []string{"services.yml", "with_tls.yml"}, expected: &config.Configuration{ - TLS: []*tls.Configuration{ - { - Certificate: &tls.Certificate{ - CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), - KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"), + TLS: &config.TLSConfiguration{ + Certificates: []*tls.CertAndStores{ + { + Certificate: tls.Certificate{ + CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"), + }, }, }, }, @@ -968,21 +1001,23 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "TLS with tls options", paths: []string{"services.yml", "with_tls_options.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "default/foo": { - MinVersion: "VersionTLS12", - CipherSuites: []string{ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - }, - ClientCA: tls.ClientCA{ - Files: []tls.FileOrContent{ - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "default/foo": { + MinVersion: "VersionTLS12", + CipherSuites: []string{ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", }, - Optional: true, + ClientCA: tls.ClientCA{ + Files: []tls.FileOrContent{ + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + }, + Optional: true, + }, + SniStrict: true, }, - SniStrict: true, }, }, TCP: &config.TCPConfiguration{ @@ -1024,21 +1059,23 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "TLS with tls options and specific namespace", paths: []string{"services.yml", "with_tls_options_and_specific_namespace.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "myns/foo": { - MinVersion: "VersionTLS12", - CipherSuites: []string{ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - }, - ClientCA: tls.ClientCA{ - Files: []tls.FileOrContent{ - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "myns/foo": { + MinVersion: "VersionTLS12", + CipherSuites: []string{ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", }, - Optional: true, + ClientCA: tls.ClientCA{ + Files: []tls.FileOrContent{ + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + }, + Optional: true, + }, + SniStrict: true, }, - SniStrict: true, }, }, TCP: &config.TCPConfiguration{ @@ -1080,20 +1117,22 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "TLS with bad tls options", paths: []string{"services.yml", "with_bad_tls_options.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "default/foo": { - MinVersion: "VersionTLS12", - CipherSuites: []string{ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - }, - ClientCA: tls.ClientCA{ - Files: []tls.FileOrContent{ - tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "default/foo": { + MinVersion: "VersionTLS12", + CipherSuites: []string{ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", }, - Optional: true, + ClientCA: tls.ClientCA{ + Files: []tls.FileOrContent{ + tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + }, + Optional: true, + }, + SniStrict: true, }, - SniStrict: true, }, }, TCP: &config.TCPConfiguration{ @@ -1135,9 +1174,11 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "TLS with unknown tls options", paths: []string{"services.yml", "with_unknown_tls_options.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "default/foo": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "default/foo": { + MinVersion: "VersionTLS12", + }, }, }, TCP: &config.TCPConfiguration{ @@ -1179,9 +1220,11 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "TLS with unknown tls options namespace", paths: []string{"services.yml", "with_unknown_tls_options_namespace.yml"}, expected: &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "default/foo": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "default/foo": { + MinVersion: "VersionTLS12", + }, }, }, TCP: &config.TCPConfiguration{ @@ -1223,6 +1266,7 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "TLS with ACME", paths: []string{"services.yml", "with_tls_acme.yml"}, expected: &config.Configuration{ + TLS: &config.TLSConfiguration{}, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, @@ -1260,6 +1304,7 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "Simple Ingress Route, defaulting to https for servers", paths: []string{"services.yml", "with_https_default.yml"}, expected: &config.Configuration{ + TLS: &config.TLSConfiguration{}, TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{}, Services: map[string]*config.TCPService{}, diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index b2a0095ba..7f4b24c08 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -257,7 +257,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl ingresses := client.GetIngresses() - tlsConfigs := make(map[string]*tls.Configuration) + tlsConfigs := make(map[string]*tls.CertAndStores) for _, ingress := range ingresses { ctx = log.With(ctx, log.Str("ingress", ingress.Name), log.Str("namespace", ingress.Namespace)) @@ -341,7 +341,13 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl } } - conf.TLS = getTLSConfig(tlsConfigs) + certs := getTLSConfig(tlsConfigs) + if len(certs) > 0 { + conf.TLS = &config.TLSConfiguration{ + Certificates: certs, + } + } + return conf } @@ -350,7 +356,7 @@ func shouldProcessIngress(ingressClass string, ingressClassAnnotation string) bo (len(ingressClass) == 0 && ingressClassAnnotation == traefikDefaultIngressClass) } -func getTLS(ctx context.Context, ingress *v1beta1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.Configuration) error { +func getTLS(ctx context.Context, ingress *v1beta1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { for _, t := range ingress.Spec.TLS { if t.SecretName == "" { log.FromContext(ctx).Debugf("Skipping TLS sub-section: No secret name provided") @@ -372,8 +378,8 @@ func getTLS(ctx context.Context, ingress *v1beta1.Ingress, k8sClient Client, tls return err } - tlsConfigs[configKey] = &tls.Configuration{ - Certificate: &tls.Certificate{ + tlsConfigs[configKey] = &tls.CertAndStores{ + Certificate: tls.Certificate{ CertFile: tls.FileOrContent(cert), KeyFile: tls.FileOrContent(key), }, @@ -384,14 +390,14 @@ func getTLS(ctx context.Context, ingress *v1beta1.Ingress, k8sClient Client, tls return nil } -func getTLSConfig(tlsConfigs map[string]*tls.Configuration) []*tls.Configuration { +func getTLSConfig(tlsConfigs map[string]*tls.CertAndStores) []*tls.CertAndStores { var secretNames []string for secretName := range tlsConfigs { secretNames = append(secretNames, secretName) } sort.Strings(secretNames) - var configs []*tls.Configuration + var configs []*tls.CertAndStores for _, secretName := range secretNames { configs = append(configs, tlsConfigs[secretName]) } diff --git a/pkg/provider/kubernetes/ingress/kubernetes_test.go b/pkg/provider/kubernetes/ingress/kubernetes_test.go index 388ed7ce7..ffb0e273f 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress/kubernetes_test.go @@ -702,11 +702,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, }, }, - TLS: []*tls.Configuration{ - { - Certificate: &tls.Certificate{ - CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), - KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"), + TLS: &config.TLSConfiguration{ + Certificates: []*tls.CertAndStores{ + { + Certificate: tls.Certificate{ + CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"), + }, }, }, }, @@ -973,7 +975,7 @@ func TestGetTLS(t *testing.T) { desc string ingress *v1beta1.Ingress client Client - result map[string]*tls.Configuration + result map[string]*tls.CertAndStores errResult string }{ { @@ -1080,15 +1082,15 @@ func TestGetTLS(t *testing.T) { }, }, }, - result: map[string]*tls.Configuration{ + result: map[string]*tls.CertAndStores{ "testing/test-secret": { - Certificate: &tls.Certificate{ + Certificate: tls.Certificate{ CertFile: tls.FileOrContent("tls-crt"), KeyFile: tls.FileOrContent("tls-key"), }, }, "testing/test-secret2": { - Certificate: &tls.Certificate{ + Certificate: tls.Certificate{ CertFile: tls.FileOrContent("tls-crt"), KeyFile: tls.FileOrContent("tls-key"), }, @@ -1099,7 +1101,7 @@ func TestGetTLS(t *testing.T) { desc: "return nil when no secret is defined", ingress: testIngressWithoutSecret, client: clientMock{}, - result: map[string]*tls.Configuration{}, + result: map[string]*tls.CertAndStores{}, }, } @@ -1108,7 +1110,7 @@ func TestGetTLS(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - tlsConfigs := map[string]*tls.Configuration{} + tlsConfigs := map[string]*tls.CertAndStores{} err := getTLS(context.Background(), test.ingress, test.client, tlsConfigs) if test.errResult != "" { diff --git a/pkg/server/aggregator.go b/pkg/server/aggregator.go index 60db24001..5d2c25cc9 100644 --- a/pkg/server/aggregator.go +++ b/pkg/server/aggregator.go @@ -18,8 +18,10 @@ func mergeConfiguration(configurations config.Configurations) config.Configurati Routers: make(map[string]*config.TCPRouter), Services: make(map[string]*config.TCPService), }, - TLSOptions: make(map[string]tls.TLS), - TLSStores: make(map[string]tls.Store), + TLS: &config.TLSConfiguration{ + Stores: make(map[string]tls.Store), + Options: make(map[string]tls.Options), + }, } var defaultTLSOptionProviders []string @@ -44,30 +46,33 @@ func mergeConfiguration(configurations config.Configurations) config.Configurati conf.TCP.Services[internal.MakeQualifiedName(provider, serviceName)] = service } } - conf.TLS = append(conf.TLS, configuration.TLS...) - for key, store := range configuration.TLSStores { - conf.TLSStores[key] = store - } + if configuration.TLS != nil { + conf.TLS.Certificates = append(conf.TLS.Certificates, configuration.TLS.Certificates...) - for tlsOptionsName, config := range configuration.TLSOptions { - if tlsOptionsName != "default" { - tlsOptionsName = internal.MakeQualifiedName(provider, tlsOptionsName) - } else { - defaultTLSOptionProviders = append(defaultTLSOptionProviders, provider) + for key, store := range configuration.TLS.Stores { + conf.TLS.Stores[key] = store } - conf.TLSOptions[tlsOptionsName] = config + for tlsOptionsName, options := range configuration.TLS.Options { + if tlsOptionsName != "default" { + tlsOptionsName = internal.MakeQualifiedName(provider, tlsOptionsName) + } else { + defaultTLSOptionProviders = append(defaultTLSOptionProviders, provider) + } + + conf.TLS.Options[tlsOptionsName] = options + } } } if len(defaultTLSOptionProviders) == 0 { - conf.TLSOptions["default"] = tls.TLS{} + conf.TLS.Options["default"] = tls.Options{} } else if len(defaultTLSOptionProviders) > 1 { log.WithoutContext().Errorf("Default TLS Options defined multiple times in %v", defaultTLSOptionProviders) // We do not set an empty tls.TLS{} as above so that we actually get a "cascading failure" later on, // i.e. routers depending on this missing TLS option will fail to initialize as well. - delete(conf.TLSOptions, "default") + delete(conf.TLS.Options, "default") } return conf diff --git a/pkg/server/aggregator_test.go b/pkg/server/aggregator_test.go index 6267b819a..92733f3e0 100644 --- a/pkg/server/aggregator_test.go +++ b/pkg/server/aggregator_test.go @@ -114,12 +114,12 @@ func TestAggregator_tlsoptions(t *testing.T) { testCases := []struct { desc string given config.Configurations - expected map[string]tls.TLS + expected map[string]tls.Options }{ { desc: "Nil returns an empty configuration", given: nil, - expected: map[string]tls.TLS{ + expected: map[string]tls.Options{ "default": {}, }, }, @@ -127,14 +127,16 @@ func TestAggregator_tlsoptions(t *testing.T) { desc: "Returns fully qualified elements from a mono-provider configuration map", given: config.Configurations{ "provider-1": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS12", + }, }, }, }, }, - expected: map[string]tls.TLS{ + expected: map[string]tls.Options{ "default": {}, "foo@provider-1": { MinVersion: "VersionTLS12", @@ -145,21 +147,25 @@ func TestAggregator_tlsoptions(t *testing.T) { desc: "Returns fully qualified elements from a multi-provider configuration map", given: config.Configurations{ "provider-1": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS13", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS13", + }, }, }, }, "provider-2": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS12", + }, }, }, }, }, - expected: map[string]tls.TLS{ + expected: map[string]tls.Options{ "default": {}, "foo@provider-1": { MinVersion: "VersionTLS13", @@ -173,24 +179,28 @@ func TestAggregator_tlsoptions(t *testing.T) { desc: "Create a valid default tls option when appears only in one provider", given: config.Configurations{ "provider-1": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS13", - }, - "default": { - MinVersion: "VersionTLS11", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS13", + }, + "default": { + MinVersion: "VersionTLS11", + }, }, }, }, "provider-2": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS12", + }, }, }, }, }, - expected: map[string]tls.TLS{ + expected: map[string]tls.Options{ "default": { MinVersion: "VersionTLS11", }, @@ -206,27 +216,31 @@ func TestAggregator_tlsoptions(t *testing.T) { desc: "No default tls option if it is defined in multiple providers", given: config.Configurations{ "provider-1": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS12", - }, - "default": { - MinVersion: "VersionTLS11", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS12", + }, + "default": { + MinVersion: "VersionTLS11", + }, }, }, }, "provider-2": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS13", - }, - "default": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS13", + }, + "default": { + MinVersion: "VersionTLS12", + }, }, }, }, }, - expected: map[string]tls.TLS{ + expected: map[string]tls.Options{ "foo@provider-1": { MinVersion: "VersionTLS12", }, @@ -239,21 +253,25 @@ func TestAggregator_tlsoptions(t *testing.T) { desc: "Create a default TLS Options configuration if none was provided", given: config.Configurations{ "provider-1": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS12", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS12", + }, }, }, }, "provider-2": &config.Configuration{ - TLSOptions: map[string]tls.TLS{ - "foo": { - MinVersion: "VersionTLS13", + TLS: &config.TLSConfiguration{ + Options: map[string]tls.Options{ + "foo": { + MinVersion: "VersionTLS13", + }, }, }, }, }, - expected: map[string]tls.TLS{ + expected: map[string]tls.Options{ "default": {}, "foo@provider-1": { MinVersion: "VersionTLS12", @@ -272,7 +290,7 @@ func TestAggregator_tlsoptions(t *testing.T) { t.Parallel() actual := mergeConfiguration(test.given) - assert.Equal(t, test.expected, actual.TLSOptions) + assert.Equal(t, test.expected, actual.TLS.Options) }) } } diff --git a/pkg/server/router/tcp/router_test.go b/pkg/server/router/tcp/router_test.go index 1050e7938..e65e549e2 100644 --- a/pkg/server/router/tcp/router_test.go +++ b/pkg/server/router/tcp/router_test.go @@ -203,7 +203,7 @@ func TestRuntimeConfiguration(t *testing.T) { tlsManager := tls.NewManager() tlsManager.UpdateConfigs( map[string]tls.Store{}, - map[string]tls.TLS{ + map[string]tls.Options{ "default": { MinVersion: "VersionTLS10", }, @@ -214,7 +214,7 @@ func TestRuntimeConfiguration(t *testing.T) { MinVersion: "VersionTLS11", }, }, - []*tls.Configuration{}) + []*tls.CertAndStores{}) routerManager := NewManager(conf, serviceManager, nil, nil, tlsManager) diff --git a/pkg/server/server_configuration.go b/pkg/server/server_configuration.go index de9f2bb4c..dd397f82b 100644 --- a/pkg/server/server_configuration.go +++ b/pkg/server/server_configuration.go @@ -66,7 +66,7 @@ func (s *Server) loadConfigurationTCP(configurations config.Configurations) map[ conf := mergeConfiguration(configurations) - s.tlsManager.UpdateConfigs(conf.TLSStores, conf.TLSOptions, conf.TLS) + s.tlsManager.UpdateConfigs(conf.TLS.Stores, conf.TLS.Options, conf.TLS.Certificates) rtConf := config.NewRuntimeConfig(conf) handlersNonTLS, handlersTLS := s.createHTTPHandlers(ctx, rtConf, entryPoints) @@ -167,7 +167,7 @@ func isEmptyConfiguration(conf *config.Configuration) bool { return conf.HTTP.Routers == nil && conf.HTTP.Services == nil && conf.HTTP.Middlewares == nil && - conf.TLS == nil && + (conf.TLS == nil || conf.TLS.Certificates == nil && conf.TLS.Stores == nil && conf.TLS.Options == nil) && conf.TCP.Routers == nil && conf.TCP.Services == nil } diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index c2d09a5bb..e509e4b10 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -9,8 +9,8 @@ type ClientCA struct { Optional bool } -// TLS configures TLS for an entry point -type TLS struct { +// Options configures TLS for an entry point +type Options struct { MinVersion string `export:"true"` CipherSuites []string ClientCA ClientCA @@ -22,8 +22,8 @@ type Store struct { DefaultCertificate *Certificate } -// Configuration allows mapping a TLS certificate to a list of entry points. -type Configuration struct { +// CertAndStores allows mapping a TLS certificate to a list of entry points. +type CertAndStores struct { + Certificate `yaml:",inline"` Stores []string - Certificate *Certificate } diff --git a/pkg/tls/tlsmanager.go b/pkg/tls/tlsmanager.go index 60791ace0..c1599b7d8 100644 --- a/pkg/tls/tlsmanager.go +++ b/pkg/tls/tlsmanager.go @@ -17,8 +17,8 @@ import ( type Manager struct { storesConfig map[string]Store stores map[string]*CertificateStore - configs map[string]TLS - certs []*Configuration + configs map[string]Options + certs []*CertAndStores TLSAlpnGetter func(string) (*tls.Certificate, error) lock sync.RWMutex } @@ -29,7 +29,7 @@ func NewManager() *Manager { } // UpdateConfigs updates the TLS* configuration options -func (m *Manager) UpdateConfigs(stores map[string]Store, configs map[string]TLS, certs []*Configuration) { +func (m *Manager) UpdateConfigs(stores map[string]Store, configs map[string]Options, certs []*CertAndStores) { m.lock.Lock() defer m.lock.Unlock() @@ -153,7 +153,7 @@ func buildCertificateStore(tlsStore Store) (*CertificateStore, error) { } // creates a TLS config that allows terminating HTTPS for multiple domains using SNI -func buildTLSConfig(tlsOption TLS) (*tls.Config, error) { +func buildTLSConfig(tlsOption Options) (*tls.Config, error) { conf := &tls.Config{} // ensure http2 enabled diff --git a/pkg/tls/tlsmanager_test.go b/pkg/tls/tlsmanager_test.go index 848d55389..963f548ee 100644 --- a/pkg/tls/tlsmanager_test.go +++ b/pkg/tls/tlsmanager_test.go @@ -46,15 +46,12 @@ f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA== ) func TestTLSInStore(t *testing.T) { - dynamicConfigs := - []*Configuration{ - { - Certificate: &Certificate{ - CertFile: localhostCert, - KeyFile: localhostKey, - }, - }, - } + dynamicConfigs := []*CertAndStores{{ + Certificate: Certificate{ + CertFile: localhostCert, + KeyFile: localhostKey, + }, + }} tlsManager := NewManager() tlsManager.UpdateConfigs(nil, nil, dynamicConfigs) @@ -66,15 +63,12 @@ func TestTLSInStore(t *testing.T) { } func TestTLSInvalidStore(t *testing.T) { - dynamicConfigs := - []*Configuration{ - { - Certificate: &Certificate{ - CertFile: localhostCert, - KeyFile: localhostKey, - }, - }, - } + dynamicConfigs := []*CertAndStores{{ + Certificate: Certificate{ + CertFile: localhostCert, + KeyFile: localhostKey, + }, + }} tlsManager := NewManager() tlsManager.UpdateConfigs(map[string]Store{ @@ -93,16 +87,14 @@ func TestTLSInvalidStore(t *testing.T) { } func TestManager_Get(t *testing.T) { - dynamicConfigs := - []*Configuration{ - { - Certificate: &Certificate{ - CertFile: localhostCert, - KeyFile: localhostKey, - }, - }, - } - tlsConfigs := map[string]TLS{ + dynamicConfigs := []*CertAndStores{{ + Certificate: Certificate{ + CertFile: localhostCert, + KeyFile: localhostKey, + }, + }} + + tlsConfigs := map[string]Options{ "foo": {MinVersion: "VersionTLS12"}, "bar": {MinVersion: "VersionTLS11"}, } @@ -153,5 +145,4 @@ func TestManager_Get(t *testing.T) { assert.Equal(t, config.MinVersion, test.expectedMinVersion) }) } - } From 84d7c6503906724cf321f6c1cf2dec58209cd7c6 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 28 Jun 2019 00:16:04 +0200 Subject: [PATCH 06/11] Improve tracing --- docs/content/observability/tracing.md | 234 ------------------ docs/content/observability/tracing/datadog.md | 82 ++++++ .../content/observability/tracing/haystack.md | 132 ++++++++++ docs/content/observability/tracing/instana.md | 71 ++++++ docs/content/observability/tracing/jaeger.md | 146 +++++++++++ .../content/observability/tracing/overview.md | 67 +++++ docs/content/observability/tracing/zipkin.md | 98 ++++++++ .../reference/static-configuration/cli.txt | 5 +- .../reference/static-configuration/env.md | 3 - .../reference/static-configuration/file.toml | 9 +- docs/mkdocs.yml | 8 +- .../{simple.toml => simple-jaeger.toml} | 12 +- .../fixtures/tracing/simple-zipkin.toml | 71 ++++++ integration/resources/compose/tracing.yml | 2 +- integration/tracing_test.go | 169 ++++++++++--- pkg/anonymize/anonymize_config_test.go | 11 +- pkg/config/file/file_node_test.go | 16 +- pkg/config/file/fixtures/sample.toml | 9 +- pkg/config/file/fixtures/sample.yml | 8 +- pkg/config/static/static_config.go | 100 -------- pkg/server/server.go | 72 ++++-- pkg/tracing/haystack/haystack.go | 2 +- pkg/tracing/tracing.go | 8 +- 23 files changed, 924 insertions(+), 411 deletions(-) delete mode 100644 docs/content/observability/tracing.md create mode 100644 docs/content/observability/tracing/datadog.md create mode 100644 docs/content/observability/tracing/haystack.md create mode 100644 docs/content/observability/tracing/instana.md create mode 100644 docs/content/observability/tracing/jaeger.md create mode 100644 docs/content/observability/tracing/overview.md create mode 100644 docs/content/observability/tracing/zipkin.md rename integration/fixtures/tracing/{simple.toml => simple-jaeger.toml} (89%) create mode 100644 integration/fixtures/tracing/simple-zipkin.toml diff --git a/docs/content/observability/tracing.md b/docs/content/observability/tracing.md deleted file mode 100644 index a53d8ccc2..000000000 --- a/docs/content/observability/tracing.md +++ /dev/null @@ -1,234 +0,0 @@ -# Tracing - -Visualize the Requests Flow -{: .subtitle } - -The tracing system allows developers to visualize call flows in their infrastructure. - -Traefik uses OpenTracing, an open standard designed for distributed tracing. - -Traefik supports four tracing backends: Jaeger, Zipkin, DataDog, and Instana. - -## Configuration Reference - -??? example "With Jaeger" - - ```toml - # Tracing definition - [tracing] - # Backend name used to send tracing data - # - # Default: "jaeger" - # - backend = "jaeger" - - # Service name used in Jaeger backend - # - # Default: "traefik" - # - serviceName = "traefik" - - # Span name limit allows for name truncation in case of very long Frontend/Backend names - # This can prevent certain tracing providers to drop traces that exceed their length limits - # - # Default: 0 - no truncation will occur - # - spanNameLimit = 0 - - [tracing.jaeger] - # Sampling Server URL is the address of jaeger-agent's HTTP sampling server - # - # Default: "http://localhost:5778/sampling" - # - samplingServerURL = "http://localhost:5778/sampling" - - # Sampling Type specifies the type of the sampler: const, probabilistic, rateLimiting - # - # Default: "const" - # - samplingType = "const" - - # Sampling Param is a value passed to the sampler. - # Valid values for Param field are: - # - for "const" sampler, 0 or 1 for always false/true respectively - # - for "probabilistic" sampler, a probability between 0 and 1 - # - for "rateLimiting" sampler, the number of spans per second - # - # Default: 1.0 - # - samplingParam = 1.0 - - # Local Agent Host Port instructs reporter to send spans to jaeger-agent at this address - # - # Default: "127.0.0.1:6831" - # - localAgentHostPort = "127.0.0.1:6831" - - # Generate 128-bit trace IDs, compatible with OpenCensus - # - # Default: false - gen128Bit = true - - # Set the propagation header type. This can be either: - # - "jaeger", jaeger's default trace header. - # - "b3", compatible with OpenZipkin - # - # Default: "jaeger" - propagation = "jaeger" - - # Trace Context Header Name is the http header name used to propagate tracing context. - # This must be in lower-case to avoid mismatches when decoding incoming headers. - # - # Default: "uber-trace-id" - # - traceContextHeaderName = "uber-trace-id" - ``` - - !!! warning - Traefik is only able to send data over the compact thrift protocol to the [Jaeger agent](https://www.jaegertracing.io/docs/deployment/#agent). - -??? example "With Zipkin" - - ```toml - # Tracing definition - [tracing] - # Backend name used to send tracing data - # - # Default: "jaeger" - # - backend = "zipkin" - - # Service name used in Zipkin backend - # - # Default: "traefik" - # - serviceName = "traefik" - - # Span name limit allows for name truncation in case of very long Frontend/Backend names - # This can prevent certain tracing providers to drop traces that exceed their length limits - # - # Default: 0 - no truncation will occur - # - spanNameLimit = 150 - - [tracing.zipkin] - # Zipkin HTTP endpoint used to send data - # - # Default: "http://localhost:9411/api/v1/spans" - # - httpEndpoint = "http://localhost:9411/api/v1/spans" - - # Enable Zipkin debug - # - # Default: false - # - debug = false - - # Use Zipkin SameSpan RPC style traces - # - # Default: false - # - sameSpan = false - - # Use Zipkin 128 bit root span IDs - # - # Default: true - # - id128Bit = true - - # The rate between 0.0 and 1.0 of requests to trace. - # - # Default: 1.0 - # - sampleRate = 0.2 - ``` - -??? example "With DataDog" - - ```toml - # Tracing definition - [tracing] - # Backend name used to send tracing data - # - # Default: "jaeger" - # - backend = "datadog" - - # Service name used in DataDog backend - # - # Default: "traefik" - # - serviceName = "traefik" - - # Span name limit allows for name truncation in case of very long Frontend/Backend names - # This can prevent certain tracing providers to drop traces that exceed their length limits - # - # Default: 0 - no truncation will occur - # - spanNameLimit = 100 - - [tracing.datadog] - # Local Agent Host Port instructs reporter to send spans to datadog-tracing-agent at this address - # - # Default: "127.0.0.1:8126" - # - localAgentHostPort = "127.0.0.1:8126" - - # Enable DataDog debug - # - # Default: false - # - debug = false - - # Apply shared tag in a form of Key:Value to all the traces - # - # Default: "" - # - globalTag = "" - - # Enable priority sampling. When using distributed tracing, this option must be enabled in order - # to get all the parts of a distributed trace sampled. - # - # Default: false - # - prioritySampling = false - - ``` - -??? example "With Instana" - - ```toml - # Tracing definition - [tracing] - # Backend name used to send tracing data - # - # Default: "jaeger" - # - backend = "instana" - # Service name used in Instana backend - # - # Default: "traefik" - # - serviceName = "traefik" - [tracing.instana] - # Local Agent Host instructs reporter to send spans to instana-agent at this address - # - # Default: "127.0.0.1" - # - localAgentHost = "127.0.0.1" - # Local Agent port instructs reporter to send spans to the instana-agent at this port - # - # Default: 42699 - # - localAgentPort = 42699 - # Set Instana tracer log level - # - # Default: info - # Valid values for logLevel field are: - # - error - # - warn - # - debug - # - info - # - logLevel = "info" - ``` diff --git a/docs/content/observability/tracing/datadog.md b/docs/content/observability/tracing/datadog.md new file mode 100644 index 000000000..c32888391 --- /dev/null +++ b/docs/content/observability/tracing/datadog.md @@ -0,0 +1,82 @@ +# DataDog + +To enable the DataDog: + +```toml tab="File" +[tracing] + [tracing.datadog] +``` + +```bash tab="CLI" +--tracing +--tracing.datadog +``` + +#### `localAgentHostPort` + +_Required, Default="127.0.0.1:8126"_ + +Local Agent Host Port instructs reporter to send spans to datadog-tracing-agent at this address. + +```toml tab="File" +[tracing] + [tracing.datadog] + localAgentHostPort = "127.0.0.1:8126" +``` + +```bash tab="CLI" +--tracing +--tracing.datadog.localAgentHostPort="127.0.0.1:8126" +``` + +#### `debug` + +_Optional, Default=false_ + +Enable DataDog debug. + +```toml tab="File" +[tracing] + [tracing.datadog] + debug = true +``` + +```bash tab="CLI" +--tracing +--tracing.datadog.debug=true +``` + +#### `globalTag` + +_Optional, Default=empty_ + +Apply shared tag in a form of Key:Value to all the traces. + +```toml tab="File" +[tracing] + [tracing.datadog] + globalTag = "sample" +``` + +```bash tab="CLI" +--tracing +--tracing.datadog.globalTag="sample" +``` + +#### `prioritySampling` + +_Optional, Default=false_ + +Enable priority sampling. When using distributed tracing, +this option must be enabled in order to get all the parts of a distributed trace sampled. + +```toml tab="File" +[tracing] + [tracing.datadog] + prioritySampling = true +``` + +```bash tab="CLI" +--tracing +--tracing.datadog.prioritySampling=true +``` diff --git a/docs/content/observability/tracing/haystack.md b/docs/content/observability/tracing/haystack.md new file mode 100644 index 000000000..6b6b1ac0d --- /dev/null +++ b/docs/content/observability/tracing/haystack.md @@ -0,0 +1,132 @@ +# Haystack + +To enable the Haystack: + +```toml tab="File" +[tracing] + [tracing.haystack] +``` + +```bash tab="CLI" +--tracing +--tracing.haystack +``` + +#### `localAgentHost` + +_Require, Default="127.0.0.1"_ + +Local Agent Host instructs reporter to send spans to haystack-agent at this address. + +```toml tab="File" +[tracing] + [tracing.haystack] + localAgentHost = "127.0.0.1" +``` + +```bash tab="CLI" +--tracing +--tracing.haystack.localAgentHost="127.0.0.1" +``` + +#### `localAgentPort` + +_Require, Default=42699_ + +Local Agent port instructs reporter to send spans to the haystack-agent at this port. + +```toml tab="File" +[tracing] + [tracing.haystack] + localAgentPort = 42699 +``` + +```bash tab="CLI" +--tracing +--tracing.haystack.localAgentPort=42699 +``` + +#### `globalTag` + +_Optional, Default=empty_ + +Apply shared tag in a form of Key:Value to all the traces. + +```toml tab="File" +[tracing] + [tracing.haystack] + globalTag = "sample:test" +``` + +```bash tab="CLI" +--tracing +--tracing.haystack.globalTag="sample:test" +``` + +#### `traceIDHeaderName` + +_Optional, Default=empty_ + +Specifies the header name that will be used to store the trace ID. + +```toml tab="File" +[tracing] + [tracing.haystack] + traceIDHeaderName = "sample" +``` + +```bash tab="CLI" +--tracing +--tracing.haystack.traceIDHeaderName="sample" +``` + +#### `parentIDHeaderName` + +_Optional, Default=empty_ + +Specifies the header name that will be used to store the span ID. + +```toml tab="File" +[tracing] + [tracing.haystack] + parentIDHeaderName = "sample" +``` + +```bash tab="CLI" +--tracing +--tracing.haystack.parentIDHeaderName="sample" +``` + +#### `spanIDHeaderName` + +_Optional, Default=empty_ + +Apply shared tag in a form of Key:Value to all the traces. + +```toml tab="File" +[tracing] + [tracing.haystack] + spanIDHeaderName = "sample:test" +``` + +```bash tab="CLI" +--tracing +--tracing.haystack.spanIDHeaderName="sample:test" +``` + +#### `baggagePrefixHeaderName` + +_Optional, Default=empty_ + +Specifies the header name prefix that will be used to store baggage items in a map. + +```toml tab="File" +[tracing] + [tracing.haystack] + baggagePrefixHeaderName = "sample" +``` + +```bash tab="CLI" +--tracing +--tracing.haystack.baggagePrefixHeaderName="sample" +``` diff --git a/docs/content/observability/tracing/instana.md b/docs/content/observability/tracing/instana.md new file mode 100644 index 000000000..66c09f744 --- /dev/null +++ b/docs/content/observability/tracing/instana.md @@ -0,0 +1,71 @@ +# Instana + +To enable the Instana: + +```toml tab="File" +[tracing] + [tracing.instana] +``` + +```bash tab="CLI" +--tracing +--tracing.instana +``` + +#### `localAgentHost` + +_Require, Default="127.0.0.1"_ + +Local Agent Host instructs reporter to send spans to instana-agent at this address. + +```toml tab="File" +[tracing] + [tracing.instana] + localAgentHost = "127.0.0.1" +``` + +```bash tab="CLI" +--tracing +--tracing.instana.localAgentHost="127.0.0.1" +``` + +#### `localAgentPort` + +_Require, Default=42699_ + +Local Agent port instructs reporter to send spans to the instana-agent at this port. + +```toml tab="File" +[tracing] + [tracing.instana] + localAgentPort = 42699 +``` + +```bash tab="CLI" +--tracing +--tracing.instana.localAgentPort=42699 +``` + +#### `logLevel` + +_Require, Default="info"_ + +Set Instana tracer log level. + +Valid values for logLevel field are: + +- `error` +- `warn` +- `debug` +- `info` + +```toml tab="File" +[tracing] + [tracing.instana] + logLevel = "info" +``` + +```bash tab="CLI" +--tracing +--tracing.instana.logLevel="info" +``` diff --git a/docs/content/observability/tracing/jaeger.md b/docs/content/observability/tracing/jaeger.md new file mode 100644 index 000000000..458d7ecd8 --- /dev/null +++ b/docs/content/observability/tracing/jaeger.md @@ -0,0 +1,146 @@ +# Jaeger + +To enable the Jaeger: + +```toml tab="File" +[tracing] + [tracing.jaeger] +``` + +```bash tab="CLI" +--tracing +--tracing.jaeger +``` + +!!! warning + Traefik is only able to send data over the compact thrift protocol to the [Jaeger agent](https://www.jaegertracing.io/docs/deployment/#agent). + +#### `samplingServerURL` + +_Required, Default="http://localhost:5778/sampling"_ + +Sampling Server URL is the address of jaeger-agent's HTTP sampling server. + +```toml tab="File" +[tracing] + [tracing.jaeger] + samplingServerURL = "http://localhost:5778/sampling" +``` + +```bash tab="CLI" +--tracing +--tracing.jaeger.samplingServerURL="http://localhost:5778/sampling" +``` + +#### `samplingType` + +_Required, Default="const"_ + +Sampling Type specifies the type of the sampler: `const`, `probabilistic`, `rateLimiting`. + +```toml tab="File" +[tracing] + [tracing.jaeger] + samplingType = "const" +``` + +```bash tab="CLI" +--tracing +--tracing.jaeger.samplingType="const" +``` + +#### `samplingParam` + +_Required, Default=1.0_ + +Sampling Param is a value passed to the sampler. + +Valid values for Param field are: + +- for `const` sampler, 0 or 1 for always false/true respectively +- for `probabilistic` sampler, a probability between 0 and 1 +- for `rateLimiting` sampler, the number of spans per second + +```toml tab="File" +[tracing] + [tracing.jaeger] + samplingParam = 1.0 +``` + +```bash tab="CLI" +--tracing +--tracing.jaeger.samplingParam="1.0" +``` + +#### `localAgentHostPort` + +_Required, Default="127.0.0.1:6831"_ + +Local Agent Host Port instructs reporter to send spans to jaeger-agent at this address. + +```toml tab="File" +[tracing] + [tracing.jaeger] + localAgentHostPort = "127.0.0.1:6831" +``` + +```bash tab="CLI" +--tracing +--tracing.jaeger.localAgentHostPort="127.0.0.1:6831" +``` + +#### `gen128Bit` + +_Optional, Default=false_ + +Generate 128-bit trace IDs, compatible with OpenCensus. + +```toml tab="File" +[tracing] + [tracing.jaeger] + gen128Bit = true +``` + +```bash tab="CLI" +--tracing +--tracing.jaeger.gen128Bit +``` + +#### `propagation` + +_Required, Default="jaeger"_ + +Set the propagation header type. +This can be either: + +- `jaeger`, jaeger's default trace header. +- `b3`, compatible with OpenZipkin + +```toml tab="File" +[tracing] + [tracing.jaeger] + propagation = "jaeger" +``` + +```bash tab="CLI" +--tracing +--tracing.jaeger.propagation="jaeger" +``` + +#### `traceContextHeaderName` + +_Required, Default="uber-trace-id"_ + +Trace Context Header Name is the http header name used to propagate tracing context. +This must be in lower-case to avoid mismatches when decoding incoming headers. + +```toml tab="File" +[tracing] + [tracing.jaeger] + traceContextHeaderName = "uber-trace-id" +``` + +```bash tab="CLI" +--tracing +--tracing.jaeger.traceContextHeaderName="uber-trace-id" +``` diff --git a/docs/content/observability/tracing/overview.md b/docs/content/observability/tracing/overview.md new file mode 100644 index 000000000..2de86bd07 --- /dev/null +++ b/docs/content/observability/tracing/overview.md @@ -0,0 +1,67 @@ +# Tracing + +Visualize the Requests Flow +{: .subtitle } + +The tracing system allows developers to visualize call flows in their infrastructure. + +Traefik uses OpenTracing, an open standard designed for distributed tracing. + +Traefik supports five tracing backends: + +- [Jaeger](./jaeger.md) +- [Zipkin](./zipkin.md) +- [DataDog](./datadog.md) +- [Instana](./instana.md) +- [Haystack](./haystack.md) + +## Configuration + +By default, Traefik uses Jaeger as tracing backend. + +To enable the tracing: + +```toml tab="File" +[tracing] +``` + +```bash tab="CLI" +--tracing +``` + +### Common Options + +#### `serviceName` + +_Required, Default="traefik"_ + +Service name used in selected backend. + +```toml tab="File" +[tracing] + serviceName = "traefik" +``` + +```bash tab="CLI" +--tracing +--tracing.serviceName="traefik" +``` + +#### `spanNameLimit` + +_Required, Default=0_ + +Span name limit allows for name truncation in case of very long names. +This can prevent certain tracing providers to drop traces that exceed their length limits. + +`0` means no truncation will occur. + +```toml tab="File" +[tracing] + spanNameLimit = 150 +``` + +```bash tab="CLI" +--tracing +--tracing.spanNameLimit=150 +``` diff --git a/docs/content/observability/tracing/zipkin.md b/docs/content/observability/tracing/zipkin.md new file mode 100644 index 000000000..14954468d --- /dev/null +++ b/docs/content/observability/tracing/zipkin.md @@ -0,0 +1,98 @@ +# Zipkin + +To enable the Zipkin: + +```toml tab="File" +[tracing] + [tracing.zipkin] +``` + +```bash tab="CLI" +--tracing +--tracing.zipkin +``` + +#### `httpEndpoint` + +_Required, Default="http://localhost:9411/api/v1/spans"_ + +Zipkin HTTP endpoint used to send data. + +```toml tab="File" +[tracing] + [tracing.zipkin] + httpEndpoint = "http://localhost:9411/api/v1/spans" +``` + +```bash tab="CLI" +--tracing +--tracing.zipkin.httpEndpoint="http://localhost:9411/api/v1/spans" +``` + +#### `debug` + +_Optional, Default=false_ + +Enable Zipkin debug. + +```toml tab="File" +[tracing] + [tracing.zipkin] + debug = true +``` + +```bash tab="CLI" +--tracing +--tracing.zipkin.debug=true +``` + +#### `sameSpan` + +_Optional, Default=false_ + +Use Zipkin SameSpan RPC style traces. + +```toml tab="File" +[tracing] + [tracing.zipkin] + sameSpan = true +``` + +```bash tab="CLI" +--tracing +--tracing.zipkin.sameSpan=true +``` + +#### `id128Bit` + +_Optional, Default=true_ + +Use Zipkin 128 bit root span IDs. + +```toml tab="File" +[tracing] + [tracing.zipkin] + id128Bit = false +``` + +```bash tab="CLI" +--tracing +--tracing.zipkin.id128Bit=false +``` + +#### `sampleRate` + +_Required, Default=1.0_ + +The rate between 0.0 and 1.0 of requests to trace. + +```toml tab="File" +[tracing] + [tracing.zipkin] + sampleRate = 0.2 +``` + +```bash tab="CLI" +--tracing +--tracing.zipkin.sampleRate="0.2" +``` \ No newline at end of file diff --git a/docs/content/reference/static-configuration/cli.txt b/docs/content/reference/static-configuration/cli.txt index de489cb28..b4c087f1f 100644 --- a/docs/content/reference/static-configuration/cli.txt +++ b/docs/content/reference/static-configuration/cli.txt @@ -490,9 +490,6 @@ --tracing (Default: "false") OpenTracing configuration. ---tracing.backend (Default: "jaeger") - Selects the tracking backend ('jaeger','zipkin','datadog','instana'). - --tracing.datadog (Default: "false") Settings for DataDog. @@ -526,7 +523,7 @@ Settings for Haystack. --tracing.haystack.baggageprefixheadername (Default: "") - specifies the header name prefix that will be used to store baggage items in a + Specifies the header name prefix that will be used to store baggage items in a map. --tracing.haystack.globaltag (Default: "") diff --git a/docs/content/reference/static-configuration/env.md b/docs/content/reference/static-configuration/env.md index b9f3c67da..3e092aa04 100644 --- a/docs/content/reference/static-configuration/env.md +++ b/docs/content/reference/static-configuration/env.md @@ -474,9 +474,6 @@ Add cert file for self-signed certificate. `TRAEFIK_TRACING`: OpenTracing configuration. (Default: ```false```) -`TRAEFIK_TRACING_BACKEND`: -Selects the tracking backend ('jaeger','zipkin','datadog','instana'). (Default: ```jaeger```) - `TRAEFIK_TRACING_DATADOG`: Settings for DataDog. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index b0ec36369..d87c889c6 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -177,7 +177,6 @@ name1 = "foobar" [Tracing] - Backend = "foobar" ServiceName = "foobar" SpanNameLimit = 42 @@ -212,6 +211,14 @@ LocalAgentPort = 42 LogLevel = "foobar" + [Tracing.Haystack] + LocalAgentHost = "foobar" + LocalAgentPort = 42 + GlobalTag = "foobar" + ParentIDHeaderName = "foobar" + SpanIDHeaderName = "foobar" + TraceIDHeaderName = "foobar" + [HostResolver] CnameFlattening = true ResolvConfig = "foobar" diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 6dfbe7488..7234bfa92 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -119,7 +119,13 @@ nav: - 'Observability': - 'Logs': 'observability/logs.md' - 'Access Logs': 'observability/access-logs.md' - - 'Tracing': 'observability/tracing.md' + - 'Tracing': + - 'Overview': 'observability/tracing/overview.md' + - 'Jaeger': 'observability/tracing/jaeger.md' + - 'Zipkin': 'observability/tracing/zipkin.md' + - 'DataDog': 'observability/tracing/datadog.md' + - 'Instana': 'observability/tracing/instana.md' + - 'Haystack': 'observability/tracing/haystack.md' - 'User Guides': - 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md' - 'Marathon': 'user-guides/marathon.md' diff --git a/integration/fixtures/tracing/simple.toml b/integration/fixtures/tracing/simple-jaeger.toml similarity index 89% rename from integration/fixtures/tracing/simple.toml rename to integration/fixtures/tracing/simple-jaeger.toml index 40428ddef..1a830f661 100644 --- a/integration/fixtures/tracing/simple.toml +++ b/integration/fixtures/tracing/simple-jaeger.toml @@ -12,14 +12,12 @@ level = "DEBUG" address = ":8000" [tracing] - backend = "{{.TracingBackend}}" servicename = "tracing" - [tracing.zipkin] - httpEndpoint = "http://{{.ZipkinIP}}:9411/api/v1/spans" - debug = true - [tracing.jaeger] - samplingType = "const" - samplingParam = 1.0 + [tracing.jaeger] + samplingType = "const" + samplingParam = 1.0 + samplingServerURL = "http://{{.IP}}:5778/sampling" + localAgentHostPort = "{{.IP}}:6831" [providers] [providers.file] diff --git a/integration/fixtures/tracing/simple-zipkin.toml b/integration/fixtures/tracing/simple-zipkin.toml new file mode 100644 index 000000000..e557fc122 --- /dev/null +++ b/integration/fixtures/tracing/simple-zipkin.toml @@ -0,0 +1,71 @@ +[global] +checkNewVersion = false +sendAnonymousUsage = false + +[log] +level = "DEBUG" + +[api] + +[entryPoints] + [entryPoints.web] + address = ":8000" + +[tracing] + servicename = "tracing" + [tracing.zipkin] + httpEndpoint = "http://{{.IP}}:9411/api/v1/spans" + debug = true + +[providers] + [providers.file] + +[http.routers] + [http.routers.router1] + Service = "service1" + Middlewares = ["retry", "ratelimit"] + Rule = "Path(`/ratelimit`)" + [http.routers.router2] + Service = "service2" + Middlewares = ["retry"] + Rule = "Path(`/retry`)" + [http.routers.router3] + Service = "service3" + Middlewares = ["retry", "basic-auth"] + Rule = "Path(`/auth`)" + +[http.middlewares] + [http.middlewares.retry.retry] + attempts = 3 + [http.middlewares.basic-auth.BasicAuth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] + [http.middlewares.ratelimit.RateLimit] + extractorfunc = "client.ip" + [http.middlewares.ratelimit.RateLimit.rateset.rateset1] + period = "60s" + average = 4 + burst = 5 + [http.middlewares.ratelimit.RateLimit.rateset.rateset2] + period = "3s" + average = 1 + burst = 2 + + +[http.services] + [http.services.service1] + [http.services.service1.LoadBalancer] + passHostHeader = true + [[http.services.service1.LoadBalancer.Servers]] + URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" + + [http.services.service2] + passHostHeader = true + [http.services.service2.LoadBalancer] + [[http.services.service2.LoadBalancer.Servers]] + URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" + + [http.services.service3] + passHostHeader = true + [http.services.service3.LoadBalancer] + [[http.services.service3.LoadBalancer.Servers]] + URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" diff --git a/integration/resources/compose/tracing.yml b/integration/resources/compose/tracing.yml index 05bfd4488..51f3eb8f0 100644 --- a/integration/resources/compose/tracing.yml +++ b/integration/resources/compose/tracing.yml @@ -6,7 +6,7 @@ zipkin: ports: - 9411:9411 jaeger: - image: jaegertracing/all-in-one:latest + image: jaegertracing/all-in-one:1.12 environment: COLLECTOR_ZIPKIN_HTTP_PORT: 9411 ports: diff --git a/integration/tracing_test.go b/integration/tracing_test.go index 76acf33bd..d1c718ba8 100644 --- a/integration/tracing_test.go +++ b/integration/tracing_test.go @@ -12,17 +12,15 @@ import ( type TracingSuite struct { BaseSuite - WhoAmiIP string - WhoAmiPort int - ZipkinIP string - TracingBackend string + WhoAmiIP string + WhoAmiPort int + IP string } type TracingTemplate struct { - WhoAmiIP string - WhoAmiPort int - ZipkinIP string - TracingBackend string + WhoAmiIP string + WhoAmiPort int + IP string } func (s *TracingSuite) SetUpSuite(c *check.C) { @@ -35,21 +33,20 @@ func (s *TracingSuite) SetUpSuite(c *check.C) { func (s *TracingSuite) startZipkin(c *check.C) { s.composeProject.Start(c, "zipkin") - s.ZipkinIP = s.composeProject.Container(c, "zipkin").NetworkSettings.IPAddress - s.TracingBackend = "zipkin" + s.IP = s.composeProject.Container(c, "zipkin").NetworkSettings.IPAddress // Wait for Zipkin to turn ready. - err := try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/services", 20*time.Second, try.StatusCodeIs(http.StatusOK)) + err := try.GetRequest("http://"+s.IP+":9411/api/v2/services", 20*time.Second, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) } func (s *TracingSuite) TestZipkinRateLimit(c *check.C) { s.startZipkin(c) - file := s.adaptFile(c, "fixtures/tracing/simple.toml", TracingTemplate{ - WhoAmiIP: s.WhoAmiIP, - WhoAmiPort: s.WhoAmiPort, - ZipkinIP: s.ZipkinIP, - TracingBackend: s.TracingBackend, + defer s.composeProject.Stop(c, "zipkin") + file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{ + WhoAmiIP: s.WhoAmiIP, + WhoAmiPort: s.WhoAmiPort, + IP: s.IP, }) defer os.Remove(file) @@ -89,18 +86,18 @@ func (s *TracingSuite) TestZipkinRateLimit(c *check.C) { err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service1/router1@file", "ratelimit@file")) + err = try.GetRequest("http://"+s.IP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service1/router1@file", "ratelimit@file")) c.Assert(err, checker.IsNil) } func (s *TracingSuite) TestZipkinRetry(c *check.C) { s.startZipkin(c) - file := s.adaptFile(c, "fixtures/tracing/simple.toml", TracingTemplate{ - WhoAmiIP: s.WhoAmiIP, - WhoAmiPort: 81, - ZipkinIP: s.ZipkinIP, - TracingBackend: s.TracingBackend, + defer s.composeProject.Stop(c, "zipkin") + file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{ + WhoAmiIP: s.WhoAmiIP, + WhoAmiPort: 81, + IP: s.IP, }) defer os.Remove(file) @@ -117,17 +114,17 @@ func (s *TracingSuite) TestZipkinRetry(c *check.C) { err = try.GetRequest("http://127.0.0.1:8000/retry", 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service2/router2@file", "retry@file")) + err = try.GetRequest("http://"+s.IP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service2/router2@file", "retry@file")) c.Assert(err, checker.IsNil) } func (s *TracingSuite) TestZipkinAuth(c *check.C) { s.startZipkin(c) - file := s.adaptFile(c, "fixtures/tracing/simple.toml", TracingTemplate{ - WhoAmiIP: s.WhoAmiIP, - WhoAmiPort: s.WhoAmiPort, - ZipkinIP: s.ZipkinIP, - TracingBackend: s.TracingBackend, + defer s.composeProject.Stop(c, "zipkin") + file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{ + WhoAmiIP: s.WhoAmiIP, + WhoAmiPort: s.WhoAmiPort, + IP: s.IP, }) defer os.Remove(file) @@ -144,6 +141,120 @@ func (s *TracingSuite) TestZipkinAuth(c *check.C) { err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("entrypoint web", "basic-auth@file")) + err = try.GetRequest("http://"+s.IP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("entrypoint web", "basic-auth@file")) + c.Assert(err, checker.IsNil) +} + +func (s *TracingSuite) startJaeger(c *check.C) { + s.composeProject.Start(c, "jaeger") + s.IP = s.composeProject.Container(c, "jaeger").NetworkSettings.IPAddress + + // Wait for Jaeger to turn ready. + err := try.GetRequest("http://"+s.IP+":16686/api/services", 20*time.Second, try.StatusCodeIs(http.StatusOK)) + c.Assert(err, checker.IsNil) +} + +func (s *TracingSuite) TestJaegerRateLimit(c *check.C) { + s.startJaeger(c) + defer s.composeProject.Stop(c, "jaeger") + file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{ + WhoAmiIP: s.WhoAmiIP, + WhoAmiPort: s.WhoAmiPort, + IP: s.IP, + }) + defer os.Remove(file) + + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + // wait for traefik + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth")) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + c.Assert(err, checker.IsNil) + err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + c.Assert(err, checker.IsNil) + err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) + c.Assert(err, checker.IsNil) + + // sleep for 4 seconds to be certain the configured time period has elapsed + // then test another request and verify a 200 status code + time.Sleep(4 * time.Second) + err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + c.Assert(err, checker.IsNil) + + // continue requests at 3 second intervals to test the other rate limit time period + time.Sleep(3 * time.Second) + err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + c.Assert(err, checker.IsNil) + + time.Sleep(3 * time.Second) + err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + c.Assert(err, checker.IsNil) + + time.Sleep(3 * time.Second) + err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://"+s.IP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("forward service1/router1@file", "ratelimit@file")) + c.Assert(err, checker.IsNil) + +} + +func (s *TracingSuite) TestJaegerRetry(c *check.C) { + s.startJaeger(c) + defer s.composeProject.Stop(c, "jaeger") + file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{ + WhoAmiIP: s.WhoAmiIP, + WhoAmiPort: 81, + IP: s.IP, + }) + defer os.Remove(file) + + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + // wait for traefik + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth")) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/retry", 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://"+s.IP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("forward service2/router2@file", "retry@file")) + c.Assert(err, checker.IsNil) +} + +func (s *TracingSuite) TestJaegerAuth(c *check.C) { + s.startJaeger(c) + defer s.composeProject.Stop(c, "jaeger") + file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{ + WhoAmiIP: s.WhoAmiIP, + WhoAmiPort: s.WhoAmiPort, + IP: s.IP, + }) + defer os.Remove(file) + + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + // wait for traefik + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth")) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://"+s.IP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("EntryPoint web", "basic-auth@file")) c.Assert(err, checker.IsNil) } diff --git a/pkg/anonymize/anonymize_config_test.go b/pkg/anonymize/anonymize_config_test.go index 5dc291eda..928d4254a 100644 --- a/pkg/anonymize/anonymize_config_test.go +++ b/pkg/anonymize/anonymize_config_test.go @@ -15,6 +15,7 @@ import ( "github.com/containous/traefik/pkg/provider/kubernetes/ingress" traefiktls "github.com/containous/traefik/pkg/tls" "github.com/containous/traefik/pkg/tracing/datadog" + "github.com/containous/traefik/pkg/tracing/haystack" "github.com/containous/traefik/pkg/tracing/instana" "github.com/containous/traefik/pkg/tracing/jaeger" "github.com/containous/traefik/pkg/tracing/zipkin" @@ -223,7 +224,6 @@ func TestDo_globalConfiguration(t *testing.T) { } config.Tracing = &static.Tracing{ - Backend: "myBackend", ServiceName: "myServiceName", SpanNameLimit: 3, Jaeger: &jaeger.Config{ @@ -253,6 +253,15 @@ func TestDo_globalConfiguration(t *testing.T) { LocalAgentPort: 32, LogLevel: "ggg", }, + Haystack: &haystack.Config{ + LocalAgentHost: "fff", + LocalAgentPort: 32, + GlobalTag: "eee", + TraceIDHeaderName: "fff", + ParentIDHeaderName: "ggg", + SpanIDHeaderName: "hhh", + BaggagePrefixHeaderName: "iii", + }, } config.HostResolver = &types.HostResolverConfig{ diff --git a/pkg/config/file/file_node_test.go b/pkg/config/file/file_node_test.go index 66be88999..a8e1cb7a9 100644 --- a/pkg/config/file/file_node_test.go +++ b/pkg/config/file/file_node_test.go @@ -292,7 +292,6 @@ func Test_decodeFileToNode_Toml(t *testing.T) { {Name: "MaxIdleConnsPerHost", Value: "42"}, {Name: "RootCAs", Value: "foobar,foobar"}}}, {Name: "Tracing", Children: []*parser.Node{ - {Name: "Backend", Value: "foobar"}, {Name: "DataDog", Children: []*parser.Node{ {Name: "BagagePrefixHeaderName", Value: "foobar"}, {Name: "Debug", Value: "true"}, @@ -302,6 +301,13 @@ func Test_decodeFileToNode_Toml(t *testing.T) { {Name: "PrioritySampling", Value: "true"}, {Name: "SamplingPriorityHeaderName", Value: "foobar"}, {Name: "TraceIDHeaderName", Value: "foobar"}}}, + {Name: "Haystack", Children: []*parser.Node{ + {Name: "GlobalTag", Value: "foobar"}, + {Name: "LocalAgentHost", Value: "foobar"}, + {Name: "LocalAgentPort", Value: "42"}, + {Name: "ParentIDHeaderName", Value: "foobar"}, + {Name: "SpanIDHeaderName", Value: "foobar"}, + {Name: "TraceIDHeaderName", Value: "foobar"}}}, {Name: "Instana", Children: []*parser.Node{ {Name: "LocalAgentHost", Value: "foobar"}, {Name: "LocalAgentPort", Value: "42"}, @@ -561,7 +567,6 @@ func Test_decodeFileToNode_Yaml(t *testing.T) { {Name: "MaxIdleConnsPerHost", Value: "42"}, {Name: "RootCAs", Value: "foobar,foobar"}}}, {Name: "Tracing", Children: []*parser.Node{ - {Name: "Backend", Value: "foobar"}, {Name: "DataDog", Children: []*parser.Node{ {Name: "BagagePrefixHeaderName", Value: "foobar"}, {Name: "Debug", Value: "true"}, @@ -571,6 +576,13 @@ func Test_decodeFileToNode_Yaml(t *testing.T) { {Name: "PrioritySampling", Value: "true"}, {Name: "SamplingPriorityHeaderName", Value: "foobar"}, {Name: "TraceIDHeaderName", Value: "foobar"}}}, + {Name: "Haystack", Children: []*parser.Node{ + {Name: "GlobalTag", Value: "foobar"}, + {Name: "LocalAgentHost", Value: "foobar"}, + {Name: "LocalAgentPort", Value: "42"}, + {Name: "ParentIDHeaderName", Value: "foobar"}, + {Name: "SpanIDHeaderName", Value: "foobar"}, + {Name: "TraceIDHeaderName", Value: "foobar"}}}, {Name: "Instana", Children: []*parser.Node{ {Name: "LocalAgentHost", Value: "foobar"}, {Name: "LocalAgentPort", Value: "42"}, diff --git a/pkg/config/file/fixtures/sample.toml b/pkg/config/file/fixtures/sample.toml index 8ef1d61b8..4cd6436ab 100644 --- a/pkg/config/file/fixtures/sample.toml +++ b/pkg/config/file/fixtures/sample.toml @@ -205,7 +205,6 @@ name1 = "foobar" [Tracing] - Backend = "foobar" ServiceName = "foobar" SpanNameLimit = 42 @@ -240,6 +239,14 @@ LocalAgentPort = 42 LogLevel = "foobar" + [Tracing.Haystack] + GlobalTag = "foobar" + LocalAgentHost = "foobar" + LocalAgentPort = 42 + ParentIDHeaderName = "foobar" + SpanIDHeaderName = "foobar" + TraceIDHeaderName = "foobar" + [HostResolver] CnameFlattening = true ResolvConfig = "foobar" diff --git a/pkg/config/file/fixtures/sample.yml b/pkg/config/file/fixtures/sample.yml index d5908ad38..23724c162 100644 --- a/pkg/config/file/fixtures/sample.yml +++ b/pkg/config/file/fixtures/sample.yml @@ -193,7 +193,6 @@ AccessLog: name0: foobar name1: foobar Tracing: - Backend: foobar ServiceName: foobar SpanNameLimit: 42 Jaeger: @@ -223,6 +222,13 @@ Tracing: LocalAgentHost: foobar LocalAgentPort: 42 LogLevel: foobar + Haystack: + GlobalTag: foobar + LocalAgentHost: foobar + LocalAgentPort: 42 + ParentIDHeaderName: foobar + TraceIDHeaderName: foobar + SpanIDHeaderName: foobar HostResolver: CnameFlattening: true ResolvConfig: foobar diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index c6ff9f4bd..99022af8c 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -24,7 +24,6 @@ import ( "github.com/containous/traefik/pkg/types" assetfs "github.com/elazarl/go-bindata-assetfs" "github.com/go-acme/lego/challenge/dns01" - jaegercli "github.com/uber/jaeger-client-go" ) const ( @@ -130,7 +129,6 @@ func (a *LifeCycle) SetDefaults() { // Tracing holds the tracing configuration. type Tracing struct { - Backend string `description:"Selects the tracking backend ('jaeger','zipkin','datadog','instana')." export:"true"` ServiceName string `description:"Set the name for this service." export:"true"` SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)." export:"true"` Jaeger *jaeger.Config `description:"Settings for jaeger." label:"allowEmpty"` @@ -142,7 +140,6 @@ type Tracing struct { // SetDefaults sets the default values. func (t *Tracing) SetDefaults() { - t.Backend = "jaeger" t.ServiceName = "traefik" t.SpanNameLimit = 0 } @@ -198,103 +195,6 @@ func (c *Configuration) SetEffectiveConfiguration(configFile string) { } c.initACMEProvider() - c.initTracing() -} - -func (c *Configuration) initTracing() { - if c.Tracing != nil { - switch c.Tracing.Backend { - case jaeger.Name: - if c.Tracing.Jaeger == nil { - c.Tracing.Jaeger = &jaeger.Config{ - SamplingServerURL: "http://localhost:5778/sampling", - SamplingType: "const", - SamplingParam: 1.0, - LocalAgentHostPort: "127.0.0.1:6831", - Propagation: "jaeger", - Gen128Bit: false, - TraceContextHeaderName: jaegercli.TraceContextHeaderName, - } - } - if c.Tracing.Zipkin != nil { - log.Warn("Zipkin configuration will be ignored") - c.Tracing.Zipkin = nil - } - if c.Tracing.DataDog != nil { - log.Warn("DataDog configuration will be ignored") - c.Tracing.DataDog = nil - } - if c.Tracing.Instana != nil { - log.Warn("Instana configuration will be ignored") - c.Tracing.Instana = nil - } - case zipkin.Name: - if c.Tracing.Zipkin == nil { - c.Tracing.Zipkin = &zipkin.Config{ - HTTPEndpoint: "http://localhost:9411/api/v1/spans", - SameSpan: false, - ID128Bit: true, - Debug: false, - SampleRate: 1.0, - } - } - if c.Tracing.Jaeger != nil { - log.Warn("Jaeger configuration will be ignored") - c.Tracing.Jaeger = nil - } - if c.Tracing.DataDog != nil { - log.Warn("DataDog configuration will be ignored") - c.Tracing.DataDog = nil - } - if c.Tracing.Instana != nil { - log.Warn("Instana configuration will be ignored") - c.Tracing.Instana = nil - } - case datadog.Name: - if c.Tracing.DataDog == nil { - c.Tracing.DataDog = &datadog.Config{ - LocalAgentHostPort: "localhost:8126", - GlobalTag: "", - Debug: false, - } - } - if c.Tracing.Zipkin != nil { - log.Warn("Zipkin configuration will be ignored") - c.Tracing.Zipkin = nil - } - if c.Tracing.Jaeger != nil { - log.Warn("Jaeger configuration will be ignored") - c.Tracing.Jaeger = nil - } - if c.Tracing.Instana != nil { - log.Warn("Instana configuration will be ignored") - c.Tracing.Instana = nil - } - case instana.Name: - if c.Tracing.Instana == nil { - c.Tracing.Instana = &instana.Config{ - LocalAgentHost: "localhost", - LocalAgentPort: 42699, - LogLevel: "info", - } - } - if c.Tracing.Zipkin != nil { - log.Warn("Zipkin configuration will be ignored") - c.Tracing.Zipkin = nil - } - if c.Tracing.Jaeger != nil { - log.Warn("Jaeger configuration will be ignored") - c.Tracing.Jaeger = nil - } - if c.Tracing.DataDog != nil { - log.Warn("DataDog configuration will be ignored") - c.Tracing.DataDog = nil - } - default: - log.Warnf("Unknown tracer %q", c.Tracing.Backend) - return - } - } } // FIXME handle on new configuration ACME struct diff --git a/pkg/server/server.go b/pkg/server/server.go index 4a58b5570..093ee6e21 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -20,10 +20,7 @@ import ( "github.com/containous/traefik/pkg/server/middleware" "github.com/containous/traefik/pkg/tls" "github.com/containous/traefik/pkg/tracing" - "github.com/containous/traefik/pkg/tracing/datadog" - "github.com/containous/traefik/pkg/tracing/instana" "github.com/containous/traefik/pkg/tracing/jaeger" - "github.com/containous/traefik/pkg/tracing/zipkin" "github.com/containous/traefik/pkg/types" ) @@ -53,20 +50,52 @@ type RouteAppenderFactory interface { NewAppender(ctx context.Context, middlewaresBuilder *middleware.Builder, runtimeConfiguration *config.RuntimeConfiguration) types.RouteAppender } -func setupTracing(conf *static.Tracing) tracing.TrackingBackend { - switch conf.Backend { - case jaeger.Name: - return conf.Jaeger - case zipkin.Name: - return conf.Zipkin - case datadog.Name: - return conf.DataDog - case instana.Name: - return conf.Instana - default: - log.WithoutContext().Warnf("Could not initialize tracing: unknown tracer %q", conf.Backend) - return nil +func setupTracing(conf *static.Tracing) tracing.Backend { + var backend tracing.Backend + + if conf.Jaeger != nil { + backend = conf.Jaeger } + + if conf.Zipkin != nil { + if backend != nil { + log.WithoutContext().Error("Multiple tracing backend are not supported: cannot create Zipkin backend.") + } else { + backend = conf.Zipkin + } + } + + if conf.DataDog != nil { + if backend != nil { + log.WithoutContext().Error("Multiple tracing backend are not supported: cannot create DataDog backend.") + } else { + backend = conf.DataDog + } + } + + if conf.Instana != nil { + if backend != nil { + log.WithoutContext().Error("Multiple tracing backend are not supported: cannot create Instana backend.") + } else { + backend = conf.Instana + } + } + + if conf.Haystack != nil { + if backend != nil { + log.WithoutContext().Error("Multiple tracing backend are not supported: cannot create Haystack backend.") + } else { + backend = conf.Haystack + } + } + + if backend == nil { + log.WithoutContext().Debug("Could not initialize tracing, use Jaeger by default") + backend := &jaeger.Config{} + backend.SetDefaults() + } + + return backend } // NewServer returns an initialized Server. @@ -100,11 +129,12 @@ func NewServer(staticConfiguration static.Configuration, provider provider.Provi server.routinesPool = safe.NewPool(context.Background()) if staticConfiguration.Tracing != nil { - trackingBackend := setupTracing(staticConfiguration.Tracing) - var err error - server.tracer, err = tracing.NewTracing(staticConfiguration.Tracing.ServiceName, staticConfiguration.Tracing.SpanNameLimit, trackingBackend) - if err != nil { - log.WithoutContext().Warnf("Unable to create tracer: %v", err) + tracingBackend := setupTracing(staticConfiguration.Tracing) + if tracingBackend != nil { + server.tracer, err = tracing.NewTracing(staticConfiguration.Tracing.ServiceName, staticConfiguration.Tracing.SpanNameLimit, tracingBackend) + if err != nil { + log.WithoutContext().Warnf("Unable to create tracer: %v", err) + } } } diff --git a/pkg/tracing/haystack/haystack.go b/pkg/tracing/haystack/haystack.go index b37940895..58a65be02 100644 --- a/pkg/tracing/haystack/haystack.go +++ b/pkg/tracing/haystack/haystack.go @@ -21,7 +21,7 @@ type Config struct { TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." export:"true"` ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." export:"true"` SpanIDHeaderName string `description:"Specifies the header name that will be used to store the span ID." export:"true"` - BaggagePrefixHeaderName string `description:"specifies the header name prefix that will be used to store baggage items in a map." export:"true"` + BaggagePrefixHeaderName string `description:"Specifies the header name prefix that will be used to store baggage items in a map." export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go index 463a497f4..c370c05b9 100644 --- a/pkg/tracing/tracing.go +++ b/pkg/tracing/tracing.go @@ -38,8 +38,8 @@ func FromContext(ctx context.Context) (*Tracing, error) { return tracer, nil } -// TrackingBackend is an abstraction for tracking backend (Jaeger, Zipkin, ...). -type TrackingBackend interface { +// Backend is an abstraction for tracking backend (Jaeger, Zipkin, ...). +type Backend interface { Setup(componentName string) (opentracing.Tracer, io.Closer, error) } @@ -53,14 +53,14 @@ type Tracing struct { } // NewTracing Creates a Tracing. -func NewTracing(serviceName string, spanNameLimit int, trackingBackend TrackingBackend) (*Tracing, error) { +func NewTracing(serviceName string, spanNameLimit int, tracingBackend Backend) (*Tracing, error) { tracing := &Tracing{ ServiceName: serviceName, SpanNameLimit: spanNameLimit, } var err error - tracing.tracer, tracing.closer, err = trackingBackend.Setup(serviceName) + tracing.tracer, tracing.closer, err = tracingBackend.Setup(serviceName) if err != nil { return nil, err } From f6436663ebcf67cb4db5f23e23fe5c5d2271340f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Szab=C3=B3?= Date: Fri, 28 Jun 2019 00:36:04 +0200 Subject: [PATCH 07/11] Make HTTP Keep-Alive timeout configurable for backend connections --- .../reference/static-configuration/cli.txt | 4 + .../reference/static-configuration/env.md | 4 + .../reference/static-configuration/file.toml | 1 + integration/fixtures/timeout/keepalive.toml | 31 ++++++ integration/integration_test.go | 1 + integration/keepalive_test.go | 105 ++++++++++++++++++ pkg/config/static/static_config.go | 2 + pkg/server/roundtripper.go | 1 + 8 files changed, 149 insertions(+) create mode 100644 integration/fixtures/timeout/keepalive.toml create mode 100644 integration/keepalive_test.go diff --git a/docs/content/reference/static-configuration/cli.txt b/docs/content/reference/static-configuration/cli.txt index b4c087f1f..dfece6186 100644 --- a/docs/content/reference/static-configuration/cli.txt +++ b/docs/content/reference/static-configuration/cli.txt @@ -477,6 +477,10 @@ The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. +--serverstransport.forwardingtimeouts.idleconntimeout (Default: "90s") + The maximum period for which an idle HTTP keep-alive connection to a backend + server will remain open before closing itself. + --serverstransport.insecureskipverify (Default: "false") Disable SSL certificate verification. diff --git a/docs/content/reference/static-configuration/env.md b/docs/content/reference/static-configuration/env.md index 3e092aa04..09eb82a09 100644 --- a/docs/content/reference/static-configuration/env.md +++ b/docs/content/reference/static-configuration/env.md @@ -462,6 +462,10 @@ The amount of time to wait until a connection to a backend server can be establi `TRAEFIK_SERVERSTRANSPORT_FORWARDINGTIMEOUTS_RESPONSEHEADERTIMEOUT`: The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. (Default: ```0```) +`TRAEFIK_SERVERSTRANSPORT_FORWARDINGTIMEOUTS_IDLECONNTIMEOUT`: +The maximum period for which an idle HTTP keep-alive connection to a backend +server will remain open before closing itself. (Default: ```90s```) + `TRAEFIK_SERVERSTRANSPORT_INSECURESKIPVERIFY`: Disable SSL certificate verification. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index d87c889c6..4c7d08810 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -9,6 +9,7 @@ [ServersTransport.ForwardingTimeouts] DialTimeout = 42 ResponseHeaderTimeout = 42 + IdleConnTimeout = 5 [EntryPoints] diff --git a/integration/fixtures/timeout/keepalive.toml b/integration/fixtures/timeout/keepalive.toml new file mode 100644 index 000000000..c01dce754 --- /dev/null +++ b/integration/fixtures/timeout/keepalive.toml @@ -0,0 +1,31 @@ +[global] +checkNewVersion = false +sendAnonymousUsage = false + +[log] +level = "DEBUG" + +[serversTransport.forwardingTimeouts] + idleConnTimeout = "{{ .IdleConnTimeout }}" + +[entryPoints] + [entryPoints.web] + address = ":8000" + +[api] + +[providers] + [providers.file] + +[http.routers] + [http.routers.router1] + Service = "keepalive" + Rule = "PathPrefix(`/keepalive`)" + +[http.services] + [http.services.keepalive] + [http.services.keepalive.LoadBalancer] + passHostHeader = true + [[http.services.keepalive.LoadBalancer.Servers]] + URL = "{{ .KeepAliveServer }}" + Weight = 1 diff --git a/integration/integration_test.go b/integration/integration_test.go index 1355b7767..150638c2b 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -49,6 +49,7 @@ func init() { check.Suite(&HeadersSuite{}) check.Suite(&HostResolverSuite{}) check.Suite(&HTTPSSuite{}) + check.Suite(&KeepAliveSuite{}) check.Suite(&LogRotationSuite{}) check.Suite(&MarathonSuite{}) check.Suite(&MarathonSuite15{}) diff --git a/integration/keepalive_test.go b/integration/keepalive_test.go new file mode 100644 index 000000000..7dad0153b --- /dev/null +++ b/integration/keepalive_test.go @@ -0,0 +1,105 @@ +package integration + +import ( + "math" + "net" + "net/http" + "net/http/httptest" + "os" + "time" + + "github.com/containous/traefik/integration/try" + "github.com/go-check/check" + checker "github.com/vdemeester/shakers" +) + +type KeepAliveSuite struct { + BaseSuite +} + +type KeepAliveConfig struct { + KeepAliveServer string + IdleConnTimeout string +} + +type connStateChangeEvent struct { + key string + state http.ConnState +} + +func (s *KeepAliveSuite) TestShouldRespectConfiguredBackendHttpKeepAliveTime(c *check.C) { + idleTimeout := time.Duration(75) * time.Millisecond + + connStateChanges := make(chan connStateChangeEvent) + noMoreRequests := make(chan bool, 1) + completed := make(chan bool, 1) + + // keep track of HTTP connections and their status changes and measure their idle period + go func() { + connCount := 0 + idlePeriodStartMap := make(map[string]time.Time) + idlePeriodLengthMap := make(map[string]time.Duration) + + maxWaitDuration := 5 * time.Second + maxWaitTimeExceeded := time.After(maxWaitDuration) + moreRequestsExpected := true + + // Ensure that all idle HTTP connections are closed before verification phase + for moreRequestsExpected || len(idlePeriodLengthMap) < connCount { + select { + case event := <-connStateChanges: + switch event.state { + case http.StateNew: + connCount++ + case http.StateIdle: + idlePeriodStartMap[event.key] = time.Now() + case http.StateClosed: + idlePeriodLengthMap[event.key] = time.Since(idlePeriodStartMap[event.key]) + } + case <-noMoreRequests: + moreRequestsExpected = false + case <-maxWaitTimeExceeded: + c.Logf("timeout waiting for all connections to close, waited for %v, configured idle timeout was %v", maxWaitDuration, idleTimeout) + c.Fail() + close(completed) + return + } + } + + c.Check(connCount, checker.Equals, 1) + + for _, idlePeriod := range idlePeriodLengthMap { + // Our method of measuring the actual idle period is not precise, so allow some sub-ms deviation + c.Check(math.Round(idlePeriod.Seconds()), checker.LessOrEqualThan, idleTimeout.Seconds()) + } + + close(completed) + }() + + server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + })) + + server.Config.ConnState = func(conn net.Conn, state http.ConnState) { + connStateChanges <- connStateChangeEvent{key: conn.RemoteAddr().String(), state: state} + } + server.Start() + defer server.Close() + + config := KeepAliveConfig{KeepAliveServer: server.URL, IdleConnTimeout: idleTimeout.String()} + file := s.adaptFile(c, "fixtures/timeout/keepalive.toml", config) + + defer os.Remove(file) + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + + err := cmd.Start() + c.Check(err, checker.IsNil) + defer cmd.Process.Kill() + + err = try.GetRequest("http://127.0.0.1:8000/keepalive", time.Duration(1)*time.Second, try.StatusCodeIs(200)) + c.Check(err, checker.IsNil) + + close(noMoreRequests) + <-completed +} diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index 99022af8c..d149ef37b 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -109,11 +109,13 @@ func (a *RespondingTimeouts) SetDefaults() { type ForwardingTimeouts struct { DialTimeout types.Duration `description:"The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." export:"true"` ResponseHeaderTimeout types.Duration `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists." export:"true"` + IdleConnTimeout types.Duration `description:"The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself" export:"true"` } // SetDefaults sets the default values. func (f *ForwardingTimeouts) SetDefaults() { f.DialTimeout = types.Duration(30 * time.Second) + f.IdleConnTimeout = types.Duration(90 * time.Second) } // LifeCycle contains configurations relevant to the lifecycle (such as the shutdown phase) of Traefik. diff --git a/pkg/server/roundtripper.go b/pkg/server/roundtripper.go index 90b640e06..f5a99f61f 100644 --- a/pkg/server/roundtripper.go +++ b/pkg/server/roundtripper.go @@ -63,6 +63,7 @@ func createHTTPTransport(transportConfiguration *static.ServersTransport) (*http if transportConfiguration.ForwardingTimeouts != nil { transport.ResponseHeaderTimeout = time.Duration(transportConfiguration.ForwardingTimeouts.ResponseHeaderTimeout) + transport.IdleConnTimeout = time.Duration(transportConfiguration.ForwardingTimeouts.IdleConnTimeout) } if transportConfiguration.InsecureSkipVerify { From c7d336f958f04ed63a76e308317eb5b196e01ad0 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 1 Jul 2019 11:30:05 +0200 Subject: [PATCH 08/11] Use the same case everywhere --- docs/content/contributing/data-collection.md | 27 +- .../getting-started/configuration-overview.md | 4 +- docs/content/getting-started/quick-start.md | 18 +- docs/content/https/acme.md | 276 +++-- docs/content/https/ref-acme.toml | 31 +- docs/content/https/ref-acme.yaml | 127 +++ docs/content/https/tls.md | 97 +- docs/content/middlewares/addprefix.md | 4 +- docs/content/middlewares/basicauth.md | 6 +- docs/content/middlewares/buffering.md | 2 +- docs/content/middlewares/chain.md | 30 +- docs/content/middlewares/circuitbreaker.md | 10 +- docs/content/middlewares/compress.md | 2 +- docs/content/middlewares/digestauth.md | 10 +- docs/content/middlewares/errorpages.md | 2 +- docs/content/middlewares/forwardauth.md | 54 +- docs/content/middlewares/headers.md | 103 +- docs/content/middlewares/ipwhitelist.md | 26 +- docs/content/middlewares/maxconnection.md | 4 +- docs/content/middlewares/overview.md | 26 +- docs/content/middlewares/passtlsclientcert.md | 50 +- docs/content/middlewares/ratelimit.md | 10 +- docs/content/middlewares/redirectregex.md | 4 +- docs/content/middlewares/redirectscheme.md | 2 +- docs/content/middlewares/replacepath.md | 4 +- docs/content/middlewares/replacepathregex.md | 2 +- docs/content/middlewares/retry.md | 2 +- docs/content/middlewares/stripprefix.md | 4 +- docs/content/middlewares/stripprefixregex.md | 4 +- docs/content/observability/tracing/datadog.md | 10 +- docs/content/operations/api.md | 20 +- docs/content/operations/dashboard.md | 8 +- docs/content/operations/ping.md | 2 +- docs/content/providers/docker.md | 10 +- docs/content/providers/file.md | 35 +- docs/content/providers/kubernetes-crd.md | 12 +- docs/content/providers/marathon.md | 42 +- docs/content/providers/rancher.md | 8 +- docs/content/providers/rancher.toml | 14 +- .../reference/dynamic-configuration/docker.md | 2 + .../reference/dynamic-configuration/file.toml | 467 +++++---- .../reference/dynamic-configuration/file.yaml | 229 ++--- .../dynamic-configuration/labels.yml | 306 +++--- .../reference/static-configuration/file.toml | 452 ++++----- .../reference/static-configuration/file.yaml | 250 ++--- docs/content/routing/entrypoints.md | 177 +++- docs/content/routing/overview.md | 88 +- docs/content/routing/routers/index.md | 488 ++++++--- docs/content/routing/services/index.md | 310 ++++-- docs/content/user-guides/marathon.md | 12 +- integration/fixtures/access_log_config.toml | 16 +- integration/fixtures/acme/acme_base.toml | 14 +- integration/fixtures/acme/acme_tls.toml | 24 +- .../fixtures/acme/acme_tls_dynamic.toml | 12 +- .../acme/acme_tls_multiple_entrypoints.toml | 8 +- integration/fixtures/acme/certificates.toml | 4 +- integration/fixtures/docker/minimal.toml | 16 +- integration/fixtures/docker/simple.toml | 16 +- integration/fixtures/error_pages/error.toml | 34 +- integration/fixtures/error_pages/simple.toml | 38 +- .../fixtures/file/56-simple-panic.toml | 11 +- integration/fixtures/file/dir/simple1.toml | 4 +- integration/fixtures/file/dir/simple2.toml | 4 +- integration/fixtures/file/directory.toml | 12 +- integration/fixtures/file/simple-hosts.toml | 16 +- integration/fixtures/file/simple.toml | 24 +- integration/fixtures/grpc/config.toml | 18 +- integration/fixtures/grpc/config_h2c.toml | 14 +- .../fixtures/grpc/config_h2c_termination.toml | 19 +- .../fixtures/grpc/config_insecure.toml | 18 +- integration/fixtures/grpc/config_retry.toml | 26 +- integration/fixtures/headers/basic.toml | 14 +- integration/fixtures/headers/cors.toml | 24 +- .../healthcheck/multiple-entrypoints.toml | 20 +- .../fixtures/healthcheck/port_overload.toml | 18 +- integration/fixtures/healthcheck/simple.toml | 20 +- .../https/clientca/https_1ca1config.toml | 40 +- .../https/clientca/https_2ca1config.toml | 38 +- .../https/clientca/https_2ca2config.toml | 34 +- integration/fixtures/https/dynamic_https.toml | 20 +- .../fixtures/https/dynamic_https_sni.toml | 12 +- .../https/dynamic_https_sni_default_cert.toml | 18 +- .../fixtures/https/https_redirect.toml | 60 +- integration/fixtures/https/https_sni.toml | 32 +- .../https_sni_case_insensitive_dynamic.toml | 16 +- .../https/https_sni_default_cert.toml | 18 +- .../fixtures/https/https_sni_strict.toml | 10 +- .../fixtures/https/https_tls_options.toml | 36 +- integration/fixtures/https/rootcas/https.toml | 26 +- .../https/rootcas/https_with_file.toml | 26 +- integration/fixtures/k8s_crd.toml | 22 +- integration/fixtures/k8s_default.toml | 21 +- integration/fixtures/log_rotation_config.toml | 31 +- integration/fixtures/marathon/simple.toml | 20 +- integration/fixtures/multiple_provider.toml | 31 +- integration/fixtures/multiprovider.toml | 27 +- integration/fixtures/proxy-protocol/with.toml | 20 +- .../fixtures/proxy-protocol/without.toml | 20 +- integration/fixtures/ratelimit/simple.toml | 47 +- integration/fixtures/reqacceptgrace.toml | 35 +- integration/fixtures/rest/simple.toml | 8 +- integration/fixtures/retry/simple.toml | 32 +- integration/fixtures/simple_auth.toml | 16 +- integration/fixtures/simple_default.toml | 6 +- integration/fixtures/simple_hostresolver.toml | 18 +- integration/fixtures/simple_stats.toml | 39 +- integration/fixtures/simple_web.toml | 8 +- integration/fixtures/simple_whitelist.toml | 14 +- .../tcp/catch-all-no-tls-with-https.toml | 49 +- .../fixtures/tcp/catch-all-no-tls.toml | 28 +- integration/fixtures/tcp/mixed.toml | 90 +- .../fixtures/tcp/multi-tls-options.toml | 44 +- .../fixtures/tcp/non-tls-fallback.toml | 76 +- integration/fixtures/tcp/non-tls.toml | 28 +- .../fixtures/timeout/forwarding_timeouts.toml | 30 +- integration/fixtures/timeout/keepalive.toml | 24 +- .../fixtures/tlsclientheaders/simple.toml | 7 +- .../fixtures/tracing/simple-jaeger.toml | 54 +- .../fixtures/tracing/simple-zipkin.toml | 73 +- integration/fixtures/traefik_log_config.toml | 18 +- integration/fixtures/websocket/config.toml | 22 +- .../fixtures/websocket/config_https.toml | 28 +- integration/testdata/rawdata-crd.json | 6 +- integration/testdata/rawdata-ingress.json | 3 +- pkg/anonymize/anonymize_config_test.go | 2 +- pkg/api/handler_test.go | 1 - pkg/api/testdata/getrawdata.json | 4 +- pkg/api/testdata/service-bar.json | 2 +- pkg/api/testdata/services-page2.json | 2 +- pkg/api/testdata/services.json | 4 +- pkg/api/testdata/tcpservice-bar.json | 2 +- pkg/api/testdata/tcpservices-page2.json | 2 +- pkg/api/testdata/tcpservices.json | 4 +- pkg/config/dyn_config.go | 236 ++--- pkg/config/file/file_node_test.go | 956 ++++++++---------- pkg/config/file/fixtures/sample.toml | 950 ++++++++--------- pkg/config/file/fixtures/sample.yml | 444 ++++---- pkg/config/middlewares.go | 315 +++--- pkg/config/static/entrypoints.go | 20 +- pkg/config/static/static_config.go | 95 +- pkg/metrics/datadog.go | 4 +- pkg/metrics/datadog_test.go | 2 +- pkg/ping/ping.go | 4 +- pkg/provider/acme/provider.go | 40 +- pkg/provider/docker/docker.go | 20 +- pkg/provider/file/file.go | 10 +- .../file/fixtures/toml/dir01_file01.toml | 8 +- .../file/fixtures/toml/dir01_file02.toml | 18 +- .../file/fixtures/toml/dir01_file03.toml | 26 +- .../file/fixtures/toml/simple_file_01.toml | 85 +- .../file/fixtures/toml/simple_file_02.toml | 91 +- .../fixtures/toml/simple_traefik_file_02.toml | 56 +- .../simple_traefik_file_with_templating.toml | 57 +- .../file/fixtures/yaml/dir01_file02.yml | 6 +- .../file/fixtures/yaml/dir01_file03.yml | 16 +- .../file/fixtures/yaml/simple_file_01.yml | 32 +- .../file/fixtures/yaml/simple_file_02.yml | 33 +- .../fixtures/yaml/simple_traefik_file_02.yml | 22 +- .../yaml/template_in_directory_file02.yml | 2 +- pkg/provider/kubernetes/crd/kubernetes.go | 14 +- pkg/provider/kubernetes/ingress/kubernetes.go | 22 +- pkg/provider/marathon/marathon.go | 34 +- pkg/provider/rancher/config_test.go | 1 - pkg/provider/rancher/rancher.go | 16 +- pkg/provider/rest/rest.go | 2 +- pkg/server/server.go | 6 +- pkg/tls/certificate.go | 4 +- pkg/tls/tls.go | 16 +- pkg/tracing/datadog/datadog.go | 16 +- pkg/tracing/haystack/haystack.go | 14 +- pkg/tracing/instana/instana.go | 6 +- pkg/tracing/jaeger/jaeger.go | 14 +- pkg/tracing/zipkin/zipkin.go | 10 +- pkg/types/domains.go | 4 +- pkg/types/host_resolver.go | 6 +- pkg/types/logs.go | 32 +- pkg/types/metrics.go | 44 +- pkg/types/tls.go | 10 +- traefik.sample.toml | 4 +- 179 files changed, 5118 insertions(+), 4436 deletions(-) create mode 100644 docs/content/https/ref-acme.yaml diff --git a/docs/content/contributing/data-collection.md b/docs/content/contributing/data-collection.md index 8a6faa405..467584d7c 100644 --- a/docs/content/contributing/data-collection.md +++ b/docs/content/contributing/data-collection.md @@ -14,9 +14,9 @@ For this very reason, the sendAnonymousUsage option is mandatory: we want you to ??? example "Enabling Data Collection with TOML" ```toml - [Global] - # Send anonymous usage data - sendAnonymousUsage = true + [global] + # Send anonymous usage data + sendAnonymousUsage = true ``` ??? example "Enabling Data Collection with the CLI" @@ -51,24 +51,23 @@ Once a day (the first call begins 10 minutes after the start of Traefik), we col ```toml [entryPoints] - [entryPoints.web] - address = ":80" + [entryPoints.web] + address = ":80" [api] - [Docker] + [providers.docker] endpoint = "tcp://10.10.10.10:2375" - domain = "foo.bir" exposedByDefault = true swarmMode = true - [Docker.TLS] + [providers.docker.TLS] ca = "dockerCA" cert = "dockerCert" key = "dockerKey" insecureSkipVerify = true - [ECS] + [providers.ecs] domain = "foo.bar" exposedByDefault = true clusters = ["foo-bar"] @@ -81,24 +80,24 @@ Once a day (the first call begins 10 minutes after the start of Traefik), we col ```toml [entryPoints] - [entryPoints.web] - address = ":80" + [entryPoints.web] + address = ":80" [api] - [Docker] + [providers.docker] endpoint = "xxxx" domain = "xxxx" exposedByDefault = true swarmMode = true - [Docker.TLS] + [providers.docker.TLS] ca = "xxxx" cert = "xxxx" key = "xxxx" insecureSkipVerify = false - [ECS] + [providers.ecs] domain = "xxxx" exposedByDefault = true clusters = [] diff --git a/docs/content/getting-started/configuration-overview.md b/docs/content/getting-started/configuration-overview.md index 2a8861488..a24aa7b7f 100644 --- a/docs/content/getting-started/configuration-overview.md +++ b/docs/content/getting-started/configuration-overview.md @@ -6,7 +6,7 @@ How the Magic Happens ![Configuration](../assets/img/static-dynamic-configuration.png) Configuration in Traefik can refer to two different things: - + - The fully dynamic routing configuration (referred to as the _dynamic configuration_) - The startup configuration (referred to as the _static configuration_) @@ -24,7 +24,7 @@ This configuration can change and is seamlessly hot-reloaded, without any reques Traefik gets its _dynamic configuration_ from [providers](../providers/overview.md): whether an orchestrator, a service registry, or a plain old configuration file. Since this configuration is specific to your infrastructure choices, we invite you to refer to the [dedicated section of this documentation](../providers/overview.md). !!! Note - + In the [Quick Start example](../getting-started/quick-start.md), the dynamic configuration comes from docker in the form of labels attached to your containers. !!! Note diff --git a/docs/content/getting-started/quick-start.md b/docs/content/getting-started/quick-start.md index c6e976184..abe74af88 100644 --- a/docs/content/getting-started/quick-start.md +++ b/docs/content/getting-started/quick-start.md @@ -14,13 +14,18 @@ version: '3' services: reverse-proxy: - image: traefik:v2.0 # The official v2.0 Traefik docker image - command: --api --providers.docker # Enables the web UI and tells Traefik to listen to docker + # The official v2.0 Traefik docker image + image: traefik:v2.0 + # Enables the web UI and tells Traefik to listen to docker + command: --api --providers.docker ports: - - "80:80" # The HTTP port - - "8080:8080" # The Web UI (enabled by --api) + # The HTTP port + - "80:80" + # The Web UI (enabled by --api) + - "8080:8080" volumes: - - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events + # So that Traefik can listen to the Docker events + - /var/run/docker.sock:/var/run/docker.sock ``` **That's it. Now you can launch Traefik!** @@ -42,7 +47,8 @@ Edit your `docker-compose.yml` file and add the following at the end of your fil ```yaml # ... whoami: - image: containous/whoami # A container that exposes an API to show its IP address + # A container that exposes an API to show its IP address + image: containous/whoami labels: - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)" ``` diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index ef75ecf5d..e75d26e00 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -12,56 +12,103 @@ You can configure Traefik to use an ACME provider (like Let's Encrypt) for autom ??? example "Enabling ACME" - ```toml - [entryPoints] - [entryPoints.web] - address = ":80" - - [entryPoints.http-tls] - address = ":443" - - [acme] # every router with TLS enabled will now be able to use ACME for its certificates - email = "your-email@your-domain.org" - storage = "acme.json" - onHostRule = true # dynamic generation based on the Host() & HostSNI() matchers - [acme.httpChallenge] - entryPoint = "web" # used during the challenge - ``` - -??? example "Configuring Wildcard Certificates" - - ```toml + ```toml tab="TOML" [entryPoints] [entryPoints.web] address = ":80" - + [entryPoints.http-tls] address = ":443" + + # every router with TLS enabled will now be able to use ACME for its certificates + [acme] + email = "your-email@your-domain.org" + storage = "acme.json" + # dynamic generation based on the Host() & HostSNI() matchers + onHostRule = true + [acme.httpChallenge] + # used during the challenge + entryPoint = "web" + ``` + + ```yaml tab="YAML" + entryPoints: + web: + address: ":80" + + http-tls: + address: ":443" + + # every router with TLS enabled will now be able to use ACME for its certificates + acme: + email: your-email@your-domain.org + storage: acme.json + # dynamic generation based on the Host() & HostSNI() matchers + onHostRule: true + httpChallenge: + # used during the challenge + entryPoint: web + ``` +??? example "Configuring Wildcard Certificates" + + ```toml tab="TOML" + [entryPoints] + [entryPoints.web] + address = ":80" + + [entryPoints.http-tls] + address = ":443" + [acme] email = "your-email@your-domain.org" storage = "acme.json" [acme.dnsChallenge] provider = "xxx" - + [[acme.domains]] main = "*.mydomain.com" sans = ["mydomain.com"] ``` + + ```yaml tab="YAML" + entryPoints: + web: + address: ":80" + + http-tls: + address: ":443" + + acme: + email: your-email@your-domain.org + storage: acme.json + dnsChallenge: + provide: xxx + + domains: + - main: "*.mydomain.com" + sans: + - mydomain.com + ``` ??? note "Configuration Reference" - There are many available options for ACME. For a quick glance at what's possible, browse the configuration reference: + There are many available options for ACME. + For a quick glance at what's possible, browse the configuration reference: - ```toml + ```toml tab="TOML" --8<-- "content/https/ref-acme.toml" ``` + + ```yaml tab="YAML" + --8<-- "content/https/ref-acme.yaml" + ``` ## Automatic Renewals Traefik automatically tracks the expiry date of ACME certificates it generates. -If there are less than 30 days remaining before the certificate expires, Traefik will attempt to rewnew it automatically. +If there are less than 30 days remaining before the certificate expires, Traefik will attempt to renew it automatically. !!! note Certificates that are no longer used may still be renewed, as Traefik does not currently check if the certificate is being used before renewing. @@ -77,9 +124,14 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry ??? example "Configuring the `tlsChallenge`" - ```toml + ```toml tab="TOML" [acme] - [acme.tlsChallenge] + [acme.tlsChallenge] + ``` + + ```yaml tab="YAML" + acme: + tlsChallenge: {} ``` ### `httpChallenge` @@ -91,11 +143,18 @@ when using the `HTTP-01` challenge, `acme.httpChallenge.entryPoint` must be reac ??? example "Using an EntryPoint Called http for the `httpChallenge`" - ```toml + ```toml tab="TOML" [acme] - # ... - [acme.httpChallenge] - entryPoint = "http" + # ... + [acme.httpChallenge] + entryPoint = "http" + ``` + + ```yaml tab="YAML" + acme: + # ... + httpChallenge: + entryPoint: http ``` !!! note @@ -107,12 +166,21 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni ??? example "Configuring a `dnsChallenge` with the DigitalOcean Provider" - ```toml + ```toml tab="TOML" [acme] - # ... - [acme.dnsChallenge] - provider = "digitalocean" - delayBeforeCheck = 0 + # ... + [acme.dnsChallenge] + provider = "digitalocean" + delayBeforeCheck = 0 + # ... + ``` + + ```yaml tab="YAML" + acme: + # ... + dnsChallenge: + provider: digitalocean + delayBeforeCheck: 0 # ... ``` @@ -200,12 +268,22 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used Use custom DNS servers to resolve the FQDN authority. -```toml +```toml tab="TOML" [acme] - # ... - [acme.dnsChallenge] - # ... - resolvers = ["1.1.1.1:53", "8.8.8.8:53"] + # ... + [acme.dnsChallenge] + # ... + resolvers = ["1.1.1.1:53", "8.8.8.8:53"] +``` + +```yaml tab="YAML" +acme: + # ... + dnsChallenge: + # ... + resolvers: + - "1.1.1.1:53" + - "8.8.8.8:53" ``` #### Wildcard Domains @@ -213,12 +291,23 @@ Use custom DNS servers to resolve the FQDN authority. [ACME V2](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) supports wildcard certificates. As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/staging-endpoint-for-acme-v2/49605) wildcard certificates can only be generated through a [`DNS-01` challenge](#dnschallenge). -```toml +```toml tab="TOML" [acme] - # ... - [[acme.domains]] - main = "*.local1.com" - sans = ["local1.com"] + # ... + [[acme.domains]] + main = "*.local1.com" + sans = ["local1.com"] + +# ... +``` + +```yaml tab="YAML" +acme: + # ... + domains: + - main: "*.local1.com" + sans: + - local1.com # ... ``` @@ -240,17 +329,33 @@ You can set SANs (alternative domains) for each main domain. Every domain must have A/AAAA records pointing to Traefik. Each domain & SAN will lead to a certificate request. -```toml +```toml tab="TOML" [acme] - # ... - [[acme.domains]] - main = "local1.com" - sans = ["test1.local1.com", "test2.local1.com"] - [[acme.domains]] - main = "local2.com" - [[acme.domains]] - main = "*.local3.com" - sans = ["local3.com", "test1.test1.local3.com"] + # ... + [[acme.domains]] + main = "local1.com" + sans = ["test1.local1.com", "test2.local1.com"] + [[acme.domains]] + main = "local2.com" + [[acme.domains]] + main = "*.local3.com" + sans = ["local3.com", "test1.test1.local3.com"] +# ... +``` + +```yaml tab="YAML" +acme: + # ... + domains: + - main: "local1.com" + sans: + - "test1.local1.com" + - "test2.local1.com" + - main: "local2.com" + - main: "*.local3.com" + sans: + - "local3.com" + - "test1.test1.local3.com" # ... ``` @@ -264,11 +369,18 @@ Each domain & SAN will lead to a certificate request. ??? example "Using the Let's Encrypt staging server" - ```toml + ```toml tab="TOML" [acme] - # ... - caServer = "https://acme-staging-v02.api.letsencrypt.org/directory" - # ... + # ... + caServer = "https://acme-staging-v02.api.letsencrypt.org/directory" + # ... + ``` + + ```yaml tab="YAML" + acme: + # ... + caServer: https://acme-staging-v02.api.letsencrypt.org/directory + # ... ``` ## `onHostRule` @@ -277,11 +389,18 @@ Enable certificate generation on [routers](../routing/routers/index.md) `Host` & This will request a certificate from Let's Encrypt for each router with a Host rule. -```toml +```toml tab="TOML" [acme] - # ... - onHostRule = true - # ... + # ... + onHostRule = true + # ... +``` + +```yaml tab="YAML" +acme: + # ... + onHostRule: true + # ... ``` !!! note "Multiple Hosts in a Rule" @@ -294,17 +413,23 @@ This will request a certificate from Let's Encrypt for each router with a Host r The `storage` option sets the location where your ACME certificates are saved to. -```toml +```toml tab="TOML" [acme] - # ... - storage = "acme.json" - # ... + # ... + storage = "acme.json" + # ... ``` -The value can refer to two kinds of storage: +```yaml tab="YAML" +acme + # ... + storage: acme.json + # ... +``` + +The value can refer to some kinds of storage: - a JSON file -- a KV store entry ### In a File @@ -323,19 +448,6 @@ docker run -v "/my/host/acme:/etc/traefik/acme" traefik !!! warning For concurrency reason, this file cannot be shared across multiple instances of Traefik. Use a key value store entry instead. -### In a a Key Value Store Entry - -ACME certificates can be stored in a key-value store entry. - -```toml -storage = "traefik/acme/account" -``` - -!!! note "Storage Size" - - Because key-value stores have limited entry size, the certificates list is compressed _before_ it is saved. - For example, it is possible to store up to _approximately_ 100 ACME certificates in Consul. - ## Fallback If Let's Encrypt is not reachable, the following certificates will apply: diff --git a/docs/content/https/ref-acme.toml b/docs/content/https/ref-acme.toml index 4cc44f8e7..b3a1fc031 100644 --- a/docs/content/https/ref-acme.toml +++ b/docs/content/https/ref-acme.toml @@ -7,31 +7,11 @@ # email = "test@traefik.io" -# File used for certificates storage. -# -# Optional (Deprecated) -# -#storageFile = "acme.json" - # File or key used for certificates storage. # # Required # storage = "acme.json" -# or `storage = "traefik/acme/account"` if using KV store. - -# Deprecated, replaced by [acme.dnsChallenge]. -# -# Optional. -# -# dnsProvider = "digitalocean" - -# Deprecated, replaced by [acme.dnsChallenge.delayBeforeCheck]. -# -# Optional -# Default: 0 -# -# delayDontCheckDNS = 0 # If true, display debug log messages from the acme client library. # @@ -47,14 +27,7 @@ storage = "acme.json" # # overrideCertificates = true -# Deprecated. Enable on demand certificate generation. -# -# Optional -# Default: false -# -# onDemand = true - -# Enable certificate generation on frontends host rules. +# Enable certificate generation on routers host rules. # # Optional # Default: false @@ -95,7 +68,7 @@ storage = "acme.json" # # Required # - # entryPoint = "http" + # entryPoint = "web" # Use a DNS-01 ACME challenge rather than HTTP-01 challenge. # Note: mandatory for wildcard certificate generation. diff --git a/docs/content/https/ref-acme.yaml b/docs/content/https/ref-acme.yaml new file mode 100644 index 000000000..23cd9b7a6 --- /dev/null +++ b/docs/content/https/ref-acme.yaml @@ -0,0 +1,127 @@ +# Enable ACME (Let's Encrypt): automatic SSL. +acme: + + # Email address used for registration. + # + # Required + # + email: "test@traefik.io" + + # File or key used for certificates storage. + # + # Required + # + storage: "acme.json" + + # If true, display debug log messages from the acme client library. + # + # Optional + # Default: false + # + # acmeLogging: true + + # If true, override certificates in key-value store when using storeconfig. + # + # Optional + # Default: false + # + # overrideCertificates: true + + # Enable certificate generation on routers host rules. + # + # Optional + # Default: false + # + # onHostRule: true + + # CA server to use. + # Uncomment the line to use Let's Encrypt's staging server, + # leave commented to go to prod. + # + # Optional + # Default: "https://acme-v02.api.letsencrypt.org/directory" + # + # caServer: "https://acme-staging-v02.api.letsencrypt.org/directory" + + # KeyType to use. + # + # Optional + # Default: "RSA4096" + # + # Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192" + # + # KeyType: RSA4096 + + # Use a TLS-ALPN-01 ACME challenge. + # + # Optional (but recommended) + # + tlsChallenge: + + # Use a HTTP-01 ACME challenge. + # + # Optional + # + # httpChallenge: + + # EntryPoint to use for the HTTP-01 challenges. + # + # Required + # + # entryPoint: web + + # Use a DNS-01 ACME challenge rather than HTTP-01 challenge. + # Note: mandatory for wildcard certificate generation. + # + # Optional + # + # dnsChallenge: + + # DNS provider used. + # + # Required + # + # provider: digitalocean + + # By default, the provider will verify the TXT DNS challenge record before letting ACME verify. + # If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds. + # Useful if internal networks block external DNS queries. + # + # Optional + # Default: 0 + # + # delayBeforeCheck: 0 + + # Use following DNS servers to resolve the FQDN authority. + # + # Optional + # Default: empty + # + # resolvers + # - "1.1.1.1:53" + # - "8.8.8.8:53" + + # Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready. + # + # NOT RECOMMENDED: + # Increase the risk of reaching Let's Encrypt's rate limits. + # + # Optional + # Default: false + # + # disablePropagationCheck: true + + # Domains list. + # Only domains defined here can generate wildcard certificates. + # The certificates for these domains are negotiated at traefik startup only. + # + # domains: + # - main: "local1.com" + # sans: + # - "test1.local1.com" + # - "test2.local1.com" + # - main: "local2.com" + # - main: "*.local3.com" + # sans: + # - "local3.com" + # - "test1.test1.local3.com" diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index 541495ce2..84dacda11 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -13,7 +13,7 @@ See the [Let's Encrypt](./acme.md) page. To add / remove TLS certificates, even when Traefik is already running, their definition can be added to the [dynamic configuration](../getting-started/configuration-overview.md), in the `[[tls.certificates]]` section: -```toml +```toml tab="TOML" [[tls.certificates]] certFile = "/path/to/domain.cert" keyFile = "/path/to/domain.key" @@ -23,6 +23,15 @@ To add / remove TLS certificates, even when Traefik is already running, their de keyFile = "/path/to/other-domain.key" ``` +```yaml tab="YAML" +tls: + certificates: + - certFile: /path/to/domain.cert + keyFile: /path/to/domain.key + - certFile: /path/to/other-domain.cert + keyFile: /path/to/other-domain.key +``` + !!! important "File Provider Only" In the above example, we've used the [file provider](../providers/file.md) to handle these definitions. @@ -32,23 +41,29 @@ To add / remove TLS certificates, even when Traefik is already running, their de In Traefik, certificates are grouped together in certificates stores, which are defined as such: -```toml +```toml tab="TOML" [tls.stores] [tls.stores.default] ``` +```yaml tab="YAML" +tls: + stores: + default: {} +``` + !!! important "Alpha restriction" During the alpha version, any store definition other than the default one (named `default`) will be ignored, and there is thefore only one globally available TLS store. -In the `[[tls.certificates]]` section, a list of stores can then be specified to indicate where the certificates should be stored: +In the `tls.certificates` section, a list of stores can then be specified to indicate where the certificates should be stored: -```toml +```toml tab="TOML" [[tls.certificates]] - stores = ["default"] certFile = "/path/to/domain.cert" keyFile = "/path/to/domain.key" + stores = ["default"] [[tls.certificates]] # Note that since no store is defined, @@ -57,6 +72,19 @@ In the `[[tls.certificates]]` section, a list of stores can then be specified to keyFile = "/path/to/other-domain.key" ``` +```yaml tab="YAML" +tls: + certificates: + - certFile: /path/to/domain.cert + keyFile: /path/to/domain.key + stores: + - default + # Note that since no store is defined, + # the certificate below will be stored in the `default` store. + - certFile: /path/to/other-domain.cert + keyFile: /path/to/other-domain.key +``` + !!! important "Alpha restriction" During the alpha version, the `stores` list will actually be ignored and automatically set to `["default"]`. @@ -66,7 +94,7 @@ In the `[[tls.certificates]]` section, a list of stores can then be specified to Traefik can use a default certificate for connections without a SNI, or without a matching domain. This default certificate should be defined in a TLS store: -```toml +```toml tab="TOML" [tls.stores] [tls.stores.default] [tls.stores.default.defaultCertificate] @@ -74,6 +102,15 @@ This default certificate should be defined in a TLS store: keyFile = "path/to/cert.key" ``` +```yaml tab="YAML" +tls: + stores: + default: + defaultCertificate: + certFile: path/to/cert.crt + keyFile: path/to/cert.key +``` + If no default certificate is provided, Traefik generates and uses a self-signed certificate. ## TLS Options @@ -82,7 +119,7 @@ The TLS options allow one to configure some parameters of the TLS connection. ### Minimum TLS Version -```toml +```toml tab="TOML" [tls.options] [tls.options.default] @@ -92,6 +129,16 @@ The TLS options allow one to configure some parameters of the TLS connection. minVersion = "VersionTLS13" ``` +```yaml tab="YAML" +tls: + options: + default: + minVersion: VersionTLS12 + + mintls13: + minVersion: VersionTLS13 +``` + ### Mutual Authentication Traefik supports both optional and strict (which is the default) mutual authentication, though the `ClientCA.files` section. @@ -102,20 +149,32 @@ For clients with a certificate, the `optional` option governs the behaviour as f - When `optional = false`, Traefik accepts connections only from clients presenting a certificate signed by a CA listed in `ClientCA.files`. - When `optional = true`, Traefik authorizes connections from clients presenting a certificate signed by an unknown CA. -```toml +```toml tab="TOML" [tls.options] [tls.options.default] - [tls.options.default.ClientCA] + [tls.options.default.clientCA] # in PEM format. each file can contain multiple CAs. files = ["tests/clientca1.crt", "tests/clientca2.crt"] optional = false ``` +```yaml tab="YAML" +tls: + options: + default: + clientCA: + # in PEM format. each file can contain multiple CAs. + files: + - tests/clientca1.crt + - tests/clientca2.crt + optional: false +``` + ### Cipher Suites See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more information. -```toml +```toml tab="TOML" [tls.options] [tls.options.default] cipherSuites = [ @@ -124,13 +183,29 @@ See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more informat ] ``` +```yaml tab="YAML" +tls: + options: + default: + cipherSuites: + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_RSA_WITH_AES_256_GCM_SHA384 +``` + ### Strict SNI Checking With strict SNI checking, Traefik won't allow connections from clients connections that do not specify a server_name extension. -```toml +```toml tab="TOML" [tls.options] [tls.options.default] sniStrict = true ``` + +```yaml tab="YAML" +tls: + options: + default: + sniStrict: true +``` diff --git a/docs/content/middlewares/addprefix.md b/docs/content/middlewares/addprefix.md index 5f3ce6298..0c3ffe998 100644 --- a/docs/content/middlewares/addprefix.md +++ b/docs/content/middlewares/addprefix.md @@ -41,8 +41,8 @@ labels: ```toml tab="File" # Prefixing with /foo [http.middlewares] - [http.middlewares.add-foo.AddPrefix] - prefix = "/foo" + [http.middlewares.add-foo.addPrefix] + prefix = "/foo" ``` ## Configuration Options diff --git a/docs/content/middlewares/basicauth.md b/docs/content/middlewares/basicauth.md index 45455f654..b132eec2c 100644 --- a/docs/content/middlewares/basicauth.md +++ b/docs/content/middlewares/basicauth.md @@ -47,7 +47,7 @@ labels: ```toml tab="File" # Declaring the user list [http.middlewares] - [http.middlewares.test-auth.basicauth] + [http.middlewares.test-auth.basicAuth] users = [ "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", @@ -61,7 +61,7 @@ labels: Passwords must be encoded using MD5, SHA1, or BCrypt. !!! tip - + Use `htpasswd` to generate the passwords. ### `users` @@ -120,7 +120,7 @@ spec: ``` ```toml tab="File" -[http.middlewares.my-auth.basicauth] +[http.middlewares.my-auth.basicAuth] # ... headerField = "X-WebAuth-User" ``` diff --git a/docs/content/middlewares/buffering.md b/docs/content/middlewares/buffering.md index ce76b6599..c29ec3991 100644 --- a/docs/content/middlewares/buffering.md +++ b/docs/content/middlewares/buffering.md @@ -46,7 +46,7 @@ labels: # Sets the maximum request body to 2Mb [http.middlewares] [http.middlewares.limit.buffering] - maxRequestBodyBytes = 250000 + maxRequestBodyBytes = 250000 ``` ## Configuration Options diff --git a/docs/content/middlewares/chain.md b/docs/content/middlewares/chain.md index 79d5444a4..09b16ad95 100644 --- a/docs/content/middlewares/chain.md +++ b/docs/content/middlewares/chain.md @@ -111,27 +111,27 @@ labels: ```toml tab="File" # ... [http.routers] - [http.routers.router1] - service = "service1" - middlewares = ["secured"] - rule = "Host(`mydomain`)" + [http.routers.router1] + service = "service1" + middlewares = ["secured"] + rule = "Host(`mydomain`)" [http.middlewares] - [http.middlewares.secured.Chain] - middlewares = ["https-only", "known-ips", "auth-users"] + [http.middlewares.secured.chain] + middlewares = ["https-only", "known-ips", "auth-users"] - [http.middlewares.auth-users.BasicAuth] - users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] + [http.middlewares.auth-users.basicAuth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] - [http.middlewares.https-only.redirectScheme] - scheme = "https" + [http.middlewares.https-only.redirectScheme] + scheme = "https" - [http.middlewares.known-ips.ipWhiteList] - sourceRange = ["192.168.1.7", "127.0.0.1/32"] + [http.middlewares.known-ips.ipWhiteList] + sourceRange = ["192.168.1.7", "127.0.0.1/32"] [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://127.0.0.1:80" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "http://127.0.0.1:80" ``` diff --git a/docs/content/middlewares/circuitbreaker.md b/docs/content/middlewares/circuitbreaker.md index 1a970c24a..1d837a5ed 100644 --- a/docs/content/middlewares/circuitbreaker.md +++ b/docs/content/middlewares/circuitbreaker.md @@ -55,8 +55,8 @@ labels: ```toml tab="File" # Latency Check [http.middlewares] - [http.middlewares.latency-check.circuitBreaker] - expression = "LatencyAtQuantileMS(50.0) > 100" + [http.middlewares.latency-check.circuitBreaker] + expression = "LatencyAtQuantileMS(50.0) > 100" ``` ## Possible States @@ -66,7 +66,7 @@ There are three possible states for your circuit breaker: - Close (your service operates normally) - Open (the fallback mechanism takes over your service) - Recovering (the circuit breaker tries to resume normal operations by progressively sending requests to your service) - + ### Close While close, the circuit breaker only collects metrics to analyze the behavior of the requests. @@ -95,7 +95,7 @@ The `expression` can check three different metrics: - The network error ratio (`NetworkErrorRatio`) - The status code ratio (`ResponseCodeRatio`) - The latency at quantile, in milliseconds (`LatencyAtQuantileMS`) - + #### `NetworkErrorRatio` If you want the circuit breaker to trigger at a 30% ratio of network errors, the expression will be `NetworkErrorRatio() > 0.30` @@ -151,7 +151,7 @@ Here is the list of supported operators: ### Fallback mechanism The fallback mechanism returns a `HTTP 503 Service Unavailable` to the client (instead of calling the target service). This behavior cannot be configured. - + ### `CheckPeriod` The interval used to evaluate `expression` and decide if the state of the circuit breaker must change. By default, `CheckPeriod` is 100Ms. This value cannot be configured. diff --git a/docs/content/middlewares/compress.md b/docs/content/middlewares/compress.md index eb1531a44..67d0b7b08 100644 --- a/docs/content/middlewares/compress.md +++ b/docs/content/middlewares/compress.md @@ -40,7 +40,7 @@ labels: ```toml tab="File" # Enable gzip compression [http.middlewares] - [http.middlewares.test-compress.Compress] + [http.middlewares.test-compress.compress] ``` ## Notes diff --git a/docs/content/middlewares/digestauth.md b/docs/content/middlewares/digestauth.md index 70b6a97a6..d0d00d22b 100644 --- a/docs/content/middlewares/digestauth.md +++ b/docs/content/middlewares/digestauth.md @@ -53,7 +53,7 @@ labels: ## Configuration Options -### `Users` +### `users` The `users` option is an array of authorized users. Each user will be declared using the `name:realm:encoded-password` format. @@ -61,7 +61,7 @@ The `users` option is an array of authorized users. Each user will be declared u If both `users` and `usersFile` are provided, the two are merged. The content of `usersFile` has precedence over `users`. -### `UsersFile` +### `usersFile` The `usersFile` option is the path to an external file that contains the authorized users for the middleware. @@ -78,11 +78,11 @@ The file content is a list of `name:realm:encoded-password`. If both `users` and `usersFile` are provided, the two are merged. The content of `usersFile` has precedence over `users`. -### `Realm` +### `realm` You can customize the realm for the authentication with the `realm` option. The default value is `traefik`. -### `HeaderField` +### `headerField` You can customize the header field for the authenticated user using the `headerField`option. @@ -121,6 +121,6 @@ labels: headerField = "X-WebAuth-User" ``` -### `RemoveHeader` +### `removeHeader` Set the `removeHeader` option to `true` to remove the authorization header before forwarding the request to your service. (Default value is `false`.) diff --git a/docs/content/middlewares/errorpages.md b/docs/content/middlewares/errorpages.md index 6e4b21c1f..601d73b5c 100644 --- a/docs/content/middlewares/errorpages.md +++ b/docs/content/middlewares/errorpages.md @@ -52,7 +52,7 @@ labels: ```toml tab="File" # Custom Error Page for 5XX [http.middlewares] - [http.middlewares.test-errorpage.Errors] + [http.middlewares.test-errorpage.errors] status = ["500-599"] service = "serviceError" query = "/{status}.html" diff --git a/docs/content/middlewares/forwardauth.md b/docs/content/middlewares/forwardauth.md index 63fc37c44..7c96bbd9b 100644 --- a/docs/content/middlewares/forwardauth.md +++ b/docs/content/middlewares/forwardauth.md @@ -14,14 +14,14 @@ Otherwise, the response from the authentication server is returned. ```yaml tab="Docker" # Forward authentication to authserver.com labels: -- "traefik.http.middlewares.test-auth.ForwardAuth.Address=https://authserver.com/auth" -- "traefik.http.middlewares.test-auth.ForwardAuth.AuthResponseHeaders=X-Auth-User, X-Secret" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.CA=path/to/local.crt" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.CAOptional=true" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.Cert=path/to/foo.cert" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.InsecureSkipVerify=true" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.Key=path/to/foo.key" -- "traefik.http.middlewares.test-auth.ForwardAuth.TrustForwardHeader=true" +- "traefik.http.middlewares.test-auth.forwardauth.address=https://authserver.com/auth" +- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret" +- "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt" +- "traefik.http.middlewares.test-auth.forwardauth.tls.caOptional=true" +- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert" +- "traefik.http.middlewares.test-auth.forwardauth.tls.insecureSkipVerify=true" +- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" +- "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true" ``` ```yaml tab="Kubernetes" @@ -45,28 +45,28 @@ spec: ```json tab="Marathon" "labels": { - "traefik.http.middlewares.test-auth.ForwardAuth.Address": "https://authserver.com/auth", - "traefik.http.middlewares.test-auth.ForwardAuth.AuthResponseHeaders": "X-Auth-User,X-Secret", - "traefik.http.middlewares.test-auth.ForwardAuth.TLS.CA": "path/to/local.crt", - "traefik.http.middlewares.test-auth.ForwardAuth.TLS.CAOptional": "true", - "traefik.http.middlewares.test-auth.ForwardAuth.TLS.Cert": "path/to/foo.cert", - "traefik.http.middlewares.test-auth.ForwardAuth.TLS.InsecureSkipVerify": "true", - "traefik.http.middlewares.test-auth.ForwardAuth.TLS.Key": "path/to/foo.key", - "traefik.http.middlewares.test-auth.ForwardAuth.TrustForwardHeader": "true" + "traefik.http.middlewares.test-auth.forwardauth.address": "https://authserver.com/auth", + "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders": "X-Auth-User,X-Secret", + "traefik.http.middlewares.test-auth.forwardauth.tls.ca": "path/to/local.crt", + "traefik.http.middlewares.test-auth.forwardauth.tls.caOptional": "true", + "traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert", + "traefik.http.middlewares.test-auth.forwardauth.tls.insecureSkipVerify": "true", + "traefik.http.middlewares.test-auth.forwardauth.tls.key": "path/to/foo.key", + "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader": "true" } ``` ```yaml tab="Rancher" # Forward authentication to authserver.com labels: -- "traefik.http.middlewares.test-auth.ForwardAuth.Address=https://authserver.com/auth" -- "traefik.http.middlewares.test-auth.ForwardAuth.AuthResponseHeaders=X-Auth-User, X-Secret" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.CA=path/to/local.crt" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.CAOptional=true" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.Cert=path/to/foo.cert" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.InsecureSkipVerify=true" -- "traefik.http.middlewares.test-auth.ForwardAuth.TLS.Key=path/to/foo.key" -- "traefik.http.middlewares.test-auth.ForwardAuth.TrustForwardHeader=true" +- "traefik.http.middlewares.test-auth.forwardauth.address=https://authserver.com/auth" +- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret" +- "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt" +- "traefik.http.middlewares.test-auth.forwardauth.tls.caOptional=true" +- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert" +- "traefik.http.middlewares.test-auth.forwardauth.tls.InisecureSkipVerify=true" +- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" +- "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true" ``` ```toml tab="File" @@ -77,7 +77,7 @@ labels: trustForwardHeader = true authResponseHeaders = ["X-Auth-User", "X-Secret"] - [http.middlewares.test-auth.forwardauth.tls] + [http.middlewares.test-auth.forwardAuth.tls] ca = "path/to/local.crt" caOptional = true cert = "path/to/foo.cert" @@ -92,7 +92,7 @@ The `address` option defines the authentication server address. ### `trustForwardHeader` -Set the `trustForwardHeader` option to true to trust all the existing X-Forwarded-* headers. +Set the `trustForwardHeader` option to `true` to trust all the existing `X-Forwarded-*` headers. ### `authResponseHeaders` @@ -100,4 +100,4 @@ The `authResponseHeaders` option is the list of the headers to copy from the aut ### `tls` -The `tls` option is the tls configuration from Traefik to the authentication server. +The `tls` option is the TLS configuration from Traefik to the authentication server. diff --git a/docs/content/middlewares/headers.md b/docs/content/middlewares/headers.md index 23528b3e2..716d49525 100644 --- a/docs/content/middlewares/headers.md +++ b/docs/content/middlewares/headers.md @@ -15,8 +15,8 @@ Add the `X-Script-Name` header to the proxied request and the `X-Custom-Response ```yaml tab="Docker" labels: -- "traefik.http.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name=test" -- "traefik.http.middlewares.testHeader.Headers.CustomResponseHeaders.X-Custom-Response-Header=True" +- "traefik.http.middlewares.testHeader.headers.customrequestheaders.X-Script-Name=test" +- "traefik.http.middlewares.testHeader.headers.customresponseheaders.X-Custom-Response-Header=True" ``` ```yaml tab="Kubernetes" @@ -34,23 +34,23 @@ spec: ```json tab="Marathon" "labels": { - "traefik.http.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name": "test", - "traefik.http.middlewares.testHeader.Headers.CustomResponseHeaders.X-Custom-Response-Header": "True" + "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test", + "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header": "True" } ``` ```yaml tab="Rancher" labels: -- "traefik.http.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name=test" -- "traefik.http.middlewares.testHeader.Headers.CustomResponseHeaders.X-Custom-Response-Header=True" +- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test" +- "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=True" ``` ```toml tab="File" [http.middlewares] [http.middlewares.testHeader.headers] - [http.middlewares.testHeader.headers.CustomRequestHeaders] + [http.middlewares.testHeader.headers.customRequestHeaders] X-Script-Name = "test" - [http.middlewares.testHeader.headers.CustomResponseHeaders] + [http.middlewares.testHeader.headers.customResponseHeaders] X-Custom-Response-Header = "True" ``` @@ -77,22 +77,22 @@ spec: ```yaml tab="Rancher" labels: - - "traefik.http.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name=test" + - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test" ``` ```json tab="Marathon" "labels": { - "traefik.http.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name": "test", + "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test", } ``` ```toml tab="File" [http.middlewares] [http.middlewares.testHeader.headers] - [http.middlewares.testHeader.headers.CustomRequestHeaders] + [http.middlewares.testHeader.headers.customRequestHeaders] X-Script-Name = "test" # Adds X-Custom-Request-Header = "" # Removes - [http.middlewares.testHeader.headers.CustomResponseHeaders] + [http.middlewares.testHeader.headers.customResponseHeaders] X-Custom-Response-Header = "" # Removes ``` @@ -103,8 +103,8 @@ This functionality allows for some easy security features to quickly be set. ```yaml tab="Docker" labels: - - "traefik.http.middlewares.testHeader.Headers.FrameDeny=true" - - "traefik.http.middlewares.testHeader.Headers.SSLRedirect=true" + - "traefik.http.middlewares.testHeader.headers.framedeny=true" + - "traefik.http.middlewares.testHeader.headers.sslredirect=true" ``` ```yaml tab="Kubernetes" @@ -120,14 +120,14 @@ spec: ```yaml tab="Rancher" labels: - - "traefik.http.middlewares.testHeader.Headers.FrameDeny=true" - - "traefik.http.middlewares.testHeader.Headers.SSLRedirect=true" + - "traefik.http.middlewares.testheader.headers.framedeny=true" + - "traefik.http.middlewares.testheader.headers.sslredirect=true" ``` ```json tab="Marathon" "labels": { - "traefik.http.middlewares.testHeader.Headers.FrameDeny": "true", - "traefik.http.middlewares.testHeader.Headers.SSLRedirect": "true" + "traefik.http.middlewares.testheader.headers.framedeny": "true", + "traefik.http.middlewares.testheader.headers.sslredirect": "true" } ``` @@ -145,10 +145,10 @@ This functionality allows for more advanced security features to quickly be set. ```yaml tab="Docker" labels: - - "traefik.http.middlewares.testHeader.Headers.AccessControlAllowMethods=GET,OPTIONS,PUT" - - "traefik.http.middlewares.testHeader.Headers.AccessControlAllowOrigin=origin-list-or-null" - - "traefik.http.middlewares.testHeader.Headers.AccessControlMaxAge=100" - - "traefik.http.middlewares.testHeader.Headers.AddVaryHeader=true" + - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT" + - "traefik.http.middlewares.testheader.headers.accesscontrolalloworigin=origin-list-or-null" + - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100" + - "traefik.http.middlewares.testheader.headers.addvaryheader=true" ``` ```yaml tab="Kubernetes" @@ -158,39 +158,39 @@ metadata: name: testHeader spec: headers: - AccessControlAllowMethods: + accessControlAllowMethods: - "GET" - "OPTIONS" - "PUT" - AccessControlAllowOrigin: "origin-list-or-null" - AccessControlMaxAge: 100 - AddVaryHeader: "true" + accessControlAllowOrigin: "origin-list-or-null" + accessControlMaxAge: 100 + addVaryHeader: "true" ``` ```yaml tab="Rancher" labels: - - "traefik.http.middlewares.testHeader.Headers.AccessControlAllowMethods=GET,OPTIONS,PUT" - - "traefik.http.middlewares.testHeader.Headers.AccessControlAllowOrigin=origin-list-or-null" - - "traefik.http.middlewares.testHeader.Headers.AccessControlMaxAge=100" - - "traefik.http.middlewares.testHeader.Headers.AddVaryHeader=true" + - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT" + - "traefik.http.middlewares.testheader.headers.accesscontrolalloworigin=origin-list-or-null" + - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100" + - "traefik.http.middlewares.testheader.headers.addvaryheader=true" ``` ```json tab="Marathon" "labels": { - "traefik.http.middlewares.testHeader.Headers.AccessControlAllowMethods": "GET,OPTIONS,PUT", - "traefik.http.middlewares.testHeader.Headers.AccessControlAllowOrigin": "origin-list-or-null", - "traefik.http.middlewares.testHeader.Headers.AccessControlMaxAge": "100", - "traefik.http.middlewares.testHeader.Headers.AddVaryHeader": "true" + "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods": "GET,OPTIONS,PUT", + "traefik.http.middlewares.testheader.headers.accesscontrolalloworigin": "origin-list-or-null", + "traefik.http.middlewares.testheader.headers.accesscontrolmaxage": "100", + "traefik.http.middlewares.testheader.headers.addvaryheader": "true" } ``` ```toml tab="File" [http.middlewares] [http.middlewares.testHeader.headers] - AccessControlAllowMethods= ["GET", "OPTIONS", "PUT"] - AccessControlAllowOrigin = "origin-list-or-null" - AccessControlMaxAge = 100 - AddVaryHeader = true + accessControlAllowMethods= ["GET", "OPTIONS", "PUT"] + accessControlAllowOrigin = "origin-list-or-null" + accessControlMaxAge = 100 + addVaryHeader = true ``` ## Configuration Options @@ -225,7 +225,8 @@ The `accessControlAllowMethods` indicates which methods can be used during requ ### `accessControlAllowOrigin` -The `accessControlAllowOrigin` indicates whether a resource can be shared by returning different values. The three options for this value are: +The `accessControlAllowOrigin` indicates whether a resource can be shared by returning different values. +The three options for this value are: - `origin-list-or-null` - `*` @@ -261,11 +262,12 @@ Set the `sslTemporaryRedirect` to `true` to force an SSL redirection using a 302 ### `sslHost` -The `SSLHost` option is the host name that is used to redirect http requests to https. +The `sslHost` option is the host name that is used to redirect http requests to https. ### `sslProxyHeaders` -The `sslProxyHeaders` option is set of header keys with associated values that would indicate a valid https request. Useful when using other proxies with header like: `"X-Forwarded-Proto": "https"`. +The `sslProxyHeaders` option is set of header keys with associated values that would indicate a valid https request. +Useful when using other proxies with header like: `"X-Forwarded-Proto": "https"`. ### `sslForceHost` @@ -273,7 +275,8 @@ Set `sslForceHost` to true and set SSLHost to forced requests to use `SSLHost` e ### `stsSeconds` -The `stsSeconds` is the max-age of the Strict-Transport-Security header. If set to 0, would NOT include the header. +The `stsSeconds` is the max-age of the Strict-Transport-Security header. +If set to 0, would NOT include the header. ### `stsIncludeSubdomains` @@ -281,11 +284,11 @@ The `stsIncludeSubdomains` is set to true, the `includeSubdomains` will be appen ### `stsPreload` -Set `STSPreload` to true to have the `preload` flag appended to the Strict-Transport-Security header. +Set `stsPreload` to true to have the `preload` flag appended to the Strict-Transport-Security header. ### `forceSTSHeader` -Set `ForceSTSHeader` to true, to add the STS header even when the connection is HTTP. +Set `forceSTSHeader` to true, to add the STS header even when the connection is HTTP. ### `frameDeny` @@ -293,7 +296,8 @@ Set `frameDeny` to true to add the `X-Frame-Options` header with the value of `D ### `customFrameOptionsValue` -The `customFrameOptionsValue` allows the `X-Frame-Options` header value to be set with a custom value. This overrides the FrameDeny option. +The `customFrameOptionsValue` allows the `X-Frame-Options` header value to be set with a custom value. +This overrides the FrameDeny option. ### `contentTypeNosniff` @@ -301,11 +305,12 @@ Set `contentTypeNosniff` to true to add the `X-Content-Type-Options` header with ### `browserXssFilter` -Set `BrowserXssFilter` to true to add the `X-XSS-Protection` header with the value `1; mode=block`. +Set `browserXssFilter` to true to add the `X-XSS-Protection` header with the value `1; mode=block`. ### `customBrowserXSSValue` -The `customBrowserXssValue` option allows the `X-XSS-Protection` header value to be set with a custom value. This overrides the BrowserXssFilter option. +The `customBrowserXssValue` option allows the `X-XSS-Protection` header value to be set with a custom value. +This overrides the BrowserXssFilter option. ### `contentSecurityPolicy` @@ -321,5 +326,7 @@ The `referrerPolicy` allows sites to control when browsers will pass the Referer ### `isDevelopment` -Set `isDevelopment` to true when developing. The AllowedHosts, SSL, and STS options can cause some unwanted effects. Usually testing happens on http, not https, and on localhost, not your production domain. +Set `isDevelopment` to true when developing. +The AllowedHosts, SSL, and STS options can cause some unwanted effects. +Usually testing happens on http, not https, and on localhost, not your production domain. If you would like your development environment to mimic production with complete Host blocking, SSL redirects, and STS headers, leave this as false. diff --git a/docs/content/middlewares/ipwhitelist.md b/docs/content/middlewares/ipwhitelist.md index 1d038eaa8..c39e42b54 100644 --- a/docs/content/middlewares/ipwhitelist.md +++ b/docs/content/middlewares/ipwhitelist.md @@ -12,7 +12,7 @@ IPWhitelist accepts / refuses requests based on the client IP. ```yaml tab="Docker" # Accepts request from defined IP labels: -- "traefik.http.middlewares.test-ipwhitelist.IPWhiteList.SourceRange=127.0.0.1/32, 192.168.1.7" +- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7" ``` ```yaml tab="Kubernetes" @@ -29,14 +29,14 @@ spec: ```json tab="Marathon" "labels": { - "traefik.http.middlewares.test-ipwhitelist.IPWhiteList.SourceRange": "127.0.0.1/32,192.168.1.7" + "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange": "127.0.0.1/32,192.168.1.7" } ``` ```yaml tab="Rancher" # Accepts request from defined IP labels: -- "traefik.http.middlewares.test-ipwhitelist.IPWhiteList.SourceRange=127.0.0.1/32, 192.168.1.7" +- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7" ``` ```toml tab="File" @@ -75,7 +75,7 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th ```yaml tab="Docker" # Whitelisting Based on `X-Forwarded-For` with `depth=2` labels: - - "traefik.http.middlewares.testIPwhitelist.ipWhiteList.SourceRange=127.0.0.1/32, 192.168.1.7" + - "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7" - "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2" ``` @@ -87,23 +87,23 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th name: testIPwhitelist spec: ipWhiteList: - SourceRange: + sourceRange: - 127.0.0.1/32 - 192.168.1.7 - ipstrategy: + ipStrategy: depth: 2 ``` ```yaml tab="Rancher" # Whitelisting Based on `X-Forwarded-For` with `depth=2` labels: - - "traefik.http.middlewares.testIPwhitelist.ipWhiteList.SourceRange=127.0.0.1/32, 192.168.1.7" + - "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7" - "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2" ``` ```json tab="Marathon" "labels": { - "traefik.http.middlewares.testIPwhitelist.ipWhiteList.SourceRange": "127.0.0.1/32, 192.168.1.7", + "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange": "127.0.0.1/32, 192.168.1.7", "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth": "2" } ``` @@ -114,7 +114,7 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th [http.middlewares.test-ipwhitelist.ipWhiteList] sourceRange = ["127.0.0.1/32", "192.168.1.7"] [http.middlewares.test-ipwhitelist.ipWhiteList.ipStrategy] - depth = 2 + depth = 2 ``` !!! note @@ -142,7 +142,7 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th ```yaml tab="Docker" # Exclude from `X-Forwarded-For` labels: - - "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedIPs=127.0.0.1/32, 192.168.1.7" + - "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" ``` ```yaml tab="Kubernetes" @@ -153,7 +153,7 @@ metadata: name: test-ipwhitelist spec: ipWhiteList: - ipstrategy: + ipStrategy: excludedIPs: - 127.0.0.1/32 - 192.168.1.7 @@ -162,12 +162,12 @@ spec: ```yaml tab="Rancher" # Exclude from `X-Forwarded-For` labels: - - "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedIPs=127.0.0.1/32, 192.168.1.7" + - "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" ``` ```json tab="Marathon" "labels": { - "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedIPs": "127.0.0.1/32, 192.168.1.7" + "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7" } ``` diff --git a/docs/content/middlewares/maxconnection.md b/docs/content/middlewares/maxconnection.md index 6c13363d0..b0523d790 100644 --- a/docs/content/middlewares/maxconnection.md +++ b/docs/content/middlewares/maxconnection.md @@ -40,8 +40,8 @@ labels: ```toml tab="File" # Limiting to 10 simultaneous connections [http.middlewares] - [http.middlewares.test-maxconn.maxconn] - amount = 10 + [http.middlewares.test-maxconn.maxConn] + amount = 10 ``` ## Configuration Options diff --git a/docs/content/middlewares/overview.md b/docs/content/middlewares/overview.md index 335a824ca..102f10d03 100644 --- a/docs/content/middlewares/overview.md +++ b/docs/content/middlewares/overview.md @@ -22,7 +22,7 @@ whoami: # Create a middleware named `foo-add-prefix` - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo" # Apply the middleware named `foo-add-prefix` to the router named `router1` - - "traefik.http.router.router1.Middlewares=foo-add-prefix@docker" + - "traefik.http.router.router1.middlewares=foo-add-prefix@docker" ``` ```yaml tab="Kubernetes" @@ -46,7 +46,7 @@ kind: Middleware metadata: name: stripprefix spec: - stripprefix: + stripPrefix: prefixes: - /stripit @@ -66,7 +66,7 @@ spec: ```json tab="Marathon" "labels": { "traefik.http.middlewares.foo-add-prefix.addprefix.prefix": "/foo", - "traefik.http.router.router1.Middlewares": "foo-add-prefix@marathon" + "traefik.http.router.router1.middlewares": "foo-add-prefix@marathon" } ``` @@ -76,30 +76,30 @@ labels: # Create a middleware named `foo-add-prefix` - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo" # Apply the middleware named `foo-add-prefix` to the router named `router1` - - "traefik.http.router.router1.Middlewares=foo-add-prefix@rancher" + - "traefik.http.router.router1.middlewares=foo-add-prefix@rancher" ``` ```toml tab="File" # As Toml Configuration File [providers] - [providers.file] + [providers.file] [http.routers] [http.routers.router1] - Service = "myService" - Middlewares = ["foo-add-prefix"] - Rule = "Host(`example.com`)" + service = "myService" + middlewares = ["foo-add-prefix"] + rule = "Host(`example.com`)" [http.middlewares] - [http.middlewares.foo-add-prefix.AddPrefix] + [http.middlewares.foo-add-prefix.addPrefix] prefix = "/foo" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://127.0.0.1:80" + [[http.services.service1.loadBalancer.servers]] + url = "http://127.0.0.1:80" ``` ## Provider Namespace @@ -132,7 +132,7 @@ and therefore this specification would be ignored even if present. [providers.file] [http.middlewares] - [http.middlewares.add-foo-prefix.AddPrefix] + [http.middlewares.add-foo-prefix.addPrefix] prefix = "/foo" ``` diff --git a/docs/content/middlewares/passtlsclientcert.md b/docs/content/middlewares/passtlsclientcert.md index ed4c073a9..4824845b5 100644 --- a/docs/content/middlewares/passtlsclientcert.md +++ b/docs/content/middlewares/passtlsclientcert.md @@ -23,7 +23,7 @@ kind: Middleware metadata: name: addprefix spec: - passtlsclientcert: + passTLSClientCert: pem: true ``` @@ -42,7 +42,7 @@ labels: ```toml tab="File" # Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header. [http.middlewares] - [http.middlewares.test-passtlsclientcert.passtlsclientcert] + [http.middlewares.test-passtlsclientcert.passTLSClientCert] pem = true ``` @@ -77,7 +77,7 @@ labels: metadata: name: test-passtlsclientcert spec: - passtlsclientcert: + passTLSClientCert: info: notAfter: true notBefore: true @@ -147,12 +147,12 @@ labels: ```toml tab="File" # Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header [http.middlewares] - [http.middlewares.test-passtlsclientcert.passtlsclientcert] - [http.middlewares.test-passtlsclientcert.passtlsclientcert.info] + [http.middlewares.test-passtlsclientcert.passTLSClientCert] + [http.middlewares.test-passtlsclientcert.passTLSClientCert.info] notAfter = true notBefore = true sans = true - [http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject] + [http.middlewares.test-passtlsclientcert.passTLSClientCert.info.subject] country = true province = true locality = true @@ -160,7 +160,7 @@ labels: commonName = true serialNumber = true domainComponent = true - [http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer] + [http.middlewares.test-passtlsclientcert.passTLSClientCert.info.issuer] country = true province = true locality = true @@ -360,9 +360,9 @@ Subject="DC=org,DC=cheese,C=FR,C=US,ST=Cheese org state,ST=Cheese com state,L=TO If there are more than one certificate, they are separated by a `;`. -#### `info.notafter` +#### `info.notAfter` -Set the `info.notafter` option to `true` to add the `Not After` information from the `Validity` part. +Set the `info.notAfter` option to `true` to add the `Not After` information from the `Validity` part. The data are taken from the following certificate part: @@ -371,15 +371,15 @@ The data are taken from the following certificate part: Not After : Dec 5 11:10:16 2020 GMT ``` -The escape `notafter` info part will be like: +The escape `notAfter` info part will be like: ```text NA=1607166616 ``` -#### `info.notbefore` +#### `info.notBefore` -Set the `info.notafter` option to `true` to add the `Not Before` information from the `Validity` part. +Set the `info.notBefore` option to `true` to add the `Not Before` information from the `Validity` part. The data are taken from the following certificate part: @@ -388,7 +388,7 @@ Validity Not Before: Dec 6 11:10:16 2018 GMT ``` -The escape `notafter` info part will be like: +The escape `notBefore` info part will be like: ```text NB=1544094616 @@ -471,9 +471,9 @@ The escape organization info in the subject part will be like : O=Cheese,O=Cheese 2 ``` -##### `info.subject.commonname` +##### `info.subject.commonName` -Set the `info.subject.commonname` option to true to add the `commonname` information into the subject. +Set the `info.subject.commonName` option to true to add the `commonName` information into the subject. The data are taken from the subject part with the `CN` key. @@ -483,9 +483,9 @@ The escape common name info in the subject part will be like : CN=*.cheese.com ``` -##### `info.subject.serialnumber` +##### `info.subject.serialNumber` -Set the `info.subject.serialnumber` option to true to add the `serialnumber` information into the subject. +Set the `info.subject.serialNumber` option to true to add the `serialNumber` information into the subject. The data are taken from the subject part with the `SN` key. @@ -495,9 +495,9 @@ The escape serial number info in the subject part will be like : SN=1234567890 ``` -##### `info.subject.domaincomponent` +##### `info.subject.domainComponent` -Set the `info.subject.domaincomponent` option to true to add the `domaincomponent` information into the subject. +Set the `info.subject.domainComponent` option to true to add the `domainComponent` information into the subject. The data are taken from the subject part with the `DC` key. @@ -563,9 +563,9 @@ The escape organization info in the issuer part will be like : O=Cheese,O=Cheese 2 ``` -##### `info.issuer.commonname` +##### `info.issuer.commonName` -Set the `info.issuer.commonname` option to true to add the `commonname` information into the issuer. +Set the `info.issuer.commonName` option to true to add the `commonName` information into the issuer. The data are taken from the issuer part with the `CN` key. @@ -575,9 +575,9 @@ The escape common name info in the issuer part will be like : CN=Simple Signing CA 2 ``` -##### `info.issuer.serialnumber` +##### `info.issuer.serialNumber` -Set the `info.issuer.serialnumber` option to true to add the `serialnumber` information into the issuer. +Set the `info.issuer.serialNumber` option to true to add the `serialNumber` information into the issuer. The data are taken from the issuer part with the `SN` key. @@ -587,9 +587,9 @@ The escape serial number info in the issuer part will be like : SN=1234567890 ``` -##### `info.issuer.domaincomponent` +##### `info.issuer.domainComponent` -Set the `info.issuer.domaincomponent` option to true to add the `domaincomponent` information into the issuer. +Set the `info.issuer.domainComponent` option to true to add the `domainComponent` information into the issuer. The data are taken from the issuer part with the `DC` key. diff --git a/docs/content/middlewares/ratelimit.md b/docs/content/middlewares/ratelimit.md index 29add7f32..65dbc84ba 100644 --- a/docs/content/middlewares/ratelimit.md +++ b/docs/content/middlewares/ratelimit.md @@ -33,7 +33,7 @@ metadata: spec: rateLimit: extractorFunc: client.ip - rateset: + rateSet: rate0: period: 10s average: 100 @@ -74,15 +74,15 @@ labels: # Here, an average of 5 requests every 3 seconds is allowed and an average of 100 requests every 10 seconds. # These can "burst" up to 10 and 200 in each period, respectively. [http.middlewares] - [http.middlewares.test-ratelimit.ratelimit] + [http.middlewares.test-ratelimit.rateLimit] extractorfunc = "client.ip" - [http.middlewares.test-ratelimit.ratelimit.rateset.rate0] + [http.middlewares.test-ratelimit.rateLimit.rateSet.rate0] period = "10s" average = 100 burst = 200 - [http.middlewares.test-ratelimit.ratelimit.rateset.rate1] + [http.middlewares.test-ratelimit.rateLimit.rateSet.rate1] period = "3s" average = 5 burst = 10 @@ -100,7 +100,7 @@ The possible values are: - `client.ip` categorizes requests based on the client ip. - `request.header.ANY_HEADER` categorizes requests based on the provided `ANY_HEADER` value. -### `ratelimit` +### `rateSet` You can combine multiple rate limits. The rate limit will trigger with the first reached limit. diff --git a/docs/content/middlewares/redirectregex.md b/docs/content/middlewares/redirectregex.md index 5fcd90652..6a1d89255 100644 --- a/docs/content/middlewares/redirectregex.md +++ b/docs/content/middlewares/redirectregex.md @@ -45,7 +45,7 @@ labels: ```toml tab="File" # Redirect with domain replacement [http.middlewares] - [http.middlewares.test-redirectregex.redirectregex] + [http.middlewares.test-redirectregex.redirectRegex] regex = "^http://localhost/(.*)" replacement = "http://mydomain/$1" ``` @@ -58,7 +58,7 @@ Set the `permanent` option to `true` to apply a permanent redirection. ### `regex` -The `Regex` option is the regular expression to match and capture elements from the request URL. +The `regex` option is the regular expression to match and capture elements from the request URL. !!! warning diff --git a/docs/content/middlewares/redirectscheme.md b/docs/content/middlewares/redirectscheme.md index acf3f4279..d658e3c7b 100644 --- a/docs/content/middlewares/redirectscheme.md +++ b/docs/content/middlewares/redirectscheme.md @@ -41,7 +41,7 @@ labels: ```toml tab="File" # Redirect to https [http.middlewares] - [http.middlewares.test-redirectscheme.redirectscheme] + [http.middlewares.test-redirectscheme.redirectScheme] scheme = "https" ``` diff --git a/docs/content/middlewares/replacepath.md b/docs/content/middlewares/replacepath.md index 6270b8f9c..d8c1a771f 100644 --- a/docs/content/middlewares/replacepath.md +++ b/docs/content/middlewares/replacepath.md @@ -41,8 +41,8 @@ labels: ```toml tab="File" # Replace the path by /foo [http.middlewares] - [http.middlewares.test-replacepath.ReplacePath] - path = "/foo" + [http.middlewares.test-replacepath.replacePath] + path = "/foo" ``` ## Configuration Options diff --git a/docs/content/middlewares/replacepathregex.md b/docs/content/middlewares/replacepathregex.md index 2b977c3bb..3c8e242d9 100644 --- a/docs/content/middlewares/replacepathregex.md +++ b/docs/content/middlewares/replacepathregex.md @@ -61,7 +61,7 @@ The ReplacePathRegex middleware will: ### `regex` -The `Regex` option is the regular expression to match and capture the path from the request URL. +The `regex` option is the regular expression to match and capture the path from the request URL. !!! warning diff --git a/docs/content/middlewares/retry.md b/docs/content/middlewares/retry.md index 7cdd590b2..d07c0aebf 100644 --- a/docs/content/middlewares/retry.md +++ b/docs/content/middlewares/retry.md @@ -41,7 +41,7 @@ labels: ```toml tab="File" # Retry to send request 4 times [http.middlewares] - [http.middlewares.test-retry.Retry] + [http.middlewares.test-retry.retry] attempts = 4 ``` diff --git a/docs/content/middlewares/stripprefix.md b/docs/content/middlewares/stripprefix.md index 806687367..0b7ff50f7 100644 --- a/docs/content/middlewares/stripprefix.md +++ b/docs/content/middlewares/stripprefix.md @@ -43,8 +43,8 @@ labels: ```toml tab="File" # Strip prefix /foobar and /fiibar [http.middlewares] - [http.middlewares.test-stripprefix.StripPrefix] - prefixes = ["/foobar", "/fiibar"] + [http.middlewares.test-stripprefix.stripPrefix] + prefixes = ["/foobar", "/fiibar"] ``` ## Configuration Options diff --git a/docs/content/middlewares/stripprefixregex.md b/docs/content/middlewares/stripprefixregex.md index 484168e7f..e51e4ccdc 100644 --- a/docs/content/middlewares/stripprefixregex.md +++ b/docs/content/middlewares/stripprefixregex.md @@ -41,7 +41,7 @@ labels: ```toml tab="File" # Replace the path by /foo [http.middlewares] - [http.middlewares.test-stripprefixregex.StripPrefixRegex] + [http.middlewares.test-stripprefixregex.stripPrefixRegex] regex: "^/foo/(.*)" ``` @@ -56,7 +56,7 @@ The StripPrefixRegex middleware will: !!! tip - Use a `StripPrefixRegex` middleware if your backend listens on the root path (`/`) but should be routeable on a specific prefix. + Use a `stripPrefixRegex` middleware if your backend listens on the root path (`/`) but should be routeable on a specific prefix. ### `regex` diff --git a/docs/content/observability/tracing/datadog.md b/docs/content/observability/tracing/datadog.md index c32888391..5d68d399d 100644 --- a/docs/content/observability/tracing/datadog.md +++ b/docs/content/observability/tracing/datadog.md @@ -4,7 +4,7 @@ To enable the DataDog: ```toml tab="File" [tracing] - [tracing.datadog] + [tracing.dataDog] ``` ```bash tab="CLI" @@ -20,7 +20,7 @@ Local Agent Host Port instructs reporter to send spans to datadog-tracing-agent ```toml tab="File" [tracing] - [tracing.datadog] + [tracing.dataDog] localAgentHostPort = "127.0.0.1:8126" ``` @@ -37,7 +37,7 @@ Enable DataDog debug. ```toml tab="File" [tracing] - [tracing.datadog] + [tracing.dataDog] debug = true ``` @@ -54,7 +54,7 @@ Apply shared tag in a form of Key:Value to all the traces. ```toml tab="File" [tracing] - [tracing.datadog] + [tracing.dataDog] globalTag = "sample" ``` @@ -72,7 +72,7 @@ this option must be enabled in order to get all the parts of a distributed trace ```toml tab="File" [tracing] - [tracing.datadog] + [tracing.dataDog] prioritySampling = true ``` diff --git a/docs/content/operations/api.md b/docs/content/operations/api.md index 0bbf0a185..a7a4c41f1 100644 --- a/docs/content/operations/api.md +++ b/docs/content/operations/api.md @@ -128,19 +128,19 @@ You can define a custom address/port like this: ```toml [entryPoints] [entryPoints.web] - address = ":80" + address = ":80" [entryPoints.foo] - address = ":8082" + address = ":8082" [entryPoints.bar] - address = ":8083" + address = ":8083" [ping] -entryPoint = "foo" + entryPoint = "foo" [api] -entryPoint = "bar" + entryPoint = "bar" ``` In the above example, you would access a service at /foo, an api endpoint, or the health-check as follows: @@ -160,9 +160,9 @@ To restrict access to the API handler, one can add authentication with the [basi ```toml [http.middlewares] - [http.middlewares.api-auth.basicauth] - users = [ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - ] + [http.middlewares.api-auth.basicAuth] + users = [ + "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", + "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", + ] ``` diff --git a/docs/content/operations/dashboard.md b/docs/content/operations/dashboard.md index c8c4c02dc..a867c1976 100644 --- a/docs/content/operations/dashboard.md +++ b/docs/content/operations/dashboard.md @@ -10,13 +10,13 @@ The dashboard is the central place that shows you the current active routes hand Therefore, the dashboard is currently not working.
- Dashboard - Providers -
The dashboard in action with Traefik listening to 3 different providers
+ Dashboard - Providers +
The dashboard in action with Traefik listening to 3 different providers
- Dashboard - Health -
The dashboard shows the health of the system.
+ Dashboard - Health +
The dashboard shows the health of the system.
By default, the dashboard is available on `/` on port `:8080`. diff --git a/docs/content/operations/ping.md b/docs/content/operations/ping.md index 0cde3ec6e..694e220dd 100644 --- a/docs/content/operations/ping.md +++ b/docs/content/operations/ping.md @@ -22,7 +22,7 @@ Checking the Health of Your Traefik Instances address = ":8082" [ping] - entryPoint = "ping" + entryPoint = "ping" ``` | Path | Method | Description | diff --git a/docs/content/providers/docker.md b/docs/content/providers/docker.md index 3fc1daabc..fb25b14ea 100644 --- a/docs/content/providers/docker.md +++ b/docs/content/providers/docker.md @@ -18,7 +18,7 @@ Attach labels to your containers and let Traefik do the rest! ```toml [providers.docker] - endpoint = "unix:///var/run/docker.sock" + endpoint = "unix:///var/run/docker.sock" ``` Attaching labels to containers (in your docker compose file) @@ -136,8 +136,8 @@ Traefik requires access to the docker socket to get its dynamic configuration. ```toml # ... [providers] - [providers.docker] - endpoint = "unix:///var/run/docker.sock" + [providers.docker] + endpoint = "unix:///var/run/docker.sock" ``` ### `usebindportip` @@ -194,8 +194,8 @@ and the template has access to all the labels defined on this container. ```toml tab="File" [providers.docker] -defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" -# ... + defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" + # ... ``` ```txt tab="CLI" diff --git a/docs/content/providers/file.md b/docs/content/providers/file.md index 8a940b943..689238e05 100644 --- a/docs/content/providers/file.md +++ b/docs/content/providers/file.md @@ -45,7 +45,7 @@ You can write these configuration elements: # Add the middleware [http.middlewares] - [http.middlewares.my-basic-auth.BasicAuth] + [http.middlewares.my-basic-auth.basicAuth] users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] usersFile = "etc/traefik/.htpasswd" @@ -53,37 +53,42 @@ You can write these configuration elements: # Add the service [http.services] [http.services.service-foo] - [http.services.service-foo.LoadBalancer] - [[http.services.service-foo.LoadBalancer.Servers]] + [http.services.service-foo.loadBalancer] + [[http.services.service-foo.loadBalancer.servers]] url = "http://foo/" - [[http.services.service-foo.LoadBalancer.Servers]] + [[http.services.service-foo.loadBalancer.servers]] url = "http://bar/" ``` ```yaml tab="YAML" http: + # Add the router routers: router0: - entrypoints: + entryPoints: - web middlewares: - my-basic-auth service: service-foo rule: Path(`foo`) + + # Add the middleware middlewares: my-basic-auth: basicAuth: users: - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ - test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0 - usersfile: etc/traefik/.htpasswd - headerfield: "" + usersFile: etc/traefik/.htpasswd + + # Add the service services: service-foo: - loadbalancer: + loadBalancer: servers: - url: http://foo/ - url: http://bar/ + passHostHeader: false ``` ## Provider Configuration Options @@ -170,7 +175,7 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat {{ end }} - [http.Services] + [http.services] {{ range $i, $e := until 100 }} [http.services.service{{ $e }}] # ... @@ -185,7 +190,7 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat {{ end }} - [tcp.Services] + [tcp.services] {{ range $i, $e := until 100 }} [http.services.service{{ $e }}] # ... @@ -193,9 +198,9 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat {{ range $i, $e := until 10 }} [[tls.certificates]] - CertFile = "/etc/traefik/cert-{{ $e }}.pem" - KeyFile = "/etc/traefik/cert-{{ $e }}.key" - Store = ["my-store-foo-{{ $e }}", "my-store-bar-{{ $e }}"] + certFile = "/etc/traefik/cert-{{ $e }}.pem" + keyFile = "/etc/traefik/cert-{{ $e }}.key" + store = ["my-store-foo-{{ $e }}", "my-store-bar-{{ $e }}"] {{ end }} [tls.config] @@ -237,8 +242,8 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat {{ range $i, $e := until 10 }} tls: certificates: - - certfile: "/etc/traefik/cert-{{ $e }}.pem" - keyfile: "/etc/traefik/cert-{{ $e }}.key" + - certFile: "/etc/traefik/cert-{{ $e }}.pem" + keyFile: "/etc/traefik/cert-{{ $e }}.key" store: - "my-store-foo-{{ $e }}" - "my-store-bar-{{ $e }}" diff --git a/docs/content/providers/kubernetes-crd.md b/docs/content/providers/kubernetes-crd.md index 95a2885e8..b0f35ae94 100644 --- a/docs/content/providers/kubernetes-crd.md +++ b/docs/content/providers/kubernetes-crd.md @@ -33,7 +33,7 @@ In this case, the endpoint is required. Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted authentication and authorization of the associated kubeconfig. ```toml tab="File" -[Providers.KubernetesCRD] +[providers.kubernetesCRD] endpoint = "http://localhost:8080" # ... ``` @@ -50,7 +50,7 @@ _Optional, Default=empty_ Bearer token used for the Kubernetes client configuration. ```toml tab="File" -[Providers.KubernetesCRD] +[providers.kubernetesCRD] token = "mytoken" # ... ``` @@ -68,7 +68,7 @@ Path to the certificate authority file. Used for the Kubernetes client configuration. ```toml tab="File" -[Providers.KubernetesCRD] +[providers.kubernetesCRD] certAuthFilePath = "/my/ca.crt" # ... ``` @@ -85,7 +85,7 @@ _Optional, Default: all namespaces (empty array)_ Array of namespaces to watch. ```toml tab="File" -[Providers.KubernetesCRD] +[providers.kubernetesCRD] namespaces = ["default", "production"] # ... ``` @@ -105,7 +105,7 @@ A label selector can be defined to filter on specific Ingress objects only. See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details. ```toml tab="File" -[Providers.KubernetesCRD] +[providers.kubernetesCRD] labelselector = "A and not B" # ... ``` @@ -125,7 +125,7 @@ If the parameter is non-empty, only Ingresses containing an annotation with the Otherwise, Ingresses missing the annotation, having an empty value, or the value `traefik` are processed. ```toml tab="File" -[Providers.KubernetesCRD] +[providers.kubernetesCRD] ingressClass = "traefik-internal" # ... ``` diff --git a/docs/content/providers/marathon.md b/docs/content/providers/marathon.md index 178bb01ff..d37e3ed78 100644 --- a/docs/content/providers/marathon.md +++ b/docs/content/providers/marathon.md @@ -13,7 +13,7 @@ See also [Marathon user guide](../user-guides/marathon.md). ```toml tab="File" [providers.marathon] - endpoint = "http://127.0.0.1:8080" + endpoint = "http://127.0.0.1:8080" ``` ```txt tab="CLI" @@ -58,9 +58,9 @@ _Optional_ Enables Marathon basic authentication. ```toml tab="File" -[marathon.basic] -httpBasicAuthUser = "foo" -httpBasicPassword = "bar" +[providers.marathon.basic] + httpBasicAuthUser = "foo" + httpBasicPassword = "bar" ``` ```txt tab="CLI" @@ -79,8 +79,8 @@ If set, it overrides the Authorization header. ```toml tab="File" [providers.marathon] -dcosToken = "xxxxxx" -# ... + dcosToken = "xxxxxx" + # ... ``` ```txt tab="CLI" @@ -102,8 +102,8 @@ and the template has access to all the labels defined on this Marathon applicati ```toml tab="File" [providers.marathon] -defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" -# ... + defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" + # ... ``` ```txt tab="CLI" @@ -133,8 +133,8 @@ You can optionally specify multiple endpoints: ```toml tab="File" [providers.marathon] -endpoint = "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" -# ... + endpoint = "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" + # ... ``` ```txt tab="CLI" @@ -247,11 +247,11 @@ _Optional_ TLS client configuration. [tls/#Config](https://golang.org/pkg/crypto/tls/#Config). ```toml tab="File" -[marathon.TLS] -CA = "/etc/ssl/ca.crt" -Cert = "/etc/ssl/marathon.cert" -Key = "/etc/ssl/marathon.key" -insecureSkipVerify = true +[providers.marathon.tls] + ca = "/etc/ssl/ca.crt" + cert = "/etc/ssl/marathon.cert" + key = "/etc/ssl/marathon.key" + insecureSkipVerify = true ``` ```txt tab="CLI" @@ -296,23 +296,23 @@ and the router automatically gets a rule defined by defaultRule (if no rule for ### Routers To update the configuration of the Router automatically attached to the application, -add labels starting with `traefik.HTTP.Routers.{router-name-of-your-choice}.` and followed by the option you want to change. -For example, to change the routing rule, you could add the label ```traefik.HTTP.Routers.Routername.Rule=Host(`my-domain`)```. +add labels starting with `traefik.http.routers.{router-name-of-your-choice}.` and followed by the option you want to change. +For example, to change the routing rule, you could add the label ```traefik.http.routers.routername.rule=Host(`my-domain`)```. Every [Router](../routing/routers/index.md) parameter can be updated this way. ### Services To update the configuration of the Service automatically attached to the container, -add labels starting with `traefik.HTTP.Services.{service-name-of-your-choice}.`, followed by the option you want to change. -For example, to change the passhostheader behavior, you'd add the label `traefik.HTTP.Services.Servicename.LoadBalancer.PassHostHeader=false`. +add labels starting with `traefik.http.services.{service-name-of-your-choice}.`, followed by the option you want to change. +For example, to change the passHostHeader behavior, you'd add the label `traefik.http.services.servicename.loadbalancer.passhostheader=false`. Every [Service](../routing/services/index.md) parameter can be updated this way. ### Middleware -You can declare pieces of middleware using labels starting with `traefik.HTTP.Middlewares.{middleware-name-of-your-choice}.`, followed by the middleware type/options. -For example, to declare a middleware [`redirectscheme`](../middlewares/redirectscheme.md) named `my-redirect`, you'd write `traefik.HTTP.Middlewares.my-redirect.RedirectScheme.Scheme: https`. +You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{middleware-name-of-your-choice}.`, followed by the middleware type/options. +For example, to declare a middleware [`redirectscheme`](../middlewares/redirectscheme.md) named `my-redirect`, you'd write `traefik.http.middlewares.my-redirect.redirectscheme.scheme: https`. ??? example "Declaring and Referencing a Middleware" diff --git a/docs/content/providers/rancher.md b/docs/content/providers/rancher.md index a9572d61b..a5662f31f 100644 --- a/docs/content/providers/rancher.md +++ b/docs/content/providers/rancher.md @@ -19,7 +19,7 @@ Attach labels to your services and let Traefik do the rest! Enabling the rancher provider ```toml - [Providers.Rancher] + [providers.rancher] ``` Attaching labels to services @@ -58,9 +58,9 @@ The service name can be accessed as the `Name` identifier, and the template has access to all the labels defined on this container. ```toml tab="File" -[Providers.Rancher] -defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" -# ... +[providers.rancher] + defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" + # ... ``` ```txt tab="CLI" diff --git a/docs/content/providers/rancher.toml b/docs/content/providers/rancher.toml index 5ce4bac50..b209fb8cb 100644 --- a/docs/content/providers/rancher.toml +++ b/docs/content/providers/rancher.toml @@ -1,20 +1,20 @@ # Enable Rancher Provider. -[Providers.Rancher] +[providers.rancher] # Expose Rancher services by default in Traefik. - ExposedByDefault = true + exposedByDefault = true # Enable watch Rancher changes. - Watch = true + watch = true # Filter services with unhealthy states and inactive states. - EnableServiceHealthFilter = true + enableServiceHealthFilter = true # Defines the polling interval (in seconds). - RefreshSeconds = true + refreshSeconds = true # Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, which is less accurate - IntervalPoll = false + intervalPoll = false # Prefix used for accessing the Rancher metadata service - Prefix = "/latest" + prefix = "/latest" diff --git a/docs/content/reference/dynamic-configuration/docker.md b/docs/content/reference/dynamic-configuration/docker.md index 1ba5becff..b8c137743 100644 --- a/docs/content/reference/dynamic-configuration/docker.md +++ b/docs/content/reference/dynamic-configuration/docker.md @@ -3,6 +3,8 @@ Dynamic configuration with Docker Labels {: .subtitle } +The labels are case insensitive. + ```yaml --8<-- "content/reference/dynamic-configuration/labels.yml" ``` diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index 1879364b9..8dab9ba61 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -1,259 +1,248 @@ -[HTTP] - - [HTTP.Routers] - - [HTTP.Routers.Router0] - EntryPoints = ["foobar", "foobar"] - Middlewares = ["foobar", "foobar"] - Service = "foobar" - Rule = "foobar" +[http] + [http.routers] + [http.routers.Router0] + entryPoints = ["foobar", "foobar"] + middlewares = ["foobar", "foobar"] + service = "foobar" + rule = "foobar" priority = 42 - [HTTP.Routers.Router0.tls] + [http.routers.Router0.tls] options = "TLS0" - - [HTTP.Middlewares] - - [HTTP.Middlewares.Middleware0.AddPrefix] - Prefix = "foobar" - - [HTTP.Middlewares.Middleware1.StripPrefix] - Prefixes = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware2.StripPrefixRegex] - Regex = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware3.ReplacePath] - Path = "foobar" - - [HTTP.Middlewares.Middleware4.ReplacePathRegex] - Regex = "foobar" - Replacement = "foobar" - - [HTTP.Middlewares.Middleware5.Chain] - Middlewares = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware6.IPWhiteList] - SourceRange = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware7.IPWhiteList.IPStrategy] - Depth = 42 - ExcludedIPs = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware8.Headers] - AccessControlAllowCredentials = true - AccessControlAllowHeaders = ["foobar", "foobar"] - AccessControlAllowMethods = ["foobar", "foobar"] - AccessControlAllowOrigin = "foobar" - AccessControlExposeHeaders = ["foobar", "foobar"] - AccessControlMaxAge = 42 - AddVaryHeader = true - AllowedHosts = ["foobar", "foobar"] - HostsProxyHeaders = ["foobar", "foobar"] - SSLRedirect = true - SSLTemporaryRedirect = true - SSLHost = "foobar" - SSLForceHost = true - STSSeconds = 42 - STSIncludeSubdomains = true - STSPreload = true - ForceSTSHeader = true - FrameDeny = true - CustomFrameOptionsValue = "foobar" - ContentTypeNosniff = true - BrowserXSSFilter = true - CustomBrowserXSSValue = "foobar" - ContentSecurityPolicy = "foobar" - PublicKey = "foobar" - ReferrerPolicy = "foobar" - IsDevelopment = true - [HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders] + [http.middlewares] + [http.middlewares.Middleware0] + [http.middlewares.Middleware0.addPrefix] + prefix = "foobar" + [http.middlewares.Middleware1] + [http.middlewares.Middleware1.stripPrefix] + prefixes = ["foobar", "foobar"] + [http.middlewares.Middleware10] + [http.middlewares.Middleware10.rateLimit] + extractorFunc = "foobar" + [http.middlewares.Middleware10.rateLimit.rateSet] + [http.middlewares.Middleware10.rateLimit.rateSet.Rate0] + period = 42 + average = 42 + burst = 42 + [http.middlewares.Middleware10.rateLimit.rateSet.Rate1] + period = 42 + average = 42 + burst = 42 + [http.middlewares.Middleware11] + [http.middlewares.Middleware11.redirectRegex] + regex = "foobar" + replacement = "foobar" + permanent = true + [http.middlewares.Middleware12] + [http.middlewares.Middleware12.redirectScheme] + scheme = "foobar" + port = "foobar" + permanent = true + [http.middlewares.Middleware13] + [http.middlewares.Middleware13.basicAuth] + users = ["foobar", "foobar"] + usersFile = "foobar" + realm = "foobar" + removeHeader = true + headerField = "foobar" + [http.middlewares.Middleware14] + [http.middlewares.Middleware14.digestAuth] + users = ["foobar", "foobar"] + usersFile = "foobar" + removeHeader = true + realm = "foobar" + headerField = "foobar" + [http.middlewares.Middleware15] + [http.middlewares.Middleware15.forwardAuth] + address = "foobar" + trustForwardHeader = true + authResponseHeaders = ["foobar", "foobar"] + [http.middlewares.Middleware15.forwardAuth.tls] + ca = "foobar" + caOptional = true + cert = "foobar" + key = "foobar" + insecureSkipVerify = true + [http.middlewares.Middleware16] + [http.middlewares.Middleware16.maxConn] + amount = 42 + extractorFunc = "foobar" + [http.middlewares.Middleware17] + [http.middlewares.Middleware17.buffering] + maxRequestBodyBytes = 42 + memRequestBodyBytes = 42 + maxResponseBodyBytes = 42 + memResponseBodyBytes = 42 + retryExpression = "foobar" + [http.middlewares.Middleware18] + [http.middlewares.Middleware18.circuitBreaker] + expression = "foobar" + [http.middlewares.Middleware19] + [http.middlewares.Middleware19.compress] + [http.middlewares.Middleware2] + [http.middlewares.Middleware2.stripPrefixRegex] + regex = ["foobar", "foobar"] + [http.middlewares.Middleware20] + [http.middlewares.Middleware20.passTLSClientCert] + pem = true + [http.middlewares.Middleware20.passTLSClientCert.info] + notAfter = true + notBefore = true + sans = true + [http.middlewares.Middleware20.passTLSClientCert.info.subject] + country = true + province = true + locality = true + organization = true + commonName = true + serialNumber = true + domainComponent = true + [http.middlewares.Middleware20.passTLSClientCert.info.issuer] + country = true + province = true + locality = true + organization = true + commonName = true + serialNumber = true + domainComponent = true + [http.middlewares.Middleware21] + [http.middlewares.Middleware21.retry] + attemps = 42 + [http.middlewares.Middleware3] + [http.middlewares.Middleware3.replacePath] + path = "foobar" + [http.middlewares.Middleware4] + [http.middlewares.Middleware4.replacePathRegex] + regex = "foobar" + replacement = "foobar" + [http.middlewares.Middleware5] + [http.middlewares.Middleware5.chain] + middlewares = ["foobar", "foobar"] + [http.middlewares.Middleware6] + [http.middlewares.Middleware6.ipWhiteList] + sourceRange = ["foobar", "foobar"] + [http.middlewares.Middleware7] + [http.middlewares.Middleware7.ipWhiteList] + [http.middlewares.Middleware7.ipWhiteList.ipStrategy] + depth = 42 + excludedIPs = ["foobar", "foobar"] + [http.middlewares.Middleware8] + [http.middlewares.Middleware8.headers] + accessControlAllowCredentials = true + accessControlAllowHeaders = ["foobar", "foobar"] + accessControlAllowMethods = ["foobar", "foobar"] + accessControlAllowOrigin = "foobar" + accessControlExposeHeaders = ["foobar", "foobar"] + accessControlMaxAge = 42 + addVaryHeader = true + allowedHosts = ["foobar", "foobar"] + hostsProxyHeaders = ["foobar", "foobar"] + sslRedirect = true + sslTemporaryRedirect = true + sslHost = "foobar" + sslForceHost = true + stsSeconds = 42 + stsIncludeSubdomains = true + stsPreload = true + forceSTSHeader = true + frameDeny = true + customFrameOptionsValue = "foobar" + contentTypeNosniff = true + browserXssFilter = true + customBrowserXSSValue = "foobar" + contentSecurityPolicy = "foobar" + publicKey = "foobar" + referrerPolicy = "foobar" + isDevelopment = true + [http.middlewares.Middleware8.headers.customRequestHeaders] name0 = "foobar" name1 = "foobar" - [HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders] + [http.middlewares.Middleware8.headers.customResponseHeaders] name0 = "foobar" name1 = "foobar" - [HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders] + [http.middlewares.Middleware8.headers.sslProxyHeaders] name0 = "foobar" name1 = "foobar" + [http.middlewares.Middleware9] + [http.middlewares.Middleware9.errors] + status = ["foobar", "foobar"] + service = "foobar" + query = "foobar" + [http.services] + [http.services.Service0] + [http.services.Service0.loadBalancer] + passHostHeader = true + [http.services.Service0.loadBalancer.stickiness] + cookieName = "foobar" - [HTTP.Middlewares.Middleware9.Errors] - Status = ["foobar", "foobar"] - Service = "foobar" - Query = "foobar" + [[http.services.Service0.loadBalancer.servers]] + url = "foobar" - [HTTP.Middlewares.Middleware10.RateLimit] - ExtractorFunc = "foobar" - [HTTP.Middlewares.Middleware10.RateLimit.RateSet] - [HTTP.Middlewares.Middleware10.RateLimit.RateSet.Rate0] - Period = 42 - Average = 42 - Burst = 42 - [HTTP.Middlewares.Middleware10.RateLimit.RateSet.Rate1] - Period = 42 - Average = 42 - Burst = 42 - - [HTTP.Middlewares.Middleware11.RedirectRegex] - Regex = "foobar" - Replacement = "foobar" - Permanent = true - - [HTTP.Middlewares.Middleware12.RedirectScheme] - Scheme = "foobar" - Port = "foobar" - Permanent = true - - [HTTP.Middlewares.Middleware13.BasicAuth] - Users = ["foobar", "foobar"] - UsersFile = "foobar" - Realm = "foobar" - RemoveHeader = true - HeaderField = "foobar" - - [HTTP.Middlewares.Middleware14.DigestAuth] - Users = ["foobar", "foobar"] - UsersFile = "foobar" - RemoveHeader = true - Realm = "foobar" - HeaderField = "foobar" - - [HTTP.Middlewares.Middleware15.ForwardAuth] - Address = "foobar" - TrustForwardHeader = true - AuthResponseHeaders = ["foobar", "foobar"] - [HTTP.Middlewares.Middleware15.ForwardAuth.TLS] - CA = "foobar" - CAOptional = true - Cert = "foobar" - Key = "foobar" - InsecureSkipVerify = true - - [HTTP.Middlewares.Middleware16.MaxConn] - Amount = 42 - ExtractorFunc = "foobar" - - [HTTP.Middlewares.Middleware17.Buffering] - MaxRequestBodyBytes = 42 - MemRequestBodyBytes = 42 - MaxResponseBodyBytes = 42 - MemResponseBodyBytes = 42 - RetryExpression = "foobar" - - [HTTP.Middlewares.Middleware18.CircuitBreaker] - Expression = "foobar" - - [HTTP.Middlewares.Middleware19.Compress] - - [HTTP.Middlewares.Middleware20.PassTLSClientCert] - PEM = true - [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info] - NotAfter = true - NotBefore = true - Sans = true - [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info.Subject] - Country = true - Province = true - Locality = true - Organization = true - CommonName = true - SerialNumber = true - DomainComponent = true - [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info.Issuer] - Country = true - Province = true - Locality = true - Organization = true - CommonName = true - SerialNumber = true - DomainComponent = true - - [HTTP.Middlewares.Middleware21.Retry] - Attempts = 42 - - [HTTP.Services] - [HTTP.Services.Service0] - [HTTP.Services.Service0.LoadBalancer] - PassHostHeader = true - - [[HTTP.Services.Service0.LoadBalancer.Servers]] - URL = "foobar" - - [HTTP.Services.Service0.LoadBalancer.Stickiness] - CookieName = "foobar" - - [[HTTP.Services.Service0.LoadBalancer.Servers]] - URL = "foobar" - - [HTTP.Services.Service0.LoadBalancer.HealthCheck] - Scheme = "foobar" - Path = "foobar" - Port = 42 - Interval = "foobar" - Timeout = "foobar" - Hostname = "foobar" - [HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers] + [[http.services.Service0.loadBalancer.servers]] + url = "foobar" + [http.services.Service0.loadBalancer.healthCheck] + scheme = "foobar" + path = "foobar" + port = 42 + interval = "foobar" + timeout = "foobar" + hostname = "foobar" + [http.services.Service0.loadBalancer.healthCheck.headers] name0 = "foobar" name1 = "foobar" - [HTTP.Services.Service0.LoadBalancer.ResponseForwarding] - FlushInterval = "foobar" + [http.services.Service0.loadBalancer.responseForwarding] + flushInterval = "foobar" -[TCP] - - [TCP.Routers] - - [TCP.Routers.TCPRouter0] - EntryPoints = ["foobar", "foobar"] - Service = "foobar" - Rule = "foobar" - [TCP.Routers.TCPRouter0.tls] +[tcp] + [tcp.routers] + [tcp.routers.TCPRouter0] + entryPoints = ["foobar", "foobar"] + service = "foobar" + rule = "foobar" + [tcp.routers.TCPRouter0.tls] passthrough = true options = "TLS1" + [tcp.services] + [tcp.services.TCPService0] + [tcp.services.TCPService0.loadBalancer] - [TCP.Services] + [[tcp.services.TCPService0.loadBalancer.servers]] + address = "foobar" - [TCP.Services.TCPService0] - [TCP.Services.TCPService0.LoadBalancer] + [[tcp.services.TCPService0.loadBalancer.servers]] + address = "foobar" - [[TCP.Services.TCPService0.LoadBalancer.Servers]] - Address = "foobar" +[tls] - [[TCP.Services.TCPService0.LoadBalancer.Servers]] - Address = "foobar" + [[tls.certificates]] + certFile = "foobar" + keyFile = "foobar" + stores = ["foobar", "foobar"] -[TLS] - - [[TLS.Certificates]] - Stores = ["foobar", "foobar"] - CertFile = "foobar" - KeyFile = "foobar" - - [[TLS.Certificates]] - Stores = ["foobar", "foobar"] - CertFile = "foobar" - KeyFile = "foobar" - - [TLS.Options] - [TLS.Options.TLS0] - MinVersion = "foobar" - CipherSuites = ["foobar", "foobar"] - SniStrict = true - [TLS.Options.TLS0.ClientCA] - Files = ["foobar", "foobar"] - Optional = true - [TLS.Options.TLS1] - MinVersion = "foobar" - CipherSuites = ["foobar", "foobar"] - SniStrict = true - [TLS.Options.TLS1.ClientCA] - Files = ["foobar", "foobar"] - Optional = true - - [TLS.Stores] - [TLS.Stores.Store0] - [TLS.Stores.Store0.DefaultCertificate] - CertFile = "foobar" - KeyFile = "foobar" - [TLS.Stores.Store1] - [TLS.Stores.Store1.DefaultCertificate] - CertFile = "foobar" - KeyFile = "foobar" + [[tls.certificates]] + certFile = "foobar" + keyFile = "foobar" + stores = ["foobar", "foobar"] + [tls.options] + [tls.options.TLS0] + minVersion = "foobar" + cipherSuites = ["foobar", "foobar"] + sniStrict = true + [tls.options.TLS0.clientCA] + files = ["foobar", "foobar"] + optional = true + [tls.options.TLS1] + minVersion = "foobar" + cipherSuites = ["foobar", "foobar"] + sniStrict = true + [tls.options.TLS1.clientCA] + files = ["foobar", "foobar"] + optional = true + [tls.stores] + [tls.stores.Store0] + [tls.stores.Store0.defaultCertificate] + certFile = "foobar" + keyFile = "foobar" + [tls.stores.Store1] + [tls.stores.Store1.defaultCertificate] + certFile = "foobar" + keyFile = "foobar" diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index 0587df582..1e72d988a 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -1,7 +1,7 @@ http: routers: Router0: - entrypoints: + entryPoints: - foobar - foobar middlewares: @@ -10,8 +10,7 @@ http: service: foobar rule: foobar priority: 42 - tls: - options: TLS0 + tls: {} middlewares: Middleware0: addPrefix: @@ -40,65 +39,63 @@ http: - foobar Middleware6: ipWhiteList: - sourcerange: + sourceRange: - foobar - foobar - ipstrategy: null Middleware7: ipWhiteList: - sourcerange: [] - ipstrategy: + ipStrategy: depth: 42 - excludedips: + excludedIPs: - foobar - foobar Middleware8: headers: - customrequestheaders: + customRequestHeaders: name0: foobar name1: foobar - customresponseheaders: + customResponseHeaders: name0: foobar name1: foobar - accesscontrolallowcredentials: true - accesscontrolallowheaders: + accessControlAllowCredentials: true + accessControlAllowHeaders: - foobar - foobar - accesscontrolallowmethods: + accessControlAllowMethods: - foobar - foobar - accesscontrolalloworigin: foobar - accesscontrolexposeheaders: + accessControlAllowOrigin: foobar + accessControlExposeHeaders: - foobar - foobar - accesscontrolmaxage: 42 - addvaryheader: true - allowedhosts: + accessControlMaxAge: 42 + addVaryHeader: true + allowedHosts: - foobar - foobar - hostsproxyheaders: + hostsProxyHeaders: - foobar - foobar - sslredirect: true - ssltemporaryredirect: true - sslhost: foobar - sslproxyheaders: + sslRedirect: true + sslTemporaryRedirect: true + sslHost: foobar + sslProxyHeaders: name0: foobar name1: foobar - sslforcehost: true - stsseconds: 42 - stsincludesubdomains: true - stspreload: true - forcestsheader: true - framedeny: true - customframeoptionsvalue: foobar - contenttypenosniff: true - browserxssfilter: true - custombrowserxssvalue: foobar - contentsecuritypolicy: foobar - publickey: foobar - referrerpolicy: foobar - isdevelopment: true + sslForceHost: true + stsSeconds: 42 + stsIncludeSubdomains: true + stsPreload: true + forceSTSHeader: true + frameDeny: true + customFrameOptionsValue: foobar + contentTypeNosniff: true + browserXssFilter: true + customBrowserXSSValue: foobar + contentSecurityPolicy: foobar + publicKey: foobar + referrerPolicy: foobar + isDevelopment: true Middleware9: errors: status: @@ -108,7 +105,7 @@ http: query: foobar Middleware10: rateLimit: - rateset: + rateSet: Rate0: period: 42000000000 average: 42 @@ -117,7 +114,7 @@ http: period: 42000000000 average: 42 burst: 42 - extractorfunc: foobar + extractorFunc: foobar Middleware11: redirectRegex: regex: foobar @@ -133,43 +130,43 @@ http: users: - foobar - foobar - usersfile: foobar + usersFile: foobar realm: foobar - removeheader: true - headerfield: foobar + removeHeader: true + headerField: foobar Middleware14: digestAuth: users: - foobar - foobar - usersfile: foobar - removeheader: true + usersFile: foobar + removeHeader: true realm: foobar - headerfield: foobar + headerField: foobar Middleware15: forwardAuth: address: foobar tls: ca: foobar - caoptional: true + caOptional: true cert: foobar key: foobar - insecureskipverify: true - trustforwardheader: true - authresponseheaders: + insecureSkipVerify: true + trustForwardHeader: true + authResponseHeaders: - foobar - foobar Middleware16: maxConn: amount: 42 - extractorfunc: foobar + extractorFunc: foobar Middleware17: buffering: - maxrequestbodybytes: 42 - memrequestbodybytes: 42 - maxresponsebodybytes: 42 - memresponsebodybytes: 42 - retryexpression: foobar + maxRequestBodyBytes: 42 + memRequestBodyBytes: 42 + maxResponseBodyBytes: 42 + memResponseBodyBytes: 42 + retryExpression: foobar Middleware18: circuitBreaker: expression: foobar @@ -179,43 +176,37 @@ http: passTLSClientCert: pem: true info: - notafter: true - notbefore: true + notAfter: true + notBefore: true sans: true subject: country: true province: true locality: true organization: true - commonname: true - serialnumber: true - domaincomponent: true + commonName: true + serialNumber: true + domainComponent: true issuer: country: true province: true locality: true organization: true - commonname: true - serialnumber: true - domaincomponent: true + commonName: true + serialNumber: true + domainComponent: true Middleware21: retry: - attempts: 42 + attemps: 42 services: Service0: - loadbalancer: + loadBalancer: stickiness: - cookiename: foobar - securecookie: false - httponlycookie: false + cookieName: foobar servers: - url: foobar - scheme: "" - port: "" - url: foobar - scheme: "" - port: "" - healthcheck: + healthCheck: scheme: foobar path: foobar port: 42 @@ -225,70 +216,66 @@ http: headers: name0: foobar name1: foobar - passhostheader: true - responseforwarding: - flushinterval: foobar + passHostHeader: true + responseForwarding: + flushInterval: foobar tcp: routers: TCPRouter0: - entrypoints: + entryPoints: - foobar - foobar service: foobar rule: foobar tls: passthrough: true - options: TLS1 services: TCPService0: - loadbalancer: + loadBalancer: servers: - address: foobar - port: "" - address: foobar - port: "" tls: - - stores: - - foobar - - foobar - certificate: - certfile: foobar - keyfile: foobar - - stores: - - foobar - - foobar - certificate: - certfile: foobar - keyfile: foobar -tlsoptions: - TLS0: - minversion: foobar - ciphersuites: - - foobar - - foobar - clientca: - files: + certificates: + - certFile: foobar + keyFile: foobar + stores: - foobar - foobar - optional: true - snistrict: true - TLS1: - minversion: foobar - ciphersuites: - - foobar - - foobar - clientca: - files: + - certFile: foobar + keyFile: foobar + stores: - foobar - foobar - optional: true - snistrict: true -tlsstores: - Store0: - defaultcertificate: - certfile: foobar - keyfile: foobar - Store1: - defaultcertificate: - certfile: foobar - keyfile: foobar + options: + TLS0: + minVersion: foobar + cipherSuites: + - foobar + - foobar + clientCA: + files: + - foobar + - foobar + optional: true + sniStrict: true + TLS1: + minVersion: foobar + cipherSuites: + - foobar + - foobar + clientCA: + files: + - foobar + - foobar + optional: true + sniStrict: true + stores: + Store0: + defaultCertificate: + certFile: foobar + keyFile: foobar + Store1: + defaultCertificate: + certFile: foobar + keyFile: foobar diff --git a/docs/content/reference/dynamic-configuration/labels.yml b/docs/content/reference/dynamic-configuration/labels.yml index c7ba2981e..a1b557cfb 100644 --- a/docs/content/reference/dynamic-configuration/labels.yml +++ b/docs/content/reference/dynamic-configuration/labels.yml @@ -1,154 +1,154 @@ labels: -- "traefik.HTTP.Middlewares.Middleware0.AddPrefix.Prefix=foobar" -- "traefik.HTTP.Middlewares.Middleware1.BasicAuth.HeaderField=foobar" -- "traefik.HTTP.Middlewares.Middleware1.BasicAuth.Realm=foobar" -- "traefik.HTTP.Middlewares.Middleware1.BasicAuth.RemoveHeader=true" -- "traefik.HTTP.Middlewares.Middleware1.BasicAuth.Users=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware1.BasicAuth.UsersFile=foobar" -- "traefik.HTTP.Middlewares.Middleware2.Buffering.MaxRequestBodyBytes=42" -- "traefik.HTTP.Middlewares.Middleware2.Buffering.MaxResponseBodyBytes=42" -- "traefik.HTTP.Middlewares.Middleware2.Buffering.MemRequestBodyBytes=42" -- "traefik.HTTP.Middlewares.Middleware2.Buffering.MemResponseBodyBytes=42" -- "traefik.HTTP.Middlewares.Middleware2.Buffering.RetryExpression=foobar" -- "traefik.HTTP.Middlewares.Middleware3.Chain.Middlewares=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware4.CircuitBreaker.Expression=foobar" -- "traefik.HTTP.Middlewares.Middleware5.DigestAuth.HeaderField=foobar" -- "traefik.HTTP.Middlewares.Middleware5.DigestAuth.Realm=foobar" -- "traefik.HTTP.Middlewares.Middleware5.DigestAuth.RemoveHeader=true" -- "traefik.HTTP.Middlewares.Middleware5.DigestAuth.Users=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware5.DigestAuth.UsersFile=foobar" -- "traefik.HTTP.Middlewares.Middleware6.Errors.Query=foobar" -- "traefik.HTTP.Middlewares.Middleware6.Errors.Service=foobar" -- "traefik.HTTP.Middlewares.Middleware6.Errors.Status=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.Address=foobar" -- "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.AuthResponseHeaders=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.CA=foobar" -- "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.CAOptional=true" -- "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Cert=foobar" -- "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.InsecureSkipVerify=true" -- "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Key=foobar" -- "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TrustForwardHeader=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowCredentials=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowHeaders=X-foobar, X-fiibar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowMethods=GET, PUT" -- "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowOrigin=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlExposeHeaders=X-foobar, X-fiibar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlMaxAge=200" -- "traefik.HTTP.Middlewares.Middleware8.Headers.AddVaryHeader=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.AllowedHosts=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.BrowserXSSFilter=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.ContentSecurityPolicy=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.ContentTypeNosniff=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.CustomBrowserXSSValue=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.CustomFrameOptionsValue=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders.name0=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders.name1=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders.name0=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders.name1=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.ForceSTSHeader=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.FrameDeny=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.HostsProxyHeaders=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.IsDevelopment=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.PublicKey=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.ReferrerPolicy=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.SSLForceHost=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.SSLHost=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders.name0=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders.name1=foobar" -- "traefik.HTTP.Middlewares.Middleware8.Headers.SSLRedirect=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.SSLTemporaryRedirect=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.STSIncludeSubdomains=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.STSPreload=true" -- "traefik.HTTP.Middlewares.Middleware8.Headers.STSSeconds=42" -- "traefik.HTTP.Middlewares.Middleware9.IPWhiteList.IPStrategy.Depth=42" -- "traefik.HTTP.Middlewares.Middleware9.IPWhiteList.IPStrategy.ExcludedIPs=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware9.IPWhiteList.SourceRange=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware10.MaxConn.Amount=42" -- "traefik.HTTP.Middlewares.Middleware10.MaxConn.ExtractorFunc=foobar" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.NotAfter=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.NotBefore=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Sans=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Country=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Province=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Locality=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Organization=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.CommonName=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.SerialNumber=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.DomainComponent=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Country=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Province=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Locality=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Organization=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.CommonName=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.SerialNumber=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.DomainComponent=true" -- "traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.PEM=true" -- "traefik.HTTP.Middlewares.Middleware12.RateLimit.ExtractorFunc=foobar" -- "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Average=42" -- "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Burst=42" -- "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Period=42" -- "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Average=42" -- "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Burst=42" -- "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Period=42" -- "traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Regex=foobar" -- "traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Replacement=foobar" -- "traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Permanent=true" -- "traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Scheme=https" -- "traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Port=80" -- "traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Permanent=true" -- "traefik.HTTP.Middlewares.Middleware14.ReplacePath.Path=foobar" -- "traefik.HTTP.Middlewares.Middleware15.ReplacePathRegex.Regex=foobar" -- "traefik.HTTP.Middlewares.Middleware15.ReplacePathRegex.Replacement=foobar" -- "traefik.HTTP.Middlewares.Middleware16.Retry.Attempts=42" -- "traefik.HTTP.Middlewares.Middleware17.StripPrefix.Prefixes=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware18.StripPrefixRegex.Regex=foobar, fiibar" -- "traefik.HTTP.Middlewares.Middleware19.Compress=true" -- "traefik.HTTP.Routers.Router0.EntryPoints=foobar, fiibar" -- "traefik.HTTP.Routers.Router0.Middlewares=foobar, fiibar" -- "traefik.HTTP.Routers.Router0.Priority=42" -- "traefik.HTTP.Routers.Router0.Rule=foobar" -- "traefik.HTTP.Routers.Router0.Service=foobar" -- "traefik.HTTP.Routers.Router0.TLS=true" -- "traefik.HTTP.Routers.Router0.TLS.options=foo" -- "traefik.HTTP.Routers.Router1.EntryPoints=foobar, fiibar" -- "traefik.HTTP.Routers.Router1.Middlewares=foobar, fiibar" -- "traefik.HTTP.Routers.Router1.Priority=42" -- "traefik.HTTP.Routers.Router1.Rule=foobar" -- "traefik.HTTP.Routers.Router1.Service=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name0=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name1=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Hostname=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Interval=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Path=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Port=42" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Scheme=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Timeout=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.PassHostHeader=true" -- "traefik.HTTP.Services.Service0.LoadBalancer.ResponseForwarding.FlushInterval=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.server.Port=8080" -- "traefik.HTTP.Services.Service0.LoadBalancer.server.Scheme=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.Stickiness.CookieName=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name0=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Hostname=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Interval=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Path=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Port=42" -- "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Scheme=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Timeout=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.PassHostHeader=true" -- "traefik.HTTP.Services.Service1.LoadBalancer.ResponseForwarding.FlushInterval=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.server.Port=8080" -- "traefik.HTTP.Services.Service1.LoadBalancer.server.Scheme=foobar" -- "traefik.TCP.Routers.Router0.Rule=foobar" -- "traefik.TCP.Routers.Router0.EntryPoints=foobar, fiibar" -- "traefik.TCP.Routers.Router0.Service=foobar" -- "traefik.TCP.Routers.Router0.TLS.Passthrough=false" -- "traefik.TCP.Routers.Router0.TLS.options=bar" -- "traefik.TCP.Routers.Router1.Rule=foobar" -- "traefik.TCP.Routers.Router1.EntryPoints=foobar, fiibar" -- "traefik.TCP.Routers.Router1.Service=foobar" -- "traefik.TCP.Routers.Router1.TLS.Passthrough=false" -- "traefik.TCP.Routers.Router1.TLS.options=foobar" -- "traefik.TCP.Services.Service0.LoadBalancer.server.Port=42" -- "traefik.TCP.Services.Service1.LoadBalancer.server.Port=42" +- "traefik.http.middlewares.Middleware0.addprefix.prefix=foobar" +- "traefik.http.middlewares.Middleware1.basicauth.headerfield=foobar" +- "traefik.http.middlewares.Middleware1.basicauth.realm=foobar" +- "traefik.http.middlewares.Middleware1.basicauth.removeheader=true" +- "traefik.http.middlewares.Middleware1.basicauth.users=foobar, fiibar" +- "traefik.http.middlewares.Middleware1.basicauth.usersfile=foobar" +- "traefik.http.middlewares.Middleware2.buffering.maxrequestbodybytes=42" +- "traefik.http.middlewares.Middleware2.buffering.maxresponsebodybytes=42" +- "traefik.http.middlewares.Middleware2.buffering.memrequestbodybytes=42" +- "traefik.http.middlewares.Middleware2.buffering.memresponsebodybytes=42" +- "traefik.http.middlewares.Middleware2.buffering.retryexpression=foobar" +- "traefik.http.middlewares.Middleware3.chain.middlewares=foobar, fiibar" +- "traefik.http.middlewares.Middleware4.circuitbreaker.expression=foobar" +- "traefik.http.middlewares.Middleware5.digestauth.headerfield=foobar" +- "traefik.http.middlewares.Middleware5.digestauth.realm=foobar" +- "traefik.http.middlewares.Middleware5.digestauth.removeheader=true" +- "traefik.http.middlewares.Middleware5.digestauth.users=foobar, fiibar" +- "traefik.http.middlewares.Middleware5.digestauth.usersfile=foobar" +- "traefik.http.middlewares.Middleware6.errors.query=foobar" +- "traefik.http.middlewares.Middleware6.errors.service=foobar" +- "traefik.http.middlewares.Middleware6.errors.status=foobar, fiibar" +- "traefik.http.middlewares.Middleware7.forwardauth.address=foobar" +- "traefik.http.middlewares.Middleware7.forwardauth.authresponseheaders=foobar, fiibar" +- "traefik.http.middlewares.Middleware7.forwardauth.tls.ca=foobar" +- "traefik.http.middlewares.Middleware7.forwardauth.tls.caoptional=true" +- "traefik.http.middlewares.Middleware7.forwardauth.tls.cert=foobar" +- "traefik.http.middlewares.Middleware7.forwardauth.tls.insecureskipverify=true" +- "traefik.http.middlewares.Middleware7.forwardauth.tls.key=foobar" +- "traefik.http.middlewares.Middleware7.forwardauth.trustforwardheader=true" +- "traefik.http.middlewares.Middleware8.headers.accesscontrolallowcredentials=true" +- "traefik.http.middlewares.Middleware8.headers.accesscontrolallowheaders=x-foobar, x-fiibar" +- "traefik.http.middlewares.Middleware8.headers.accesscontrolallowmethods=get, put" +- "traefik.http.middlewares.Middleware8.headers.accesscontrolalloworigin=foobar" +- "traefik.http.middlewares.Middleware8.headers.accesscontrolexposeheaders=x-foobar, x-fiibar" +- "traefik.http.middlewares.Middleware8.headers.accesscontrolmaxage=200" +- "traefik.http.middlewares.Middleware8.headers.addvaryheader=true" +- "traefik.http.middlewares.Middleware8.headers.allowedhosts=foobar, fiibar" +- "traefik.http.middlewares.Middleware8.headers.browserxssfilter=true" +- "traefik.http.middlewares.Middleware8.headers.contentsecuritypolicy=foobar" +- "traefik.http.middlewares.Middleware8.headers.contenttypenosniff=true" +- "traefik.http.middlewares.Middleware8.headers.custombrowserxssvalue=foobar" +- "traefik.http.middlewares.Middleware8.headers.customframeoptionsvalue=foobar" +- "traefik.http.middlewares.Middleware8.headers.customrequestheaders.name0=foobar" +- "traefik.http.middlewares.Middleware8.headers.customrequestheaders.name1=foobar" +- "traefik.http.middlewares.Middleware8.headers.customresponseheaders.name0=foobar" +- "traefik.http.middlewares.Middleware8.headers.customresponseheaders.name1=foobar" +- "traefik.http.middlewares.Middleware8.headers.forcestsheader=true" +- "traefik.http.middlewares.Middleware8.headers.framedeny=true" +- "traefik.http.middlewares.Middleware8.headers.hostsproxyheaders=foobar, fiibar" +- "traefik.http.middlewares.Middleware8.headers.isdevelopment=true" +- "traefik.http.middlewares.Middleware8.headers.publickey=foobar" +- "traefik.http.middlewares.Middleware8.headers.referrerpolicy=foobar" +- "traefik.http.middlewares.Middleware8.headers.sslforcehost=true" +- "traefik.http.middlewares.Middleware8.headers.sslhost=foobar" +- "traefik.http.middlewares.Middleware8.headers.sslproxyheaders.name0=foobar" +- "traefik.http.middlewares.Middleware8.headers.sslproxyheaders.name1=foobar" +- "traefik.http.middlewares.Middleware8.headers.sslredirect=true" +- "traefik.http.middlewares.Middleware8.headers.ssltemporaryredirect=true" +- "traefik.http.middlewares.Middleware8.headers.stsincludesubdomains=true" +- "traefik.http.middlewares.Middleware8.headers.stspreload=true" +- "traefik.http.middlewares.Middleware8.headers.stsseconds=42" +- "traefik.http.middlewares.Middleware9.ipwhitelist.ipstrategy.depth=42" +- "traefik.http.middlewares.Middleware9.ipwhitelist.ipstrategy.excludedips=foobar, fiibar" +- "traefik.http.middlewares.Middleware9.ipwhitelist.sourcerange=foobar, fiibar" +- "traefik.http.middlewares.Middleware10.maxconn.amount=42" +- "traefik.http.middlewares.Middleware10.maxconn.extractorfunc=foobar" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.notafter=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.notbefore=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.sans=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.country=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.province=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.locality=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.organization=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.commonname=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.serialnumber=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.domaincomponent=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.country=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.province=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.locality=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.organization=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.commonname=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.serialnumber=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.domaincomponent=true" +- "traefik.http.middlewares.Middleware11.passtlsclientcert.pem=true" +- "traefik.http.middlewares.Middleware12.ratelimit.extractorfunc=foobar" +- "traefik.http.middlewares.Middleware12.ratelimit.rateset.rate0.average=42" +- "traefik.http.middlewares.Middleware12.ratelimit.rateset.rate0.burst=42" +- "traefik.http.middlewares.Middleware12.ratelimit.rateset.rate0.period=42" +- "traefik.http.middlewares.Middleware12.ratelimit.rateset.rate1.average=42" +- "traefik.http.middlewares.Middleware12.ratelimit.rateset.rate1.burst=42" +- "traefik.http.middlewares.Middleware12.ratelimit.rateset.rate1.period=42" +- "traefik.http.middlewares.Middleware13.redirectregex.regex=foobar" +- "traefik.http.middlewares.Middleware13.redirectregex.replacement=foobar" +- "traefik.http.middlewares.Middleware13.redirectregex.permanent=true" +- "traefik.http.middlewares.Middleware13b.redirectscheme.scheme=https" +- "traefik.http.middlewares.Middleware13b.redirectscheme.port=80" +- "traefik.http.middlewares.Middleware13b.redirectscheme.permanent=true" +- "traefik.http.middlewares.Middleware14.replacepath.path=foobar" +- "traefik.http.middlewares.Middleware15.replacepathregex.regex=foobar" +- "traefik.http.middlewares.Middleware15.replacepathregex.replacement=foobar" +- "traefik.http.middlewares.Middleware16.retry.attempts=42" +- "traefik.http.middlewares.Middleware17.stripprefix.prefixes=foobar, fiibar" +- "traefik.http.middlewares.Middleware18.stripprefixregex.regex=foobar, fiibar" +- "traefik.http.middlewares.Middleware19.compress=true" +- "traefik.http.routers.Router0.entrypoints=foobar, fiibar" +- "traefik.http.routers.Router0.middlewares=foobar, fiibar" +- "traefik.http.routers.Router0.priority=42" +- "traefik.http.routers.Router0.rule=foobar" +- "traefik.http.routers.Router0.service=foobar" +- "traefik.http.routers.Router0.tls=true" +- "traefik.http.routers.Router0.tls.options=foo" +- "traefik.http.routers.Router1.entrypoints=foobar, fiibar" +- "traefik.http.routers.Router1.middlewares=foobar, fiibar" +- "traefik.http.routers.Router1.priority=42" +- "traefik.http.routers.Router1.rule=foobar" +- "traefik.http.routers.Router1.service=foobar" +- "traefik.http.services.Service0.loadbalancer.healthcheck.headers.name0=foobar" +- "traefik.http.services.Service0.loadbalancer.healthcheck.headers.name1=foobar" +- "traefik.http.services.Service0.loadbalancer.healthcheck.hostname=foobar" +- "traefik.http.services.Service0.loadbalancer.healthcheck.interval=foobar" +- "traefik.http.services.Service0.loadbalancer.healthcheck.path=foobar" +- "traefik.http.services.Service0.loadbalancer.healthcheck.port=42" +- "traefik.http.services.Service0.loadbalancer.healthcheck.scheme=foobar" +- "traefik.http.services.Service0.loadbalancer.healthcheck.timeout=foobar" +- "traefik.http.services.Service0.loadbalancer.passhostheader=true" +- "traefik.http.services.Service0.loadbalancer.responseforwarding.flushinterval=foobar" +- "traefik.http.services.Service0.loadbalancer.server.port=8080" +- "traefik.http.services.Service0.loadbalancer.server.scheme=foobar" +- "traefik.http.services.Service0.loadbalancer.stickiness.cookiename=foobar" +- "traefik.http.services.Service1.loadbalancer.healthcheck.headers.name0=foobar" +- "traefik.http.services.Service1.loadbalancer.healthcheck.headers.name1=foobar" +- "traefik.http.services.Service1.loadbalancer.healthcheck.hostname=foobar" +- "traefik.http.services.Service1.loadbalancer.healthcheck.interval=foobar" +- "traefik.http.services.Service1.loadbalancer.healthcheck.path=foobar" +- "traefik.http.services.Service1.loadbalancer.healthcheck.port=42" +- "traefik.http.services.Service1.loadbalancer.healthcheck.scheme=foobar" +- "traefik.http.services.Service1.loadbalancer.healthcheck.timeout=foobar" +- "traefik.http.services.Service1.loadbalancer.passhostheader=true" +- "traefik.http.services.Service1.loadbalancer.responseforwarding.flushinterval=foobar" +- "traefik.http.services.Service1.loadbalancer.server.port=8080" +- "traefik.http.services.Service1.loadbalancer.server.scheme=foobar" +- "traefik.tcp.routers.Router0.rule=foobar" +- "traefik.tcp.routers.Router0.entrypoints=foobar, fiibar" +- "traefik.tcp.routers.Router0.service=foobar" +- "traefik.tcp.routers.Router0.tls.passthrough=false" +- "traefik.tcp.routers.Router0.tls.options=bar" +- "traefik.tcp.routers.Router1.rule=foobar" +- "traefik.tcp.routers.Router1.entrypoints=foobar, fiibar" +- "traefik.tcp.routers.Router1.service=foobar" +- "traefik.tcp.routers.Router1.tls.passthrough=false" +- "traefik.tcp.routers.Router1.tls.options=foobar" +- "traefik.tcp.services.Service0.loadbalancer.server.port=42" +- "traefik.tcp.services.Service1.loadbalancer.server.port=42" diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index 4c7d08810..c53815310 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -1,254 +1,232 @@ -[Global] - CheckNewVersion = true - SendAnonymousUsage = true +[global] + checkNewVersion = true + sendAnonymousUsage = true -[ServersTransport] - InsecureSkipVerify = true - RootCAs = ["foobar", "foobar"] - MaxIdleConnsPerHost = 42 - [ServersTransport.ForwardingTimeouts] - DialTimeout = 42 - ResponseHeaderTimeout = 42 - IdleConnTimeout = 5 +[serversTransport] + insecureSkipVerify = true + rootCAs = ["foobar", "foobar"] + maxIdleConnsPerHost = 42 + [serversTransport.forwardingTimeouts] + dialTimeout = 42 + responseHeaderTimeout = 42 + idleConnTimeout = 42 -[EntryPoints] +[entryPoints] + [entryPoints.EntryPoint0] + address = "foobar" + [entryPoints.EntryPoint0.transport] + [entryPoints.EntryPoint0.transport.lifeCycle] + requestAcceptGraceTimeout = 42 + graceTimeOut = 42 + [entryPoints.EntryPoint0.transport.respondingTimeouts] + readTimeout = 42 + writeTimeout = 42 + idleTimeout = 42 + [entryPoints.EntryPoint0.proxyProtocol] + insecure = true + trustedIPs = ["foobar", "foobar"] + [entryPoints.EntryPoint0.forwardedHeaders] + insecure = true + trustedIPs = ["foobar", "foobar"] - [EntryPoints.EntryPoint0] - Address = "foobar" - [EntryPoints.EntryPoint0.Transport] - [EntryPoints.EntryPoint0.Transport.LifeCycle] - RequestAcceptGraceTimeout = 42 - GraceTimeOut = 42 - [EntryPoints.EntryPoint0.Transport.RespondingTimeouts] - ReadTimeout = 42 - WriteTimeout = 42 - IdleTimeout = 42 - [EntryPoints.EntryPoint0.ProxyProtocol] - Insecure = true - TrustedIPs = ["foobar", "foobar"] - [EntryPoints.EntryPoint0.ForwardedHeaders] - Insecure = true - TrustedIPs = ["foobar", "foobar"] +[providers] + providersThrottleDuration = 42 + [providers.docker] + constraints = "foobar" + watch = true + endpoint = "foobar" + defaultRule = "foobar" + exposedByDefault = true + useBindPortIP = true + swarmMode = true + network = "foobar" + swarmModeRefreshSeconds = 42 + [providers.docker.tls] + ca = "foobar" + caOptional = true + cert = "foobar" + key = "foobar" + insecureSkipVerify = true + [providers.file] + directory = "foobar" + watch = true + filename = "foobar" + debugLogGeneratedTemplate = true + traefikFile = "foobar" + [providers.marathon] + constraints = "foobar" + trace = true + watch = true + endpoint = "foobar" + defaultRule = "foobar" + exposedByDefault = true + dcosToken = "foobar" + dialerTimeout = 42 + responseHeaderTimeout = 42 + tlsHandshakeTimeout = 42 + keepAlive = 42 + forceTaskHostname = true + respectReadinessChecks = true + [providers.marathon.tls] + ca = "foobar" + caOptional = true + cert = "foobar" + key = "foobar" + insecureSkipVerify = true + [providers.marathon.basic] + httpBasicAuthUser = "foobar" + httpBasicPassword = "foobar" + [providers.kubernetes] + endpoint = "foobar" + token = "foobar" + certAuthFilePath = "foobar" + disablePassHostHeaders = true + namespaces = ["foobar", "foobar"] + labelSelector = "foobar" + ingressClass = "foobar" + [providers.kubernetes.ingressEndpoint] + ip = "foobar" + hostname = "foobar" + publishedService = "foobar" + [providers.kubernetesCRD] + endpoint = "foobar" + token = "foobar" + certAuthFilePath = "foobar" + disablePassHostHeaders = true + namespaces = ["foobar", "foobar"] + labelSelector = "foobar" + ingressClass = "foobar" + [providers.rest] + entryPoint = "foobar" + [providers.rancher] + constraints = "foobar" + watch = true + defaultRule = "foobar" + exposedByDefault = true + enableServiceHealthFilter = true + refreshSeconds = 42 + intervalPoll = true + prefix = "foobar" -[Providers] - ProvidersThrottleDuration = 42 +[api] + entryPoint = "foobar" + dashboard = true + middlewares = ["foobar", "foobar"] + [api.statistics] + recentErrors = 42 - [Providers.Docker] - Watch = true - Endpoint = "foobar" - DefaultRule = "foobar" - ExposedByDefault = true - UseBindPortIP = true - SwarmMode = true - Network = "foobar" - SwarmModeRefreshSeconds = 42 - Constraints = "foobar" +[metrics] + [metrics.prometheus] + buckets = [42.0, 42.0] + entryPoint = "foobar" + middlewares = ["foobar", "foobar"] + [metrics.dataDog] + address = "foobar" + pushInterval = "10s" + [metrics.statsD] + address = "foobar" + pushInterval = "10s" + [metrics.influxDB] + address = "foobar" + protocol = "foobar" + pushInterval = "10s" + database = "foobar" + retentionPolicy = "foobar" + username = "foobar" + password = "foobar" - [Providers.Docker.TLS] - CA = "foobar" - CAOptional = true - Cert = "foobar" - Key = "foobar" - InsecureSkipVerify = true +[ping] + entryPoint = "foobar" + middlewares = ["foobar", "foobar"] - [Providers.File] - Directory = "foobar" - Watch = true - Filename = "foobar" - DebugLogGeneratedTemplate = true - TraefikFile = "foobar" +[log] + level = "foobar" + filePath = "foobar" + format = "foobar" - [Providers.Marathon] - Trace = true - Watch = true - Endpoint = "foobar" - DefaultRule = "foobar" - ExposedByDefault = true - DCOSToken = "foobar" - DialerTimeout = 42 - ResponseHeaderTimeout = 42 - TLSHandshakeTimeout = 42 - KeepAlive = 42 - ForceTaskHostname = true - RespectReadinessChecks = true - Constraints = "foobar" - - [Providers.Marathon.TLS] - CA = "foobar" - CAOptional = true - Cert = "foobar" - Key = "foobar" - InsecureSkipVerify = true - [Providers.Marathon.Basic] - HTTPBasicAuthUser = "foobar" - HTTPBasicPassword = "foobar" - - [Providers.Kubernetes] - Endpoint = "foobar" - Token = "foobar" - CertAuthFilePath = "foobar" - DisablePassHostHeaders = true - Namespaces = ["foobar", "foobar"] - LabelSelector = "foobar" - IngressClass = "foobar" - [Providers.Kubernetes.IngressEndpoint] - IP = "foobar" - Hostname = "foobar" - PublishedService = "foobar" - - [Providers.KubernetesCRD] - Endpoint = "foobar" - Token = "foobar" - CertAuthFilePath = "foobar" - DisablePassHostHeaders = true - Namespaces = ["foobar", "foobar"] - LabelSelector = "foobar" - IngressClass = "foobar" - - [Providers.Rest] - EntryPoint = "foobar" - - [Providers.Rancher] - Watch = true - DefaultRule = "foobar" - ExposedByDefault = true - EnableServiceHealthFilter = true - RefreshSeconds = 42 - IntervalPoll = true - Prefix = "foobar" - Constraints = "foobar" - -[API] - EntryPoint = "foobar" - Dashboard = true - Middlewares = ["foobar", "foobar"] - [API.Statistics] - RecentErrors = 42 - -[Metrics] - - [Metrics.Prometheus] - Buckets = [42.0, 42.0] - EntryPoint = "foobar" - Middlewares = ["foobar", "foobar"] - - [Metrics.Datadog] - Address = "foobar" - PushInterval = "10s" - - [Metrics.StatsD] - Address = "foobar" - PushInterval = "10s" - - [Metrics.InfluxDB] - Address = "foobar" - Protocol = "foobar" - PushInterval = "10s" - Database = "foobar" - RetentionPolicy = "foobar" - Username = "foobar" - Password = "foobar" - -[Ping] - EntryPoint = "foobar" - Middlewares = ["foobar", "foobar"] - -[Log] - Level = "foobar" - FilePath = "foobar" - Format = "foobar" - -[AccessLog] - FilePath = "foobar" - Format = "foobar" - BufferingSize = 42 - [AccessLog.Filters] - StatusCodes = ["foobar", "foobar"] - RetryAttempts = true - MinDuration = 42 - [AccessLog.Fields] - DefaultMode = "foobar" - [AccessLog.Fields.Names] +[accessLog] + filePath = "foobar" + format = "foobar" + bufferingSize = 42 + [accessLog.filters] + statusCodes = ["foobar", "foobar"] + retryAttempts = true + minDuration = 42 + [accessLog.fields] + defaultMode = "foobar" + [accessLog.fields.names] name0 = "foobar" name1 = "foobar" - [AccessLog.Fields.Headers] - DefaultMode = "foobar" - [AccessLog.Fields.Headers.Names] + [accessLog.fields.headers] + defaultMode = "foobar" + [accessLog.fields.headers.names] name0 = "foobar" name1 = "foobar" -[Tracing] - ServiceName = "foobar" - SpanNameLimit = 42 +[tracing] + serviceName = "foobar" + spanNameLimit = 42 + [tracing.jaeger] + samplingServerURL = "foobar" + samplingType = "foobar" + samplingParam = 42.0 + localAgentHostPort = "foobar" + gen128Bit = true + propagation = "foobar" + traceContextHeaderName = "foobar" + [tracing.zipkin] + httpEndpoint = "foobar" + sameSpan = true + id128Bit = true + debug = true + sampleRate = 42.0 + [tracing.dataDog] + localAgentHostPort = "foobar" + globalTag = "foobar" + debug = true + prioritySampling = true + traceIDHeaderName = "foobar" + parentIDHeaderName = "foobar" + samplingPriorityHeaderName = "foobar" + bagagePrefixHeaderName = "foobar" + [tracing.instana] + localAgentHost = "foobar" + localAgentPort = 42 + logLevel = "foobar" + [tracing.haystack] + localAgentHost = "foobar" + localAgentPort = 42 + globalTag = "foobar" + traceIDHeaderName = "foobar" + parentIDHeaderName = "foobar" + spanIDHeaderName = "foobar" - [Tracing.Jaeger] - SamplingServerURL = "foobar" - SamplingType = "foobar" - SamplingParam = 42.0 - LocalAgentHostPort = "foobar" - Gen128Bit = true - Propagation = "foobar" - TraceContextHeaderName = "foobar" +[hostResolver] + cnameFlattening = true + resolvConfig = "foobar" + resolvDepth = 42 - [Tracing.Zipkin] - HTTPEndpoint = "foobar" - SameSpan = true - ID128Bit = true - Debug = true - SampleRate = 42.0 +[acme] + email = "foobar" + acmeLogging = true + caServer = "foobar" + storage = "foobar" + entryPoint = "foobar" + keyType = "foobar" + onHostRule = true + [acme.dnsChallenge] + provider = "foobar" + delayBeforeCheck = 42 + resolvers = ["foobar", "foobar"] + disablePropagationCheck = true + [acme.httpChallenge] + entryPoint = "foobar" + [acme.tlsChallenge] - [Tracing.DataDog] - LocalAgentHostPort = "foobar" - GlobalTag = "foobar" - Debug = true - PrioritySampling = true - TraceIDHeaderName = "foobar" - ParentIDHeaderName = "foobar" - SamplingPriorityHeaderName = "foobar" - BagagePrefixHeaderName = "foobar" + [[acme.domains]] + main = "foobar" + sans = ["foobar", "foobar"] - [Tracing.Instana] - LocalAgentHost = "foobar" - LocalAgentPort = 42 - LogLevel = "foobar" - - [Tracing.Haystack] - LocalAgentHost = "foobar" - LocalAgentPort = 42 - GlobalTag = "foobar" - ParentIDHeaderName = "foobar" - SpanIDHeaderName = "foobar" - TraceIDHeaderName = "foobar" - -[HostResolver] - CnameFlattening = true - ResolvConfig = "foobar" - ResolvDepth = 42 - -[ACME] - Email = "foobar" - ACMELogging = true - CAServer = "foobar" - Storage = "foobar" - EntryPoint = "foobar" - KeyType = "foobar" - OnHostRule = true - - [ACME.DNSChallenge] - Provider = "foobar" - DelayBeforeCheck = 42 - Resolvers = ["foobar", "foobar"] - DisablePropagationCheck = true - - [ACME.HTTPChallenge] - EntryPoint = "foobar" - - [ACME.TLSChallenge] - - [[ACME.Domains]] - Main = "foobar" - SANs = ["foobar", "foobar"] - - [[ACME.Domains]] - Main = "foobar" - SANs = ["foobar", "foobar"] + [[acme.domains]] + main = "foobar" + sans = ["foobar", "foobar"] diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index b616be96a..f0ac4f3db 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -1,234 +1,238 @@ global: - checknewversion: true - sendanonymoususage: true -serverstransport: - insecureskipverify: true - rootcas: + checkNewVersion: true + sendAnonymousUsage: true +serversTransport: + insecureSkipVerify: true + rootCAs: - foobar - foobar - maxidleconnsperhost: 42 - forwardingtimeouts: - dialtimeout: 42000000000 - responseheadertimeout: 42000000000 -entrypoints: + maxIdleConnsPerHost: 42 + forwardingTimeouts: + dialTimeout: 42000000000 + responseHeaderTimeout: 42000000000 + idleConnTimeout: 42000000000 +entryPoints: EntryPoint0: address: foobar transport: - lifecycle: - requestacceptgracetimeout: 42000000000 - gracetimeout: 42000000000 - respondingtimeouts: - readtimeout: 42000000000 - writetimeout: 42000000000 - idletimeout: 42000000000 - proxyprotocol: + lifeCycle: + requestAcceptGraceTimeout: 42000000000 + graceTimeOut: 42000000000 + respondingTimeouts: + readTimeout: 42000000000 + writeTimeout: 42000000000 + idleTimeout: 42000000000 + proxyProtocol: insecure: true - trustedips: + trustedIPs: - foobar - foobar - forwardedheaders: + forwardedHeaders: insecure: true - trustedips: + trustedIPs: - foobar - foobar providers: - providersthrottleduration: 42000000000 + providersThrottleDuration: 42000000000 docker: constraints: foobar watch: true endpoint: foobar - defaultrule: foobar + defaultRule: foobar tls: ca: foobar - caoptional: true + caOptional: true cert: foobar key: foobar - insecureskipverify: true - exposedbydefault: true - usebindportip: true - swarmmode: true + insecureSkipVerify: true + exposedByDefault: true + useBindPortIP: true + swarmMode: true network: foobar - swarmmoderefreshseconds: 42000000000 + swarmModeRefreshSeconds: 42000000000 file: directory: foobar watch: true filename: foobar - debugloggeneratedtemplate: true - traefikfile: foobar + debugLogGeneratedTemplate: true + traefikFile: foobar marathon: constraints: foobar trace: true watch: true endpoint: foobar - defaultrule: foobar - exposedbydefault: true - dcostoken: foobar + defaultRule: foobar + exposedByDefault: true + dcosToken: foobar tls: ca: foobar - caoptional: true + caOptional: true cert: foobar key: foobar - insecureskipverify: true - dialertimeout: 42000000000 - responseheadertimeout: 42000000000 - tlshandshaketimeout: 42000000000 - keepalive: 42000000000 - forcetaskhostname: true + insecureSkipVerify: true + dialerTimeout: 42000000000 + responseHeaderTimeout: 42000000000 + tlsHandshakeTimeout: 42000000000 + keepAlive: 42000000000 + forceTaskHostname: true basic: - httpbasicauthuser: foobar - httpbasicpassword: foobar - respectreadinesschecks: true + httpBasicAuthUser: foobar + httpBasicPassword: foobar + respectReadinessChecks: true kubernetes: endpoint: foobar token: foobar - certauthfilepath: foobar - disablepasshostheaders: true + certAuthFilePath: foobar + disablePassHostHeaders: true namespaces: - foobar - foobar - labelselector: foobar - ingressclass: foobar - ingressendpoint: + labelSelector: foobar + ingressClass: foobar + ingressEndpoint: ip: foobar hostname: foobar - publishedservice: foobar - kubernetescrd: + publishedService: foobar + kubernetesCRD: endpoint: foobar token: foobar - certauthfilepath: foobar - disablepasshostheaders: true + certAuthFilePath: foobar + disablePassHostHeaders: true namespaces: - foobar - foobar - labelselector: foobar - ingressclass: foobar + labelSelector: foobar + ingressClass: foobar rest: - entrypoint: foobar + entryPoint: foobar rancher: constraints: foobar watch: true - defaultrule: foobar - exposedbydefault: true - enableservicehealthfilter: true - refreshseconds: 42 - intervalpoll: true + defaultRule: foobar + exposedByDefault: true + enableServiceHealthFilter: true + refreshSeconds: 42 + intervalPoll: true prefix: foobar api: - entrypoint: foobar + entryPoint: foobar dashboard: true - debug: false statistics: - recenterrors: 42 + recentErrors: 42 middlewares: - foobar - foobar - dashboardassets: null metrics: prometheus: buckets: - 42 - 42 - entrypoint: foobar + entryPoint: foobar middlewares: - foobar - foobar - datadog: + dataDog: address: foobar - pushinterval: 10000000000 - statsd: + pushInterval: 10000000000 + statsD: address: foobar - pushinterval: 10000000000 - influxdb: + pushInterval: 10000000000 + influxDB: address: foobar protocol: foobar - pushinterval: 10000000000 + pushInterval: 10000000000 database: foobar - retentionpolicy: foobar + retentionPolicy: foobar username: foobar password: foobar ping: - entrypoint: foobar + entryPoint: foobar middlewares: - foobar - foobar log: level: foobar - filepath: foobar + filePath: foobar format: foobar -accesslog: - filepath: foobar +accessLog: + filePath: foobar format: foobar filters: - statuscodes: + statusCodes: - foobar - foobar - retryattempts: true - minduration: 42000000000 + retryAttempts: true + minDuration: 42000000000 fields: - defaultmode: foobar + defaultMode: foobar names: name0: foobar name1: foobar headers: - defaultmode: foobar + defaultMode: foobar names: name0: foobar name1: foobar - bufferingsize: 42 + bufferingSize: 42 tracing: - backend: foobar - servicename: foobar - spannamelimit: 42 + serviceName: foobar + spanNameLimit: 42 jaeger: - samplingserverurl: foobar - samplingtype: foobar - samplingparam: 42 - localagenthostport: foobar - gen128bit: true + samplingServerURL: foobar + samplingType: foobar + samplingParam: 42 + localAgentHostPort: foobar + gen128Bit: true propagation: foobar - tracecontextheadername: foobar + traceContextHeaderName: foobar zipkin: - httpendpoint: foobar - samespan: true - id128bit: true + httpEndpoint: foobar + sameSpan: true + id128Bit: true debug: true - samplerate: 42 - datadog: - localagenthostport: foobar - globaltag: foobar + sampleRate: 42 + dataDog: + localAgentHostPort: foobar + globalTag: foobar debug: true - prioritysampling: true - traceidheadername: foobar - parentidheadername: foobar - samplingpriorityheadername: foobar - bagageprefixheadername: foobar + prioritySampling: true + traceIDHeaderName: foobar + parentIDHeaderName: foobar + samplingPriorityHeaderName: foobar + bagagePrefixHeaderName: foobar instana: - localagenthost: foobar - localagentport: 42 - loglevel: foobar - haystack: null -hostresolver: - cnameflattening: true - resolvconfig: foobar - resolvdepth: 42 + localAgentHost: foobar + localAgentPort: 42 + logLevel: foobar + haystack: + localAgentHost: foobar + localAgentPort: 42 + globalTag: foobar + traceIDHeaderName: foobar + parentIDHeaderName: foobar + spanIDHeaderName: foobar +hostResolver: + cnameFlattening: true + resolvConfig: foobar + resolvDepth: 42 acme: email: foobar - acmelogging: true - caserver: foobar + acmeLogging: true + caServer: foobar storage: foobar - entrypoint: foobar - keytype: foobar - onhostrule: true - dnschallenge: + entryPoint: foobar + keyType: foobar + onHostRule: true + dnsChallenge: provider: foobar - delaybeforecheck: 42000000000 + delayBeforeCheck: 42000000000 resolvers: - foobar - foobar - disablepropagationcheck: true - httpchallenge: - entrypoint: foobar - tlschallenge: {} + disablePropagationCheck: true + httpChallenge: + entryPoint: foobar + tlsChallenge: {} domains: - main: foobar sans: diff --git a/docs/content/routing/entrypoints.md b/docs/content/routing/entrypoints.md index 976ca244c..78534aa9b 100644 --- a/docs/content/routing/entrypoints.md +++ b/docs/content/routing/entrypoints.md @@ -3,7 +3,7 @@ Opening Connections for Incoming Requests {: .subtitle } -![EntryPoints](../assets/img/entrypoints.png) +![entryPoints](../assets/img/entrypoints.png) EntryPoints are the network entry points into Traefik. They define the port which will receive the requests (whether HTTP or TCP). @@ -12,17 +12,27 @@ They define the port which will receive the requests (whether HTTP or TCP). ??? example "Port 80 only" - ```toml + ```toml tab="File (TOML)" [entryPoints] [entryPoints.web] - address = ":80" + address = ":80" + ``` + + ```yaml tab="File (YAML)" + entryPoints: + web: + address: ":80" + ``` + + ```ini tab="CLI" + --entryPoints.web.address=:80 ``` We define an `entrypoint` called `web` that will listen on port `80`. ??? example "Port 80 & 443" - ```toml + ```toml tab="File (TOML)" [entryPoints] [entryPoints.web] address = ":80" @@ -30,6 +40,20 @@ They define the port which will receive the requests (whether HTTP or TCP). [entryPoints.web-secure] address = ":443" ``` + + ```yaml tab="File (YAML)" + entryPoints: + web: + address: ":80" + + web-secure: + address: ":443" + ``` + + ```ini tab="CLI" + --entryPoints.web.address=:80 + --entryPoints.web-secure.address=:443 + ``` - Two entrypoints are defined: one called `web`, and the other called `web-secure`. - `web` listens on port `80`, and `web-secure` on port `443`. @@ -43,38 +67,63 @@ You can define them using a toml file, CLI arguments, or a key-value store. See the complete reference for the list of available options: -```toml tab="File" +```toml tab="File (TOML)" [entryPoints] [entryPoints.EntryPoint0] - Address = ":8888" - [entryPoints.EntryPoint0.Transport] - [entryPoints.EntryPoint0.Transport.LifeCycle] - RequestAcceptGraceTimeout = 42 - GraceTimeOut = 42 - [entryPoints.EntryPoint0.Transport.RespondingTimeouts] - ReadTimeout = 42 - WriteTimeout = 42 - IdleTimeout = 42 - [entryPoints.EntryPoint0.ProxyProtocol] - Insecure = true - TrustedIPs = ["foobar", "foobar"] - [entryPoints.EntryPoint0.ForwardedHeaders] - Insecure = true - TrustedIPs = ["foobar", "foobar"] + address = ":8888" + [entryPoints.EntryPoint0.transport] + [entryPoints.EntryPoint0.transport.lifeCycle] + requestAcceptGraceTimeout = 42 + graceTimeOut = 42 + [entryPoints.EntryPoint0.transport.respondingTimeouts] + readTimeout = 42 + writeTimeout = 42 + idleTimeout = 42 + [entryPoints.EntryPoint0.proxyProtocol] + insecure = true + trustedIPs = ["foobar", "foobar"] + [entryPoints.EntryPoint0.forwardedHeaders] + insecure = true + trustedIPs = ["foobar", "foobar"] +``` + +```yaml tab="File (YAML)" +entryPoints: + + EntryPoint0: + address: ":8888" + transport: + lifeCycle: + requestAcceptGraceTimeout: 42 + graceTimeOut: 42 + respondingTimeouts: + readTimeout: 42 + writeTimeout: 42 + idleTimeout: 42 + proxyProtocol: + insecure: true + trustedIPs: + - "foobar" + - "foobar" + forwardedHeaders: + insecure: true + trustedIPs: + - "foobar" + - "foobar" ``` ```ini tab="CLI" ---entryPoints.EntryPoint0.Address=:8888 ---entryPoints.EntryPoint0.Transport.LifeCycle.RequestAcceptGraceTimeout=42 ---entryPoints.EntryPoint0.Transport.LifeCycle.GraceTimeOut=42 ---entryPoints.EntryPoint0.Transport.RespondingTimeouts.ReadTimeout=42 ---entryPoints.EntryPoint0.Transport.RespondingTimeouts.WriteTimeout=42 ---entryPoints.EntryPoint0.Transport.RespondingTimeouts.IdleTimeout=42 ---entryPoints.EntryPoint0.ProxyProtocol.Insecure=true ---entryPoints.EntryPoint0.ProxyProtocol.TrustedIPs=foobar,foobar ---entryPoints.EntryPoint0.ForwardedHeaders.Insecure=true ---entryPoints.EntryPoint0.ForwardedHeaders.TrustedIPs=foobar,foobar +--entryPoints.EntryPoint0.address=:8888 +--entryPoints.EntryPoint0.transport.lifeCycle.requestAcceptGraceTimeout=42 +--entryPoints.EntryPoint0.transport.lifeCycle.graceTimeOut=42 +--entryPoints.EntryPoint0.transport.respondingTimeouts.readTimeout=42 +--entryPoints.EntryPoint0.transport.respondingTimeouts.writeTimeout=42 +--entryPoints.EntryPoint0.transport.respondingTimeouts.idleTimeout=42 +--entryPoints.EntryPoint0.proxyProtocol.insecure=true +--entryPoints.EntryPoint0.proxyProtocol.trustedIPs=foobar,foobar +--entryPoints.EntryPoint0.forwardedHeaders.insecure=true +--entryPoints.EntryPoint0.forwardedHeaders.trustedIPs=foobar,foobar ``` ## ProxyProtocol @@ -83,7 +132,7 @@ Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy- ??? example "Enabling Proxy Protocol with Trusted IPs" - ```toml + ```toml tab="File (TOML)" [entryPoints] [entryPoints.web] address = ":80" @@ -92,6 +141,21 @@ Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy- trustedIPs = ["127.0.0.1/32", "192.168.1.7"] ``` + ```yaml tab="File (YAML)" + entryPoints: + web: + address: ":80" + proxyProtocol + trustedIPs: + - "127.0.0.1/32" + - "192.168.1.7" + ``` + + ```ini tab="CLI" + --entryPoints.web.address=:80 + --entryPoints.web.proxyProtocol.trustedIPs=127.0.0.1/32,192.168.1.7 + ``` + IPs in `trustedIPs` only will lead to remote client address replacement: Declare load-balancer IPs or CIDR range here. ??? example "Insecure Mode -- Testing Environment Only" @@ -99,7 +163,7 @@ Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy- In a test environments, you can configure Traefik to trust every incoming connection. Doing so, every remote client address will be replaced (`trustedIPs` won't have any effect) - ```toml + ```toml tab="File (TOML)" [entryPoints] [entryPoints.web] address = ":80" @@ -107,7 +171,20 @@ Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy- [entryPoints.web.proxyProtocol] insecure = true ``` - + + ```yaml tab="File (YAML)" + entryPoints: + web: + address: ":80" + proxyProtocol: + insecure: true + ``` + + ```ini tab="CLI" + --entryPoints.web.address=:80 + --entryPoints.web.proxyProtocol.insecure + ``` + !!! warning "Queuing Traefik behind Another Load Balancer" When queuing Traefik behind another load-balancer, make sure to configure Proxy Protocol on both sides. @@ -119,7 +196,7 @@ You can configure Traefik to trust the forwarded headers information (`X-Forward ??? example "Trusting Forwarded Headers from specific IPs" - ```toml + ```toml tab="File (TOML)" [entryPoints] [entryPoints.web] address = ":80" @@ -128,13 +205,41 @@ You can configure Traefik to trust the forwarded headers information (`X-Forward trustedIPs = ["127.0.0.1/32", "192.168.1.7"] ``` + ```yaml tab="File (YAML)" + entryPoints: + web: + address: ":80" + forwardedHeaders + trustedIPs: + - "127.0.0.1/32" + - "192.168.1.7" + ``` + + ```ini tab="CLI" + --entryPoints.web.address=:80 + --entryPoints.web.forwardedHeaders.trustedIPs=127.0.0.1/32,192.168.1.7 + ``` + ??? example "Insecure Mode -- Always Trusting Forwarded Headers" - ```toml + ```toml tab="File (TOML)" [entryPoints] [entryPoints.web] address = ":80" [entryPoints.web.forwardedHeaders] - insecure = true + insecure = true + ``` + + ```yaml tab="File (YAML)" + entryPoints: + web: + address: ":80" + forwardedHeaders: + insecure: true + ``` + + ```ini tab="CLI" + --entryPoints.web.address=:80 + --entryPoints.web.forwardedHeaders.insecure ``` diff --git a/docs/content/routing/overview.md b/docs/content/routing/overview.md index 072b93f01..39247cda6 100644 --- a/docs/content/routing/overview.md +++ b/docs/content/routing/overview.md @@ -38,10 +38,11 @@ Static configuration: ``` ```yaml tab="YAML" -entrypoints: +entryPoints: web: # Listen on port 8081 for incoming requests address: :8081 + providers: # Enable the file provider to define routers / middlewares / services in a file file: {} @@ -63,13 +64,13 @@ Dynamic configuration: [http.middlewares] # Define an authentication mechanism - [http.middlewares.test-user.basicauth] + [http.middlewares.test-user.basicAuth] users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] [http.services] # Define how to reach an existing service on our infrastructure - [http.services.whoami.loadbalancer] - [[http.services.whoami.loadbalancer.servers]] + [http.services.whoami.loadBalancer] + [[http.services.whoami.loadBalancer.servers]] url = "http://private/whoami-service" ``` @@ -85,16 +86,18 @@ http: - test-user # If the rule matches, forward to the whoami service (declared below) service: whoami + middlewares: # Define an authentication mechanism test-user: basicAuth: users: - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ + services: # Define how to reach an existing service on our infrastructure whoami: - loadbalancer: + loadBalancer: servers: - url: http://private/whoami-service ``` @@ -115,17 +118,17 @@ http: ```toml tab="TOML" [entryPoints] - [entryPoints.web] - # Listen on port 8081 for incoming requests - address = ":8081" + [entryPoints.web] + # Listen on port 8081 for incoming requests + address = ":8081" [providers] - # Enable the file provider to define routers / middlewares / services in a file - [providers.file] + # Enable the file provider to define routers / middlewares / services in a file + [providers.file] ``` ```yaml tab="YAML" - entrypoints: + entryPoints: web: # Listen on port 8081 for incoming requests address: :8081 @@ -139,42 +142,43 @@ http: ```toml tab="TOML" # http routing section [http] - [http.routers] - # Define a connection between requests and services - [http.routers.to-whoami] - rule = "Host(`domain`) && PathPrefix(`/whoami/`)" - # If the rule matches, applies the middleware - middlewares = ["test-user"] - # If the rule matches, forward to the whoami service (declared below) - service = "whoami" + [http.routers] + # Define a connection between requests and services + [http.routers.to-whoami] + rule = "Host(`domain`) && PathPrefix(`/whoami/`)" + # If the rule matches, applies the middleware + middlewares = ["test-user"] + # If the rule matches, forward to the whoami service (declared below) + service = "whoami" - [http.middlewares] - # Define an authentication mechanism - [http.middlewares.test-user.basicauth] - users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] + [http.middlewares] + # Define an authentication mechanism + [http.middlewares.test-user.basicAuth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] - [http.services] - # Define how to reach an existing service on our infrastructure - [http.services.whoami.loadbalancer] - [[http.services.whoami.loadbalancer.servers]] - url = "http://private/whoami-service" + [http.services] + # Define how to reach an existing service on our infrastructure + [http.services.whoami.loadBalancer] + [[http.services.whoami.loadBalancer.servers]] + url = "http://private/whoami-service" - [tcp] - [tcp.routers] - [tcp.routers.to-whoami-tcp] - rule = "HostSNI(`whoami-tcp.traefik.io`)" - service = "whoami-tcp" - [tcp.routers.to-whoami-tcp.tls] + [tcp] + [tcp.routers] + [tcp.routers.to-whoami-tcp] + rule = "HostSNI(`whoami-tcp.traefik.io`)" + service = "whoami-tcp" + [tcp.routers.to-whoami-tcp.tls] - [tcp.services] - [tcp.services.whoami-tcp.loadbalancer] - [[tcp.services.whoami-tcp.loadbalancer.servers]] - address = "xx.xx.xx.xx:xx" + [tcp.services] + [tcp.services.whoami-tcp.loadBalancer] + [[tcp.services.whoami-tcp.loadBalancer.servers]] + address = "xx.xx.xx.xx:xx" ``` ```yaml tab="YAML" # http routing section http: + routers: # Define a connection between requests and services to-whoami: @@ -184,26 +188,30 @@ http: - test-user # If the rule matches, forward to the whoami service (declared below) service: whoami + middlewares: # Define an authentication mechanism test-user: basicAuth: users: - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ + services: # Define how to reach an existing service on our infrastructure whoami: - loadbalancer: + loadBalancer: servers: - url: http://private/whoami-service tcp: + routers: to-whoami-tcp: service: whoami-tcp rule: HostSNI(`whoami-tcp.traefik.io`) + services: whoami-tcp: - loadbalancer: + loadBalancer: servers: - address: xx.xx.xx.xx:xx ``` diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index b59513e75..811783f04 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -12,40 +12,84 @@ In the process, routers may use pieces of [middleware](../../middlewares/overvie ??? example "Requests /foo are Handled by service-foo -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [http.routers] [http.routers.my-router] - rule = "Path(`/foo`)" - service = "service-foo" + rule = "Path(`/foo`)" + service = "service-foo" + ``` + + ```yaml tab="YAML" + http: + routers: + my-router: + rule: "Path(`/foo`)" + service: service-foo ``` ??? example "With a [middleware](../../middlewares/overview.md) -- using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [http.routers] [http.routers.my-router] - rule = "Path(`/foo`)" - middlewares = ["authentication"] # declared elsewhere - service = "service-foo" + rule = "Path(`/foo`)" + # declared elsewhere + middlewares = ["authentication"] + service = "service-foo" + ``` + + ```yaml tab="YAML" + http: + routers: + my-router: + rule: "Path(`/foo`)" + # declared elsewhere + middlewares: + - authentication + service: service-foo ``` ??? example "Forwarding all (non-tls) requests on port 3306 to a database service" - - ```toml - [entryPoints] - [entryPoints.mysql-default] - address = ":80" - [entryPoints.mysql-default] - address = ":3306" + + ```toml tab="TOML" + ## Static configuration ## + + [entryPoints] + [entryPoints.web] + address = ":80" + [entryPoints.mysql-default] + address = ":3306" + + ## Dynamic configuration ## + + [tcp] + [tcp.routers] + [tcp.routers.to-database] + entryPoints = ["mysql-default"] + # Catch every request (only available rule for non-tls routers. See below.) + rule = "HostSNI(`*`)" + service = "database" ``` - ```toml - [tcp] - [tcp.routers] - [tcp.routers.to-database] - entryPoints = ["mysql-default"] - rule = "HostSNI(`*`)" # Catch every request (only available rule for non-tls routers. See below.) - service = "database" + ```yaml tab="YAML" + ## Static configuration ## + + entryPoints: + web: + address: ":80" + mysql-default: + address: ":3306" + + ## Dynamic configuration ## + + tcp: + routers: + to-database: + entryPoints: + - "mysql-default" + # Catch every request (only available rule for non-tls routers. See below.) + rule: "HostSNI(`*`)" + service: database ``` ## Configuring HTTP Routers @@ -56,43 +100,94 @@ If not specified, HTTP routers will accept requests from all defined entry point If you want to limit the router scope to a set of entry points, set the `entryPoints` option. ??? example "Listens to Every EntryPoint" - - ```toml + + ```toml tab="TOML" + ## Static configuration ## + [entryPoints] - [entryPoints.web] - # ... - [entryPoints.web-secure] - # ... - [entryPoints.other] - # ... + [entryPoints.web] + # ... + [entryPoints.web-secure] + # ... + [entryPoints.other] + # ... + + + ## Dynamic configuration ## + + [http.routers] + [http.routers.Router-1] + # By default, routers listen to every entry points + rule = "Host(`traefik.io`)" + service = "service-1" ``` - ```toml - [http.routers] - [http.routers.Router-1] - # By default, routers listen to every entrypoints - rule = "Host(`traefik.io`)" - service = "service-1" + ```yaml tab="YAML" + ## Static configuration ## + + entryPoints: + web: + # ... + web-secure: + # ... + other: + # ... + + ## Dynamic configuration ## + + http: + routers: + Router-1: + # By default, routers listen to every entry points + rule: "Host(`traefik.io`)" + service: "service-1" ``` ??? example "Listens to Specific EntryPoints" - - ```toml + + ```toml tab="TOML" + ## Static configuration ## + [entryPoints] - [entryPoints.web] - # ... - [entryPoints.web-secure] - # ... - [entryPoints.other] - # ... + [entryPoints.web] + # ... + [entryPoints.web-secure] + # ... + [entryPoints.other] + # ... + + ## Dynamic configuration ## + + [http.routers] + [http.routers.Router-1] + # won't listen to entry point web + entryPoints = ["web-secure", "other"] + rule = "Host(`traefik.io`)" + service = "service-1" ``` - ```toml - [http.routers] - [http.routers.Router-1] - entryPoints = ["web-secure", "other"] # won't listen to entrypoint web - rule = "Host(`traefik.io`)" - service = "service-1" + ```yaml tab="YAML" + ## Static configuration ## + + entryPoints: + web: + # ... + web-secure: + # ... + other: + # ... + + ## Dynamic configuration ## + + http: + routers: + Router-1: + # won't listen to entry point web + entryPoints: + - "web-secure" + - "other" + rule: "Host(`traefik.io`)" + service: "service-1" ``` ### Rule @@ -170,12 +265,23 @@ Traefik will terminate the SSL connections (meaning that it will send decrypted ??? example "Configuring the router to accept HTTPS requests only" - ```toml + ```toml tab="TOML" [http.routers] - [http.routers.Router-1] - rule = "Host(`foo-domain`) && Path(`/foo-path/`)" - service = "service-id" - [http.routers.Router-1.tls] # will terminate the TLS request + [http.routers.Router-1] + rule = "Host(`foo-domain`) && Path(`/foo-path/`)" + service = "service-id" + # will terminate the TLS request + [http.routers.Router-1.tls] + ``` + + ```yaml tab="YAML" + http: + routers: + Router-1: + rule: "Host(`foo-domain`) && Path(`/foo-path/`)" + service: service-id + # will terminate the TLS request + tls: {} ``` !!! note "HTTPS & ACME" @@ -192,16 +298,31 @@ Traefik will terminate the SSL connections (meaning that it will send decrypted ??? example "HTTP & HTTPS routes" - ```toml + ```toml tab="TOML" [http.routers] - [http.routers.my-https-router] - rule = "Host(`foo-domain`) && Path(`/foo-path/`)" - service = "service-id" - [http.routers.my-https-router.tls] # will terminate the TLS request + [http.routers.my-https-router] + rule = "Host(`foo-domain`) && Path(`/foo-path/`)" + service = "service-id" + # will terminate the TLS request + [http.routers.my-https-router.tls] - [http.routers.my-http-router] - rule = "Host(`foo-domain`) && Path(`/foo-path/`)" - service = "service-id" + [http.routers.my-http-router] + rule = "Host(`foo-domain`) && Path(`/foo-path/`)" + service = "service-id" + ``` + + ```yaml tab="YAML" + http: + routers: + my-https-router: + rule: "Host(`foo-domain`) && Path(`/foo-path/`)" + service: service-id + # will terminate the TLS request + tls: {} + + my-http-router: + rule: "Host(`foo-domain`) && Path(`/foo-path/`)" + service: service-id ``` #### `Options` @@ -209,23 +330,43 @@ Traefik will terminate the SSL connections (meaning that it will send decrypted The `Options` field enables fine-grained control of the TLS parameters. It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied only if a `Host` rule is defined. -??? example "Configuring the tls options" +??? example "Configuring the TLS options" - ```toml + ```toml tab="TOML" [http.routers] - [http.routers.Router-1] - rule = "Host(`foo-domain`) && Path(`/foo-path/`)" - service = "service-id" - [http.routers.Router-1.tls] # will terminate the TLS request - options = "foo" + [http.routers.Router-1] + rule = "Host(`foo-domain`) && Path(`/foo-path/`)" + service = "service-id" + # will terminate the TLS request + [http.routers.Router-1.tls] + options = "foo" [tls.options] [tls.options.foo] - minVersion = "VersionTLS12" - cipherSuites = [ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384" - ] + minVersion = "VersionTLS12" + cipherSuites = [ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384" + ] + ``` + + ```yaml tab="YAML" + http: + routers: + Router-1: + rule: "Host(`foo-domain`) && Path(`/foo-path/`)" + service: service-id + # will terminate the TLS request + tls: + options: foo + + tls: + options: + foo: + minVersion: VersionTLS12 + cipherSuites: + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_RSA_WITH_AES_256_GCM_SHA384 ``` ## Configuring TCP Routers @@ -242,44 +383,100 @@ If you want to limit the router scope to a set of entry points, set the entry po ??? example "Listens to Every Entry Point" - ```toml + ```toml tab="TOML" + ## Static configuration ## + [entryPoints] - [entryPoints.web] - # ... - [entryPoints.web-secure] - # ... - [entryPoints.other] - # ... + [entryPoints.web] + # ... + [entryPoints.web-secure] + # ... + [entryPoints.other] + # ... + + ## Dynamic configuration ## + + [tcp.routers] + [tcp.routers.Router-1] + # By default, routers listen to every entrypoints + rule = "HostSNI(`traefik.io`)" + service = "service-1" + # will route TLS requests (and ignore non tls requests) + [tcp.routers.Router-1.tls] ``` - ```toml - [tcp.routers] - [tcp.routers.Router-1] + ```yaml tab="YAML" + ## Static configuration ## + + entryPoints: + web: + # ... + web-secure: + # ... + other: + # ... + + ## Dynamic configuration ## + + tcp: + routers: + Router-1: # By default, routers listen to every entrypoints - rule = "HostSNI(`traefik.io`)" - service = "service-1" - [tcp.routers.Router-1.tls] # will route TLS requests (and ignore non tls requests) + rule: "HostSNI(`traefik.io`)" + service: "service-1" + # will route TLS requests (and ignore non tls requests) + tls: {} ``` ??? example "Listens to Specific Entry Points" - - ```toml + + ```toml tab="TOML" + ## Static configuration ## + [entryPoints] - [entryPoints.web] - # ... - [entryPoints.web-secure] - # ... - [entryPoints.other] - # ... - ``` - - ```toml + [entryPoints.web] + # ... + [entryPoints.web-secure] + # ... + [entryPoints.other] + # ... + + ## Dynamic configuration ## + [tcp.routers] - [tcp.routers.Router-1] - entryPoints = ["web-secure", "other"] # won't listen to entrypoint web - rule = "HostSNI(`traefik.io`)" - service = "service-1" - [tcp.routers.Router-1.tls] # will route TLS requests (and ignore non tls requests) + [tcp.routers.Router-1] + # won't listen to entry point web + entryPoints = ["web-secure", "other"] + rule = "HostSNI(`traefik.io`)" + service = "service-1" + # will route TLS requests (and ignore non tls requests) + [tcp.routers.Router-1.tls] + ``` + + ```yaml tab="YAML" + ## Static configuration ## + + entryPoints: + web: + # ... + web-secure: + # ... + other: + # ... + + ## Dynamic configuration ## + + tcp: + routers: + Router-1: + # won't listen to entry point web + entryPoints: + - "web-secure" + - "other" + rule: "HostSNI(`traefik.io`)" + service: "service-1" + # will route TLS requests (and ignore non tls requests) + tls: {} ``` ### Rule @@ -312,23 +509,44 @@ Services are the target for the router. ??? example "Configuring TLS Termination" - ```toml + ```toml tab="TOML" [tcp.routers] - [tcp.routers.Router-1] - rule = "HostSNI(`foo-domain`)" - service = "service-id" - [tcp.routers.Router-1.tls] # will terminate the TLS request by default + [tcp.routers.Router-1] + rule = "HostSNI(`foo-domain`)" + service = "service-id" + # will terminate the TLS request by default + [tcp.routers.Router-1.tls] + ``` + + ```yaml tab="YAML" + tcp: + routers: + Router-1: + rule: "HostSNI(`foo-domain`)" + service: service-id + # will terminate the TLS request by default + tld: {} ``` ??? example "Configuring passthrough" - ```toml + ```toml tab="TOML" [tcp.routers] - [tcp.routers.Router-1] - rule = "HostSNI(`foo-domain`)" - service = "service-id" - [tcp.routers.Router-1.tls] - passthrough=true + [tcp.routers.Router-1] + rule = "HostSNI(`foo-domain`)" + service = "service-id" + [tcp.routers.Router-1.tls] + passthrough = true + ``` + + ```yaml tab="YAML" + tcp: + routers: + Router-1: + rule: "HostSNI(`foo-domain`)" + service: service-id + tls: + passthrough: true ``` !!! note "TLS & ACME" @@ -342,19 +560,39 @@ It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied ??? example "Configuring the tls options" - ```toml + ```toml tab="TOML" [tcp.routers] - [tcp.routers.Router-1] - rule = "HostSNI(`foo-domain`)" - service = "service-id" - [tcp.routers.Router-1.tls] # will terminate the TLS request - options = "foo" + [tcp.routers.Router-1] + rule = "HostSNI(`foo-domain`)" + service = "service-id" + # will terminate the TLS request + [tcp.routers.Router-1.tls] + options = "foo" [tls.options] [tls.options.foo] - minVersion = "VersionTLS12" - cipherSuites = [ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384" - ] + minVersion = "VersionTLS12" + cipherSuites = [ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384" + ] + ``` + + ```yaml tab="YAML" + tcp: + routers: + Router-1: + rule: "HostSNI(`foo-domain`)" + service: service-id + # will terminate the TLS request + tls: + options: foo + + tls: + options: + foo: + minVersion: VersionTLS12 + cipherSuites: + - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" + - "TLS_RSA_WITH_AES_256_GCM_SHA384" ``` diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index b3fc7c03d..cef456c93 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -11,25 +11,45 @@ The `Services` are responsible for configuring how to reach the actual services ??? example "Declaring an HTTP Service with Two Servers -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [http.services] - [http.services.my-service.LoadBalancer] - - [[http.services.my-service.LoadBalancer.servers]] - url = "http://private-ip-server-1/" - [[http.services.my-service.LoadBalancer.servers]] - url = "http://private-ip-server-2/" + [http.services.my-service.loadBalancer] + + [[http.services.my-service.loadBalancer.servers]] + url = "http://private-ip-server-1/" + [[http.services.my-service.loadBalancer.servers]] + url = "http://private-ip-server-2/" + ``` + + ```yaml tab="YAML" + http: + services: + my-service: + loadBalancer: + servers: + - url: "http://private-ip-server-1/" + - url: "http://private-ip-server-2/" ``` ??? example "Declaring a TCP Service with Two Servers -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [tcp.services] - [tcp.services.my-service.LoadBalancer] - [[tcp.services.my-service.LoadBalancer.servers]] - address = "xx.xx.xx.xx:xx" - [[tcp.services.my-service.LoadBalancer.servers]] - address = "xx.xx.xx.xx:xx" + [tcp.services.my-service.loadBalancer] + [[tcp.services.my-service.loadBalancer.servers]] + address = "xx.xx.xx.xx:xx" + [[tcp.services.my-service.loadBalancer.servers]] + address = "xx.xx.xx.xx:xx" + ``` + + ```yaml tab="YAML" + tcp: + services: + my-service: + loadBalancer: + servers: + - address: "xx.xx.xx.xx:xx" + - address: "xx.xx.xx.xx:xx" ``` ## Configuring HTTP Services @@ -46,14 +66,24 @@ The load balancers are able to load balance the requests between multiple instan ??? example "Declaring a Service with Two Servers (with Load Balancing) -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [http.services] - [http.services.my-service.LoadBalancer] - - [[http.services.my-service.LoadBalancer.servers]] - url = "http://private-ip-server-1/" - [[http.services.my-service.LoadBalancer.servers]] - url = "http://private-ip-server-2/" + [http.services.my-service.loadBalancer] + + [[http.services.my-service.loadBalancer.servers]] + url = "http://private-ip-server-1/" + [[http.services.my-service.loadBalancer.servers]] + url = "http://private-ip-server-2/" + ``` + + ```yaml tab="YAML" + http: + services: + my-service: + loadBalancer: + servers: + - url: "http://private-ip-server-1/" + - url: "http://private-ip-server-2/" ``` #### Servers @@ -68,11 +98,20 @@ The `url` option point to a specific instance. ??? example "A Service with One Server -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [http.services] - [http.services.my-service.LoadBalancer] - [[http.services.my-service.LoadBalancer.servers]] - url = "http://private-ip-server-1/" + [http.services.my-service.loadBalancer] + [[http.services.my-service.loadBalancer.servers]] + url = "http://private-ip-server-1/" + ``` + + ```yaml tab="YAML" + http: + services: + my-service: + loadBalancer: + servers: + url: "http://private-ip-server-1/" ``` #### Load-balancing @@ -81,13 +120,23 @@ For now, only round robin load balancing is supported: ??? example "Load Balancing -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [http.services] - [http.services.my-service.LoadBalancer] - [[http.services.my-service.LoadBalancer.servers]] - url = "http://private-ip-server-1/" - [[http.services.my-service.LoadBalancer.servers]] - url = "http://private-ip-server-1/" + [http.services.my-service.loadBalancer] + [[http.services.my-service.loadBalancer.servers]] + url = "http://private-ip-server-1/" + [[http.services.my-service.loadBalancer.servers]] + url = "http://private-ip-server-2/" + ``` + + ```yaml tab="YAML" + http: + services: + my-service: + loadBalancer: + servers: + - url: "http://private-ip-server-1/" + - url: "http://private-ip-server-2/" ``` #### Sticky sessions @@ -109,39 +158,56 @@ On subsequent requests, the client is forwarded to the same server. ??? example "Adding Stickiness" - ```toml + ```toml tab="TOML" [http.services] [http.services.my-service] - [http.services.my-service.LoadBalancer.stickiness] - secureCookie = true - httpOnlyCookie = true + [http.services.my-service.loadBalancer.stickiness] + ``` + + ```yaml tab="YAML" + http: + services: + my-service: + loadBalancer: + stickiness: {} ``` ??? example "Adding Stickiness with a Custom Cookie Name" - ```toml + ```toml tab="TOML" [http.services] [http.services.my-service] - [http.services.my-service.LoadBalancer.stickiness] - cookieName = "my_stickiness_cookie_name" - secureCookie = true - httpOnlyCookie = true + [http.services.my-service.loadBalancer.stickiness] + cookieName = "my_stickiness_cookie_name" + secureCookie = true + httpOnlyCookie = true + ``` + + ```yaml tab="YAML" + http: + services: + my-service: + loadBalancer: + stickiness: + cookieName: my_stickiness_cookie_name + secureCookie: true + httpOnlyCookie: true ``` #### Health Check -Configure healthcheck to remove unhealthy servers from the load balancing rotation. +Configure health check to remove unhealthy servers from the load balancing rotation. Traefik will consider your servers healthy as long as they return status codes between `2XX` and `3XX` to the health check requests (carried out every `interval`). Below are the available options for the health check mechanism: -- `path` is appended to the server URL to set the healcheck endpoint. -- `scheme`, if defined, will replace the server URL `scheme` for the healthcheck endpoint -- `hostname`, if defined, will replace the server URL `hostname` for the healthcheck endpoint. -- `port`, if defined, will replace the server URL `port` for the healthcheck endpoint. -- `interval` defines the frequency of the healthcheck calls. -- `timeout` defines the maximum duration Traefik will wait for a healthcheck request before considering the server failed (unhealthy). -- `headers` defines custom headers to be sent to the healthcheck endpoint. +- `path` is appended to the server URL to set the health check endpoint. +- `scheme`, if defined, will replace the server URL `scheme` for the health check endpoint +- `hostname`, if defined, will replace the server URL `hostname` for the health check endpoint. +- `port`, if defined, will replace the server URL `port` for the health check endpoint. +- `interval` defines the frequency of the health check calls. +- `timeout` defines the maximum duration Traefik will wait for a health check request before considering the server failed (unhealthy). +- `headers` defines custom headers to be sent to the health check endpoint. !!! note "Interval & Timeout Format" @@ -153,50 +219,93 @@ Below are the available options for the health check mechanism: Traefik keeps monitoring the health of unhealthy servers. If a server has recovered (returning `2xx` -> `3xx` responses again), it will be added back to the load balacer rotation pool. -??? example "Custom Interval & Timeout -- Using the File Provider" +??? example "Custom Interval & Timeout -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [http.services] [http.servicess.Service-1] - [http.services.Service-1.healthcheck] - path = "/health" - interval = "10s" - timeout = "3s" + [http.services.Service-1.loadBalancer.healthCheck] + path = "/health" + interval = "10s" + timeout = "3s" ``` -??? example "Custom Port -- Using the File Provider" + ```yaml tab="YAML" + http: + servicess: + Service-1: + loadBalancer: + healthCheck: + path: /health + interval: "10s" + timeout: "3s" + ``` - ```toml +??? example "Custom Port -- Using the [File Provider](../../providers/file.md)" + + ```toml tab="TOML" [http.services] [http.services.Service-1] - [http.services.Service-1.healthcheck] - path = "/health" - port = 8080 - ``` - -??? example "Custom Scheme -- Using the File Provider" - - ```toml - [http.services] - [http.services.Service-1] - [http.services.Service-1.healthcheck] - path = "/health" - scheme = "http" - ``` - -??? example "Additional HTTP Headers -- Using the File Provider" - - ```toml - [http.services] - [http.services.Service-1] - [http.servicess.Service-1.healthcheck] - path = "/health" - - [Service.Service-1.healthcheck.headers] - My-Custom-Header = "foo" - My-Header = "bar" + [http.services.Service-1.loadBalancer.healthCheck] + path = "/health" + port = 8080 ``` + ```yaml tab="YAML" + http: + services: + Service-1: + loadBalancer: + healthCheck: + path: /health + port: 8080 + ``` + +??? example "Custom Scheme -- Using the [File Provider](../../providers/file.md)" + + ```toml tab="TOML" + [http.services] + [http.services.Service-1] + [http.services.Service-1.loadBalancer.healthCheck] + path = "/health" + scheme = "http" + ``` + + ```yaml tab="YAML" + http: + services: + Service-1: + loadBalancer: + healthCheck: + path: /health + scheme: http + ``` + +??? example "Additional HTTP Headers -- Using the [File Provider](../../providers/file.md)" + + ```toml tab="TOML" + [http.services] + [http.services.Service-1] + [http.services.Service-1.loadBalancer.healthCheck] + path = "/health" + + [http.services.Service-1.loadBalancer.healthCheck.headers] + My-Custom-Header = "foo" + My-Header = "bar" + ``` + + ```yaml tab="YAML" + http: + services: + Service-1: + loadBalancer: + healthCheck: + path: /health + headers: + My-Custom-Header: foo + My-Header: bar + ``` + ## Configuring TCP Services ### General @@ -211,13 +320,23 @@ The load balancers are able to load balance the requests between multiple instan ??? example "Declaring a Service with Two Servers -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [tcp.services] - [tcp.services.my-service.LoadBalancer] - [[tcp.services.my-service.LoadBalancer.servers]] - address = "xx.xx.xx.xx:xx" - [[tcp.services.my-service.LoadBalancer.servers]] - address = "xx.xx.xx.xx:xx" + [tcp.services.my-service.loadBalancer] + [[tcp.services.my-service.loadBalancer.servers]] + address = "xx.xx.xx.xx:xx" + [[tcp.services.my-service.loadBalancer.servers]] + address = "xx.xx.xx.xx:xx" + ``` + + ```yaml tab="YAML" + tcp: + services: + my-service: + loadBalancer: + servers: + - address: "xx.xx.xx.xx:xx" + - address: "xx.xx.xx.xx:xx" ``` #### Servers @@ -227,9 +346,18 @@ The `address` option (IP:Port) point to a specific instance. ??? example "A Service with One Server -- Using the [File Provider](../../providers/file.md)" - ```toml + ```toml tab="TOML" [tcp.services] - [tcp.services.my-service.LoadBalancer] - [[tcp.services.my-service.LoadBalancer.servers]] - address = "xx.xx.xx.xx:xx" + [tcp.services.my-service.loadBalancer] + [[tcp.services.my-service.loadBalancer.servers]] + address = "xx.xx.xx.xx:xx" + ``` + + ```yaml tab="YAML" + tcp: + services: + my-service: + loadBalancer: + servers: + address: "xx.xx.xx.xx:xx" ``` diff --git a/docs/content/user-guides/marathon.md b/docs/content/user-guides/marathon.md index e1dc501ba..e47489e91 100644 --- a/docs/content/user-guides/marathon.md +++ b/docs/content/user-guides/marathon.md @@ -17,10 +17,10 @@ Traefik tries to detect the configured mode and route traffic to the right IP ad Traefik also attempts to determine the right port (which is a [non-trivial matter in Marathon](https://mesosphere.github.io/marathon/docs/ports.html)). Following is the order by which Traefik tries to identify the port (the first one that yields a positive result will be used): -1. A arbitrary port specified through the `traefik.HTTP.Services.ServiceName.LoadBalancer.server.Port=8080` -1. The task port (possibly indexed through the `traefik.HTTP.Services.ServiceName.LoadBalancer.server.Port=index:0` label, otherwise the first one). -1. The port from the application's `portDefinitions` field (possibly indexed through the `traefik.HTTP.Services.ServiceName.LoadBalancer.server.Port=index:0` label, otherwise the first one). -1. The port from the application's `ipAddressPerTask` field (possibly indexed through the `traefik.HTTP.Services.ServiceName.LoadBalancer.server.Port=index:0` label, otherwise the first one). +1. A arbitrary port specified through the `traefik.http.services.serviceName.loadbalancer.server.port=8080` +1. The task port (possibly indexed through the `traefik.http.services.serviceName.loadbalancer.server.port=index:0` label, otherwise the first one). +1. The port from the application's `portDefinitions` field (possibly indexed through the `traefik.http.services.serviceName.loadbalancer.server.port=index:0` label, otherwise the first one). +1. The port from the application's `ipAddressPerTask` field (possibly indexed through the `traefik.http.services.serviceName.loadbalancer.server.port=index:0` label, otherwise the first one). ## Achieving high availability @@ -47,7 +47,7 @@ Beginning with version 1.4, Traefik respects readiness check results if the Trae !!! note Due to the way readiness check results are currently exposed by the Marathon API, ready tasks may be taken into rotation with a small delay. - It is on the order of one readiness check timeout interval (as configured on the application specifiation) and guarantees that non-ready tasks do not receive traffic prematurely. + It is on the order of one readiness check timeout interval (as configured on the application specification) and guarantees that non-ready tasks do not receive traffic prematurely. If readiness checks are not possible, a current mitigation strategy is to enable [retries](../middlewares/retry.md) and make sure that a sufficient number of healthy application tasks exist so that one retry will likely hit one of those. Apart from its probabilistic nature, the workaround comes at the price of increased latency. @@ -80,7 +80,7 @@ Failure reasons vary broadly and could stretch from unacceptable slowness, a tas There are two mitigaton efforts: 1. Configure [Marathon health checks](https://mesosphere.github.io/marathon/docs/health-checks.html) on each application. -2. Configure Traefik health checks (possibly via the `traefik.HTTP.Services.YourServiceName.LoadBalancer.HealthCheck.*` labels) and make sure they probe with proper frequency. +2. Configure Traefik health checks (possibly via the `traefik.http.services.yourServiceName.loadbalancer.healthcheck.*` labels) and make sure they probe with proper frequency. The Marathon health check makes sure that applications once deemed dysfunctional are being rescheduled to different slaves. However, they might take a while to get triggered and the follow-up processes to complete. diff --git a/integration/fixtures/access_log_config.toml b/integration/fixtures/access_log_config.toml index bd27bbf48..19f5416e3 100644 --- a/integration/fixtures/access_log_config.toml +++ b/integration/fixtures/access_log_config.toml @@ -1,10 +1,10 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "ERROR" -filePath = "traefik.log" + level = "ERROR" + filePath = "traefik.log" [accessLog] filePath = "access.log" @@ -24,7 +24,7 @@ filePath = "traefik.log" [api] [providers] - [providers.docker] - exposedByDefault = false - defaultRule = "Host(`{{ normalize .Name }}.docker.local`)" - watch = true + [providers.docker] + exposedByDefault = false + defaultRule = "Host(`{{ normalize .Name }}.docker.local`)" + watch = true diff --git a/integration/fixtures/acme/acme_base.toml b/integration/fixtures/acme/acme_base.toml index 9d7deab1b..0628cc57b 100644 --- a/integration/fixtures/acme/acme_base.toml +++ b/integration/fixtures/acme/acme_base.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -40,11 +40,13 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.services] - [http.services.test.loadbalancer] - [[http.services.test.loadbalancer.servers]] + [http.services.test.loadBalancer] + [[http.services.test.loadBalancer.servers]] url = "http://127.0.0.1:9010" [http.routers] diff --git a/integration/fixtures/acme/acme_tls.toml b/integration/fixtures/acme/acme_tls.toml index b7ffe5477..a977c21ac 100644 --- a/integration/fixtures/acme/acme_tls.toml +++ b/integration/fixtures/acme/acme_tls.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -40,19 +40,21 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.services] - [http.services.test.loadbalancer] - [[http.services.test.loadbalancer.servers]] - url = "http://127.0.0.1:9010" + [http.services.test.loadBalancer] + [[http.services.test.loadBalancer.servers]] + url = "http://127.0.0.1:9010" [http.routers] [http.routers.test] - entryPoints = ["web-secure"] - rule = "Host(`traefik.acme.wtf`)" - service = "test" - [http.routers.test.tls] + entryPoints = ["web-secure"] + rule = "Host(`traefik.acme.wtf`)" + service = "test" + [http.routers.test.tls] [tls.stores] [tls.stores.default.defaultCertificate] diff --git a/integration/fixtures/acme/acme_tls_dynamic.toml b/integration/fixtures/acme/acme_tls_dynamic.toml index 2de71cca5..a538796ba 100644 --- a/integration/fixtures/acme/acme_tls_dynamic.toml +++ b/integration/fixtures/acme/acme_tls_dynamic.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -36,6 +36,6 @@ level = "DEBUG" [api] [providers] - [providers.file] - filename = "fixtures/acme/certificates.toml" - watch = true + [providers.file] + filename = "fixtures/acme/certificates.toml" + watch = true diff --git a/integration/fixtures/acme/acme_tls_multiple_entrypoints.toml b/integration/fixtures/acme/acme_tls_multiple_entrypoints.toml index 8d8629ddd..757414ee4 100644 --- a/integration/fixtures/acme/acme_tls_multiple_entrypoints.toml +++ b/integration/fixtures/acme/acme_tls_multiple_entrypoints.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -16,7 +16,7 @@ level = "DEBUG" address = ":9000" # FIXME # [entryPoints.traefik.tls] -# [entryPoints.traefik.tls.DefaultCertificate] +# [entryPoints.traefik.tls.defaultCertificate] # certFile = "fixtures/acme/ssl/wildcard.crt" # keyFile = "fixtures/acme/ssl/wildcard.key" diff --git a/integration/fixtures/acme/certificates.toml b/integration/fixtures/acme/certificates.toml index f0a2c8412..4ee5ced2d 100644 --- a/integration/fixtures/acme/certificates.toml +++ b/integration/fixtures/acme/certificates.toml @@ -1,6 +1,6 @@ [http.services] - [http.services.test.loadbalancer] - [[http.services.test.loadbalancer.servers]] + [http.services.test.loadBalancer] + [[http.services.test.loadBalancer.servers]] url = "http://127.0.0.1:9010" [http.routers] diff --git a/integration/fixtures/docker/minimal.toml b/integration/fixtures/docker/minimal.toml index f3c89cba7..4ba52559e 100644 --- a/integration/fixtures/docker/minimal.toml +++ b/integration/fixtures/docker/minimal.toml @@ -1,18 +1,18 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] [providers] - [providers.docker] - endpoint = "{{ .DockerHost }}" - defaultRule = "{{ .DefaultRule }}" - exposedByDefault = false + [providers.docker] + endpoint = "{{ .DockerHost }}" + defaultRule = "{{ .DefaultRule }}" + exposedByDefault = false diff --git a/integration/fixtures/docker/simple.toml b/integration/fixtures/docker/simple.toml index 767abfd82..630fd5549 100644 --- a/integration/fixtures/docker/simple.toml +++ b/integration/fixtures/docker/simple.toml @@ -1,18 +1,18 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] [providers] - [providers.docker] - endpoint = "{{ .DockerHost }}" - defaultRule = "{{ .DefaultRule }}" - exposedByDefault = true + [providers.docker] + endpoint = "{{ .DockerHost }}" + defaultRule = "{{ .DefaultRule }}" + exposedByDefault = true diff --git a/integration/fixtures/error_pages/error.toml b/integration/fixtures/error_pages/error.toml index c4d6d4c32..801b28152 100644 --- a/integration/fixtures/error_pages/error.toml +++ b/integration/fixtures/error_pages/error.toml @@ -1,35 +1,37 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8080" + address = ":8080" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Rule = "Host(`test.local`)" + rule = "Host(`test.local`)" service = "service1" middlewares = ["error"] [http.middlewares] - [http.middlewares.error.errors] - status = ["500-502", "503-599"] - service = "error" - query = "/50x.html" + [http.middlewares.error.errors] + status = ["500-502", "503-599"] + service = "error" + query = "/50x.html" [http.services] - [http.services.service1.loadbalancer] + [http.services.service1.loadBalancer] passHostHeader = true - [[http.services.service1.loadbalancer.servers]] - url = "http://{{.Server1}}:8989474" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.Server1}}:8989474" - [http.services.error.loadbalancer] - [[http.services.error.loadbalancer.servers]] - url = "http://{{.Server2}}:80" + [http.services.error.loadBalancer] + [[http.services.error.loadBalancer.servers]] + url = "http://{{.Server2}}:80" diff --git a/integration/fixtures/error_pages/simple.toml b/integration/fixtures/error_pages/simple.toml index f34230ff2..284ad1779 100644 --- a/integration/fixtures/error_pages/simple.toml +++ b/integration/fixtures/error_pages/simple.toml @@ -1,35 +1,37 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8080" + address = ":8080" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Rule = "Host(`test.local`)" - service = "service1" - middlewares = ["error"] + rule = "Host(`test.local`)" + service = "service1" + middlewares = ["error"] [http.middlewares] - [http.middlewares.error.errors] - status = ["500-502", "503-599"] - service = "error" - query = "/50x.html" + [http.middlewares.error.errors] + status = ["500-502", "503-599"] + service = "error" + query = "/50x.html" [http.services] - [http.services.service1.loadbalancer] + [http.services.service1.loadBalancer] passHostHeader = true - [[http.services.service1.loadbalancer.servers]] - url = "http://{{.Server1}}:80" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.Server1}}:80" - [http.services.error.loadbalancer] - [[http.services.error.loadbalancer.servers]] - url = "http://{{.Server2}}:80" + [http.services.error.loadBalancer] + [[http.services.error.loadBalancer.servers]] + url = "http://{{.Server2}}:80" diff --git a/integration/fixtures/file/56-simple-panic.toml b/integration/fixtures/file/56-simple-panic.toml index fd94864de..a890ef539 100644 --- a/integration/fixtures/file/56-simple-panic.toml +++ b/integration/fixtures/file/56-simple-panic.toml @@ -1,14 +1,13 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" - + address = ":8000" [providers] - [providers.file] + [providers.file] diff --git a/integration/fixtures/file/dir/simple1.toml b/integration/fixtures/file/dir/simple1.toml index 0fd29bce1..2506bca2f 100644 --- a/integration/fixtures/file/dir/simple1.toml +++ b/integration/fixtures/file/dir/simple1.toml @@ -4,6 +4,6 @@ service = "service1" [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://172.17.0.2:80" diff --git a/integration/fixtures/file/dir/simple2.toml b/integration/fixtures/file/dir/simple2.toml index b7c92dc0b..a9c390bee 100644 --- a/integration/fixtures/file/dir/simple2.toml +++ b/integration/fixtures/file/dir/simple2.toml @@ -4,6 +4,6 @@ service = "service2" [http.services] - [http.services.service2.loadbalancer] - [[http.services.service2.loadbalancer.servers]] + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] url = "http://172.17.0.123:80" diff --git a/integration/fixtures/file/directory.toml b/integration/fixtures/file/directory.toml index 9bde5a91e..b60354f0f 100644 --- a/integration/fixtures/file/directory.toml +++ b/integration/fixtures/file/directory.toml @@ -1,14 +1,14 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [providers] - [providers.file] - directory = "fixtures/file/dir/" + [providers.file] + directory = "fixtures/file/dir/" diff --git a/integration/fixtures/file/simple-hosts.toml b/integration/fixtures/file/simple-hosts.toml index 2aea9d96b..91d379c01 100644 --- a/integration/fixtures/file/simple-hosts.toml +++ b/integration/fixtures/file/simple-hosts.toml @@ -1,16 +1,18 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] address = ":8000" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -22,6 +24,6 @@ level = "DEBUG" service = "service1" [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] - URL = "{{.Server}}" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "{{.Server}}" diff --git a/integration/fixtures/file/simple.toml b/integration/fixtures/file/simple.toml index e152729a2..96a6dea17 100644 --- a/integration/fixtures/file/simple.toml +++ b/integration/fixtures/file/simple.toml @@ -1,16 +1,18 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] address = ":8000" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -23,19 +25,19 @@ level = "DEBUG" service = "service1" [http.middlewares] - [http.middlewares.circuitbreaker.circuitbreaker] + [http.middlewares.circuitbreaker.circuitBreaker] expression = "NetworkErrorRatio() > 0.5" [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://172.17.0.2:80" - [[http.services.service1.loadbalancer.servers]] + [[http.services.service1.loadBalancer.servers]] url = "http://172.17.0.3:80" [http.services.service2] - [http.services.service2.loadbalancer] - [[http.services.service2.loadbalancer.servers]] + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] url = "http://172.17.0.4:80" - [[http.services.service2.loadbalancer.servers]] + [[http.services.service2.loadBalancer.servers]] url = "http://172.17.0.5:80" diff --git a/integration/fixtures/grpc/config.toml b/integration/fixtures/grpc/config.toml index b38ab2ffa..7e8277d8a 100644 --- a/integration/fixtures/grpc/config.toml +++ b/integration/fixtures/grpc/config.toml @@ -1,12 +1,12 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport] -rootCAs = [ """{{ .CertContent }}""" ] + rootCAs = [ """{{ .CertContent }}""" ] [entryPoints] [entryPoints.web-secure] @@ -15,7 +15,9 @@ rootCAs = [ """{{ .CertContent }}""" ] [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -24,11 +26,11 @@ rootCAs = [ """{{ .CertContent }}""" ] [http.routers.router1.tls] [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = """{{ .CertContent }}""" keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/grpc/config_h2c.toml b/integration/fixtures/grpc/config_h2c.toml index b9d317e39..096a20e78 100644 --- a/integration/fixtures/grpc/config_h2c.toml +++ b/integration/fixtures/grpc/config_h2c.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -12,7 +12,9 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -20,6 +22,6 @@ level = "DEBUG" service = "service1" [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "h2c://127.0.0.1:{{ .GRPCServerPort }}" diff --git a/integration/fixtures/grpc/config_h2c_termination.toml b/integration/fixtures/grpc/config_h2c_termination.toml index 71d3aec6b..ee48c3334 100644 --- a/integration/fixtures/grpc/config_h2c_termination.toml +++ b/integration/fixtures/grpc/config_h2c_termination.toml @@ -1,19 +1,20 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] address = ":4443" - [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -22,11 +23,11 @@ level = "DEBUG" [http.routers.router1.tls] [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] - url = "h2c://127.0.0.1:{{ .GRPCServerPort }}" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "h2c://127.0.0.1:{{ .GRPCServerPort }}" [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = """{{ .CertContent }}""" keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/grpc/config_insecure.toml b/integration/fixtures/grpc/config_insecure.toml index ce4c7fb4b..053cc4b63 100644 --- a/integration/fixtures/grpc/config_insecure.toml +++ b/integration/fixtures/grpc/config_insecure.toml @@ -1,12 +1,12 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport] -insecureSkipVerify = true + insecureSkipVerify = true [entryPoints] [entryPoints.web-secure] @@ -15,7 +15,9 @@ insecureSkipVerify = true [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -24,11 +26,11 @@ insecureSkipVerify = true [http.routers.router1.tls] [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = """{{ .CertContent }}""" keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/grpc/config_retry.toml b/integration/fixtures/grpc/config_retry.toml index f88706400..72f5b5e09 100644 --- a/integration/fixtures/grpc/config_retry.toml +++ b/integration/fixtures/grpc/config_retry.toml @@ -1,21 +1,23 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport] -rootCAs = [ """{{ .CertContent }}""" ] + rootCAs = [ """{{ .CertContent }}""" ] [entryPoints] [entryPoints.web-secure] - address = ":4443" + address = ":4443" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -26,16 +28,16 @@ rootCAs = [ """{{ .CertContent }}""" ] [http.middlewares] [http.middlewares.retryer.retry] - Attempts = 2 + attempts = 2 [http.services] - [http.services.service1.loadbalancer] - [http.services.service1.loadbalancer.responseForwarding] - flushInterval="1ms" - [[http.services.service1.loadbalancer.servers]] + [http.services.service1.loadBalancer] + [http.services.service1.loadBalancer.responseForwarding] + flushInterval = "1ms" + [[http.services.service1.loadBalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = """{{ .CertContent }}""" keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/headers/basic.toml b/integration/fixtures/headers/basic.toml index 750c5375b..5ed0ab4ba 100644 --- a/integration/fixtures/headers/basic.toml +++ b/integration/fixtures/headers/basic.toml @@ -1,16 +1,18 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] address = ":8000" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -18,6 +20,6 @@ level = "DEBUG" service = "service1" [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://172.17.0.2:80" diff --git a/integration/fixtures/headers/cors.toml b/integration/fixtures/headers/cors.toml index 91166e52c..7cc707cab 100644 --- a/integration/fixtures/headers/cors.toml +++ b/integration/fixtures/headers/cors.toml @@ -1,16 +1,18 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] address = ":8000" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -18,13 +20,13 @@ level = "DEBUG" service = "service1" [http.middlewares] - [http.middlewares.cors.Headers] - AccessControlAllowMethods= ["GET", "OPTIONS", "PUT"] - AccessControlAllowOrigin = "origin-list-or-null" - AccessControlMaxAge = 100 - AddVaryHeader = true + [http.middlewares.cors.headers] + accessControlAllowMethods= ["GET", "OPTIONS", "PUT"] + accessControlAllowOrigin = "origin-list-or-null" + accessControlMaxAge = 100 + addVaryHeader = true [http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://172.17.0.2:80" diff --git a/integration/fixtures/healthcheck/multiple-entrypoints.toml b/integration/fixtures/healthcheck/multiple-entrypoints.toml index 42b11861c..12e543186 100644 --- a/integration/fixtures/healthcheck/multiple-entrypoints.toml +++ b/integration/fixtures/healthcheck/multiple-entrypoints.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.http1] @@ -14,20 +14,22 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] service = "service1" - Rule = "Host(`test.localhost`)" + rule = "Host(`test.localhost`)" [http.services] - [http.services.service1.loadbalancer] - [http.services.service1.loadbalancer.healthcheck] + [http.services.service1.loadBalancer] + [http.services.service1.loadBalancer.healthcheck] path = "/health" interval = "1s" timeout = "0.9s" - [[http.services.service1.loadbalancer.servers]] + [[http.services.service1.loadBalancer.servers]] url = "http://{{.Server1}}:80" - [[http.services.service1.loadbalancer.servers]] + [[http.services.service1.loadBalancer.servers]] url = "http://{{.Server2}}:80" diff --git a/integration/fixtures/healthcheck/port_overload.toml b/integration/fixtures/healthcheck/port_overload.toml index 8b17a4724..892e5b463 100644 --- a/integration/fixtures/healthcheck/port_overload.toml +++ b/integration/fixtures/healthcheck/port_overload.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -12,19 +12,21 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] service = "service1" - Rule = "Host(`test.localhost`)" + rule = "Host(`test.localhost`)" [http.services] - [http.services.service1.loadbalancer] - [http.services.service1.loadbalancer.healthcheck] + [http.services.service1.loadBalancer] + [http.services.service1.loadBalancer.healthcheck] path = "/health" port = 80 interval = "1s" timeout = "0.9s" - [[http.services.service1.loadbalancer.servers]] + [[http.services.service1.loadBalancer.servers]] url = "http://{{.Server1}}:81" diff --git a/integration/fixtures/healthcheck/simple.toml b/integration/fixtures/healthcheck/simple.toml index 0e0cea877..0109337fc 100644 --- a/integration/fixtures/healthcheck/simple.toml +++ b/integration/fixtures/healthcheck/simple.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -12,20 +12,22 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] service = "service1" - Rule = "Host(`test.localhost`)" + rule = "Host(`test.localhost`)" [http.services] - [http.services.service1.loadbalancer] - [http.services.service1.loadbalancer.healthcheck] + [http.services.service1.loadBalancer] + [http.services.service1.loadBalancer.healthcheck] path = "/health" interval = "1s" timeout = "0.9s" - [[http.services.service1.loadbalancer.servers]] + [[http.services.service1.loadBalancer.servers]] url = "http://{{.Server1}}:80" - [[http.services.service1.loadbalancer.servers]] + [[http.services.service1.loadBalancer.servers]] url = "http://{{.Server2}}:80" diff --git a/integration/fixtures/https/clientca/https_1ca1config.toml b/integration/fixtures/https/clientca/https_1ca1config.toml index 063b4f22d..ba62c4fd0 100644 --- a/integration/fixtures/https/clientca/https_1ca1config.toml +++ b/integration/fixtures/https/clientca/https_1ca1config.toml @@ -1,48 +1,50 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] - address = ":4443" + address = ":4443" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Host(`snitest.com`)" + service = "service1" + rule = "Host(`snitest.com`)" [http.routers.router1.tls] [http.routers.router2] - Service = "service2" - Rule = "Host(`snitest.org`)" + service = "service2" + rule = "Host(`snitest.org`)" [http.routers.router2.tls] [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9010" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "http://127.0.0.1:9010" [http.services.service2] - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9020" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "http://127.0.0.1:9020" [[tls.certificates]] - certFile = "fixtures/https/snitest.com.cert" - keyFile = "fixtures/https/snitest.com.key" + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" [[tls.certificates]] - certFile = "fixtures/https/snitest.org.cert" - keyFile = "fixtures/https/snitest.org.key" + certFile = "fixtures/https/snitest.org.cert" + keyFile = "fixtures/https/snitest.org.key" [tls.options] [tls.options.default.ClientCA] diff --git a/integration/fixtures/https/clientca/https_2ca1config.toml b/integration/fixtures/https/clientca/https_2ca1config.toml index e09d2c006..848b4ace9 100644 --- a/integration/fixtures/https/clientca/https_2ca1config.toml +++ b/integration/fixtures/https/clientca/https_2ca1config.toml @@ -1,49 +1,51 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] - address = ":4443" + address = ":4443" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Host(`snitest.com`)" + service = "service1" + rule = "Host(`snitest.com`)" [http.routers.router1.tls] [http.routers.router2] - Service = "service2" - Rule = "Host(`snitest.org`)" + service = "service2" + rule = "Host(`snitest.org`)" [http.routers.router2.tls] [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9010" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "http://127.0.0.1:9010" [http.services.service2] - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9020" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "http://127.0.0.1:9020" [[tls.certificates]] - certFile = "fixtures/https/snitest.com.cert" - keyFile = "fixtures/https/snitest.com.key" + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" [[tls.certificates]] certFile = "fixtures/https/snitest.org.cert" keyFile = "fixtures/https/snitest.org.key" [tls.options] - [tls.options.default.ClientCA] + [tls.options.default.clientCA] files = ["fixtures/https/clientca/ca1and2.crt"] \ No newline at end of file diff --git a/integration/fixtures/https/clientca/https_2ca2config.toml b/integration/fixtures/https/clientca/https_2ca2config.toml index 138ac2a18..6340cac13 100644 --- a/integration/fixtures/https/clientca/https_2ca2config.toml +++ b/integration/fixtures/https/clientca/https_2ca2config.toml @@ -1,39 +1,41 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] - address = ":4443" + address = ":4443" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Host(`snitest.com`)" + service = "service1" + rule = "Host(`snitest.com`)" [http.routers.router1.tls] [http.routers.router2] - Service = "service2" - Rule = "Host(`snitest.org`)" + service = "service2" + rule = "Host(`snitest.org`)" [http.routers.router2.tls] [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9010" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "http://127.0.0.1:9010" [http.services.service2] - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9020" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "http://127.0.0.1:9020" [[tls.certificates]] certFile = "fixtures/https/snitest.com.cert" @@ -44,6 +46,6 @@ level = "DEBUG" keyFile = "fixtures/https/snitest.org.key" [tls.options] - [tls.options.default.ClientCA] + [tls.options.default.clientCA] files = ["fixtures/https/clientca/ca1.crt", "fixtures/https/clientca/ca2.crt"] optional = false diff --git a/integration/fixtures/https/dynamic_https.toml b/integration/fixtures/https/dynamic_https.toml index 65bfe163f..6ada7c2f5 100644 --- a/integration/fixtures/https/dynamic_https.toml +++ b/integration/fixtures/https/dynamic_https.toml @@ -11,30 +11,30 @@ [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://127.0.0.1:9010" [http.services.service2] - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] url = "http://127.0.0.1:9020" # bad certificates to validate the loop on the certificate appending [[tls.certificates]] - # bad content - certFile = """-----BEGIN CERTIFICATE----- + # bad content + certFile = """-----BEGIN CERTIFICATE----- MIIC/zCCAeegAwIBAgIJALAYHG/vGqWEMA0GCSqGSIb3DQEBBQUAMBYxFDASBgNV -----END CERTIFICATE-----""" - # bad content - keyFile = """-----BEGIN RSA PRIVATE KEY----- + # bad content + keyFile = """-----BEGIN RSA PRIVATE KEY----- wihZ13e3i5UQEYuoRcH1RUd1wyYoBSKuQnsT2WwVZ1wlXSYaELAbQgaI9NtfBA0G eRG3DaVpez4DQVupZDHMgxJUYqqKynUj6GD1YiaxGROj3TYCu6e7OxyhalhCllSu w/X5M802XqzLjeec5zHoZDfknnAkgR9MsxZYmZPFaDyL6GOKUB8= -----END RSA PRIVATE KEY-----""" [[tls.certificates]] - certFile = """-----BEGIN CERTIFICATE----- + certFile = """-----BEGIN CERTIFICATE----- MIIC/zCCAeegAwIBAgIJALAYHG/vGqWEMA0GCSqGSIb3DQEBBQUAMBYxFDASBgNV BAMMC3NuaXRlc3Qub3JnMB4XDTE1MTEyMzIyMDU0NFoXDTI1MTEyMDIyMDU0NFow FjEUMBIGA1UEAwwLc25pdGVzdC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw @@ -53,7 +53,7 @@ FJTkElnxtELAGHoIwZ+bKprnexefpn9UW84VJvJ2crSR63vBvdTrgsrEGW6kQj1I k5fvuuXbIc979pQOoO03zG0S7Wpmpsw+9dQB9TOxGITOLfCZwEuIhnv+M9lLqCks 7H2A -----END CERTIFICATE-----""" - keyFile = """-----BEGIN RSA PRIVATE KEY----- + keyFile = """-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAvG9kL+vF57+MICehzbqcQAUlAOSl5r/YO6cMLBTEjiteaNqh hc8f8fZaCIuaTCGCMuElcCTa2FIu+9pwmDKkiFV5cHLfwhO9I9iW9oHiB7t4x2xV l67lm1tbRhlGM757DlM4jxN6y1mvzTmzWCy5VCiWsXx68Z6biqUFLF86C5duXCRF diff --git a/integration/fixtures/https/dynamic_https_sni.toml b/integration/fixtures/https/dynamic_https_sni.toml index c01ae8786..2a7ff45fa 100644 --- a/integration/fixtures/https/dynamic_https_sni.toml +++ b/integration/fixtures/https/dynamic_https_sni.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] @@ -15,6 +15,6 @@ level = "DEBUG" [api] [providers] - [providers.file] - fileName = "{{.DynamicConfFileName}}" - watch = true + [providers.file] + fileName = "{{.DynamicConfFileName}}" + watch = true diff --git a/integration/fixtures/https/dynamic_https_sni_default_cert.toml b/integration/fixtures/https/dynamic_https_sni_default_cert.toml index 50efab1f4..e45d40076 100644 --- a/integration/fixtures/https/dynamic_https_sni_default_cert.toml +++ b/integration/fixtures/https/dynamic_https_sni_default_cert.toml @@ -1,18 +1,20 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] - address = ":4443" + address = ":4443" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -27,8 +29,8 @@ level = "DEBUG" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://127.0.0.1:9010" [[tls.certificates]] @@ -40,6 +42,6 @@ level = "DEBUG" keyFile = "fixtures/https/www.snitest.com.key" [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = "fixtures/https/snitest.com.cert" keyFile = "fixtures/https/snitest.com.key" diff --git a/integration/fixtures/https/https_redirect.toml b/integration/fixtures/https/https_redirect.toml index b072200b1..eed285020 100644 --- a/integration/fixtures/https/https_redirect.toml +++ b/integration/fixtures/https/https_redirect.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -17,6 +17,8 @@ level = "DEBUG" [providers] [providers.file] +## dynamic configuration ## + [http.routers] [http.routers.router1] entryPoints = [ "web" ] @@ -139,34 +141,34 @@ level = "DEBUG" [http.routers.router10TLS.tls] [http.middlewares] - [http.middlewares.api-strip.StripPrefix] - prefixes = ["/api"] - [http.middlewares.api-slash-strip.StripPrefix] - prefixes = ["/api/"] - [http.middlewares.foo-add-prefix.AddPrefix] - prefix = "/foo" - [http.middlewares.foo-slash-add-prefix.AddPrefix] - prefix = "/foo/" - [http.middlewares.id-strip-regex-prefix.StripPrefixRegex] - regex = ["/{id:[a-z]+}"] - [http.middlewares.id-slash-strip-regex-prefix.StripPrefixRegex] - regex = ["/{id:[a-z]+}/"] - [http.middlewares.api-regex-replace.ReplacePathRegex] - regex = "/api" - replacement = "/" - [http.middlewares.api-slash-regex-replace.ReplacePathRegex] - regex = "/api/" - replacement = "/" - [http.middlewares.api-replace-path.ReplacePath] - path = "/api" - [http.middlewares.api-slash-replace-path.ReplacePath] - path = "/api/" + [http.middlewares.api-strip.stripPrefix] + prefixes = ["/api"] + [http.middlewares.api-slash-strip.stripPrefix] + prefixes = ["/api/"] + [http.middlewares.foo-add-prefix.addPrefix] + prefix = "/foo" + [http.middlewares.foo-slash-add-prefix.addPrefix] + prefix = "/foo/" + [http.middlewares.id-strip-regex-prefix.stripPrefixRegex] + regex = ["/{id:[a-z]+}"] + [http.middlewares.id-slash-strip-regex-prefix.stripPrefixRegex] + regex = ["/{id:[a-z]+}/"] + [http.middlewares.api-regex-replace.replacePathRegex] + regex = "/api" + replacement = "/" + [http.middlewares.api-slash-regex-replace.replacePathRegex] + regex = "/api/" + replacement = "/" + [http.middlewares.api-replace-path.replacePath] + path = "/api" + [http.middlewares.api-slash-replace-path.replacePath] + path = "/api/" [http.middlewares.redirect-https.redirectScheme] - scheme = "https" - port = "8443" + scheme = "https" + port = "8443" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://127.0.0.1:80" diff --git a/integration/fixtures/https/https_sni.toml b/integration/fixtures/https/https_sni.toml index 3c184436c..561d5f3b5 100644 --- a/integration/fixtures/https/https_sni.toml +++ b/integration/fixtures/https/https_sni.toml @@ -1,40 +1,42 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] - address = ":4443" + address = ":4443" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Host(`snitest.com`)" + service = "service1" + rule = "Host(`snitest.com`)" [http.routers.router1.tls] [http.routers.router2] - Service = "service2" - Rule = "Host(`snitest.org`)" + service = "service2" + rule = "Host(`snitest.org`)" [http.routers.router2.tls] [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9010" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "http://127.0.0.1:9010" [http.services.service2] - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9020" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "http://127.0.0.1:9020" [[tls.certificates]] certFile = "fixtures/https/snitest.com.cert" diff --git a/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml b/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml index 364d77816..28b22f45a 100644 --- a/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml +++ b/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] @@ -12,7 +12,9 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -27,8 +29,8 @@ level = "DEBUG" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://127.0.0.1:9010" [[tls.certificates]] @@ -36,6 +38,6 @@ level = "DEBUG" keyFile = "fixtures/https/uppercase_wildcard.www.snitest.com.key" [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = "fixtures/https/wildcard.snitest.com.cert" keyFile = "fixtures/https/wildcard.snitest.com.key" diff --git a/integration/fixtures/https/https_sni_default_cert.toml b/integration/fixtures/https/https_sni_default_cert.toml index 50efab1f4..e45d40076 100644 --- a/integration/fixtures/https/https_sni_default_cert.toml +++ b/integration/fixtures/https/https_sni_default_cert.toml @@ -1,18 +1,20 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] - address = ":4443" + address = ":4443" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -27,8 +29,8 @@ level = "DEBUG" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://127.0.0.1:9010" [[tls.certificates]] @@ -40,6 +42,6 @@ level = "DEBUG" keyFile = "fixtures/https/www.snitest.com.key" [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = "fixtures/https/snitest.com.cert" keyFile = "fixtures/https/snitest.com.key" diff --git a/integration/fixtures/https/https_sni_strict.toml b/integration/fixtures/https/https_sni_strict.toml index dce7c13a2..1f15bd6cc 100644 --- a/integration/fixtures/https/https_sni_strict.toml +++ b/integration/fixtures/https/https_sni_strict.toml @@ -12,7 +12,9 @@ [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -22,8 +24,8 @@ [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] url = "http://127.0.0.1:9010" [tls.options] @@ -32,7 +34,7 @@ [tls.stores] [tls.stores.default] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = "fixtures/https/snitest.com.cert" keyFile = "fixtures/https/snitest.com.key" diff --git a/integration/fixtures/https/https_tls_options.toml b/integration/fixtures/https/https_tls_options.toml index aad21a2c4..50191c4c3 100644 --- a/integration/fixtures/https/https_tls_options.toml +++ b/integration/fixtures/https/https_tls_options.toml @@ -1,48 +1,50 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web-secure] - address = ":4443" + address = ":4443" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Host(`snitest.com`)" + service = "service1" + rule = "Host(`snitest.com`)" [http.routers.router1.tls] options = "foo" [http.routers.router2] - Service = "service2" - Rule = "Host(`snitest.org`)" + service = "service2" + rule = "Host(`snitest.org`)" [http.routers.router2.tls] options = "bar" [http.routers.router3] - Service = "service2" - Rule = "Host(`snitest.org`)" + service = "service2" + rule = "Host(`snitest.org`)" [http.routers.router3.tls] options = "unknown" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9010" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "http://127.0.0.1:9010" [http.services.service2] - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "http://127.0.0.1:9020" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "http://127.0.0.1:9020" [[tls.certificates]] certFile = "fixtures/https/snitest.com.cert" diff --git a/integration/fixtures/https/rootcas/https.toml b/integration/fixtures/https/rootcas/https.toml index ef89ac863..ae85cfaeb 100644 --- a/integration/fixtures/https/rootcas/https.toml +++ b/integration/fixtures/https/rootcas/https.toml @@ -1,13 +1,13 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport] -# Use certificate in net/internal/testcert.go -rootCAs = [ """ + # Use certificate in net/internal/testcert.go + rootCAs = [ """ -----BEGIN CERTIFICATE----- MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw @@ -26,21 +26,23 @@ fblo6RBxUQ== [entryPoints] [entryPoints.web] - address = ":8081" + address = ":8081" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Path(`/ping`)" + service = "service1" + rule = "Path(`/ping`)" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "{{ .BackendHost }}" + [[http.services.service1.loadBalancer.servers]] + url = "{{ .BackendHost }}" diff --git a/integration/fixtures/https/rootcas/https_with_file.toml b/integration/fixtures/https/rootcas/https_with_file.toml index efdd2fb6e..a37b8544c 100644 --- a/integration/fixtures/https/rootcas/https_with_file.toml +++ b/integration/fixtures/https/rootcas/https_with_file.toml @@ -1,31 +1,33 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport] -# Use certificate in net/internal/testcert.go -rootCAs = [ "fixtures/https/rootcas/local.crt"] + # Use certificate in net/internal/testcert.go + rootCAs = [ "fixtures/https/rootcas/local.crt"] [entryPoints] [entryPoints.web] - address = ":8081" + address = ":8081" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Path(`/ping`)" + service = "service1" + rule = "Path(`/ping`)" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "{{ .BackendHost }}" + [[http.services.service1.loadBalancer.servers]] + url = "{{ .BackendHost }}" diff --git a/integration/fixtures/k8s_crd.toml b/integration/fixtures/k8s_crd.toml index d34f6a03a..21bfa9855 100644 --- a/integration/fixtures/k8s_crd.toml +++ b/integration/fixtures/k8s_crd.toml @@ -1,18 +1,16 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" - -[entryPoints] - [entryPoints.web] - address = ":8000" - [entryPoints.footcp] - address = ":8093" - + level = "DEBUG" [api] -[Providers] - [Providers.KubernetesCRD] \ No newline at end of file +[entryPoints] + [entryPoints.footcp] + address = ":8093" + [entryPoints.web] + address = ":8000" + +[providers.kubernetesCRD] diff --git a/integration/fixtures/k8s_default.toml b/integration/fixtures/k8s_default.toml index 11a131af1..c6bc9b298 100644 --- a/integration/fixtures/k8s_default.toml +++ b/integration/fixtures/k8s_default.toml @@ -1,15 +1,14 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false - -[log] -level = "DEBUG" - -[entryPoints] - [entryPoints.web] - address = ":8000" + checkNewVersion = false + sendAnonymousUsage = false [api] -[Providers] - [Providers.Kubernetes] \ No newline at end of file +[log] + level = "DEBUG" + +[entryPoints] + [entryPoints.web] + address = ":8000" + +[providers.kubernetes] diff --git a/integration/fixtures/log_rotation_config.toml b/integration/fixtures/log_rotation_config.toml index bc2e429ce..e96a0c7c0 100644 --- a/integration/fixtures/log_rotation_config.toml +++ b/integration/fixtures/log_rotation_config.toml @@ -1,37 +1,36 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -filePath = "traefik.log" -level = "ERROR" + filePath = "traefik.log" + level = "ERROR" [accessLog] -filePath = "access.log" + filePath = "access.log" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [entryPoints.api] - address = ":7888" + address = ":7888" [api] -entryPoint = "api" + entryPoint = "api" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## -################################################################ -# rules -################################################################ [http.routers] [http.routers.router1] Service = "service1" - Rule = "Path(`/test1`)" + rule = "Path(`/test1`)" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://127.0.0.1:8081" + [[http.services.service1.loadBalancer.servers]] + url = "http://127.0.0.1:8081" diff --git a/integration/fixtures/marathon/simple.toml b/integration/fixtures/marathon/simple.toml index 01a77d3b1..6ae3c66c0 100644 --- a/integration/fixtures/marathon/simple.toml +++ b/integration/fixtures/marathon/simple.toml @@ -1,21 +1,21 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" -[entryPoints.api] - address = ":9090" + address = ":8000" + [entryPoints.api] + address = ":9090" [api] entryPoint = "api" [providers] - [providers.marathon] - endpoint = "{{.MarathonURL}}" - watch = true - exposedByDefault = true + [providers.marathon] + endpoint = "{{.MarathonURL}}" + watch = true + exposedByDefault = true diff --git a/integration/fixtures/multiple_provider.toml b/integration/fixtures/multiple_provider.toml index 6e8cc4979..6703950f0 100644 --- a/integration/fixtures/multiple_provider.toml +++ b/integration/fixtures/multiple_provider.toml @@ -1,32 +1,31 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] [providers] - [providers.docker] - endpoint = "unix:///var/run/docker.sock" - watch = true - exposedByDefault = false + [providers.docker] + watch = true + exposedByDefault = false - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router-1] - Service = "service-test" - Rule = "PathPrefix(`/file`)" + service = "service-test" + rule = "PathPrefix(`/file`)" [http.services] - [http.services.service-test] - [http.services.service-test.LoadBalancer] - - [[http.services.service-test.LoadBalancer.Servers]] - URL = "http://{{ .IP }}" + [http.services.service-test.loadBalancer] + [[http.services.service-test.loadBalancer.servers]] + url = "http://{{ .IP }}" diff --git a/integration/fixtures/multiprovider.toml b/integration/fixtures/multiprovider.toml index 3184a5a1f..4a2621455 100644 --- a/integration/fixtures/multiprovider.toml +++ b/integration/fixtures/multiprovider.toml @@ -1,27 +1,28 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [api] [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" -[Providers] - [Providers.Rest] +[providers] + [providers.rest] - [Providers.File] + [providers.file] + +## dynamic configuration ## [http.services] - [http.services.service] - [http.services.service.LoadBalancer] + [http.services.service.loadBalancer] + [[http.services.service.loadBalancer.servers]] + url = "{{.Server}}" - [[http.services.service.LoadBalancer.Servers]] - URL = "{{.Server}}" [http.middlewares] - [http.middlewares.customheader.Headers.CustomRequestHeaders] - X-Custom="CustomValue" + [http.middlewares.customheader.headers.customRequestHeaders] + X-Custom="CustomValue" diff --git a/integration/fixtures/proxy-protocol/with.toml b/integration/fixtures/proxy-protocol/with.toml index 5f853093d..d7a630a1f 100644 --- a/integration/fixtures/proxy-protocol/with.toml +++ b/integration/fixtures/proxy-protocol/with.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -14,16 +14,18 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Path(`/whoami`)" + service = "service1" + rule = "Path(`/whoami`)" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://{{.WhoamiIP}}" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.WhoamiIP}}" diff --git a/integration/fixtures/proxy-protocol/without.toml b/integration/fixtures/proxy-protocol/without.toml index f4c12fcdd..edd4597b2 100644 --- a/integration/fixtures/proxy-protocol/without.toml +++ b/integration/fixtures/proxy-protocol/without.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -14,16 +14,18 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Path(`/whoami`)" + service = "service1" + rule = "Path(`/whoami`)" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://{{.WhoamiIP}}" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.WhoamiIP}}" diff --git a/integration/fixtures/ratelimit/simple.toml b/integration/fixtures/ratelimit/simple.toml index cfd7a888c..ce04a31f1 100644 --- a/integration/fixtures/ratelimit/simple.toml +++ b/integration/fixtures/ratelimit/simple.toml @@ -1,45 +1,46 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [api] -entrypoint="api" + entrypoint="api" [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8081" - + address = ":8081" [entryPoints.api] - address = ":8080" + address = ":8080" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Middlewares = [ "ratelimit" ] - Rule = "Path(`/`)" + service = "service1" + middlewares = [ "ratelimit" ] + rule = "Path(`/`)" [http.middlewares] - [http.middlewares.ratelimit.RateLimit] + [http.middlewares.ratelimit.rateLimit] extractorfunc = "client.ip" - [http.middlewares.ratelimit.RateLimit.rateset.rateset1] - period = "60s" - average = 4 - burst = 5 - [http.middlewares.ratelimit.RateLimit.rateset.rateset2] - period = "3s" - average = 1 - burst = 2 + [http.middlewares.ratelimit.rateLimit.rateSet.rateset1] + period = "60s" + average = 4 + burst = 5 + [http.middlewares.ratelimit.rateLimit.rateSet.rateset2] + period = "3s" + average = 1 + burst = 2 [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] passHostHeader = true - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://{{.Server1}}:80" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.Server1}}:80" diff --git a/integration/fixtures/reqacceptgrace.toml b/integration/fixtures/reqacceptgrace.toml index 61069237d..ab5a9cedd 100644 --- a/integration/fixtures/reqacceptgrace.toml +++ b/integration/fixtures/reqacceptgrace.toml @@ -1,35 +1,36 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] + [entryPoints.web] - address = ":8000" - [entryPoints.web.transport.lifeCycle] - RequestAcceptGraceTimeout = "10s" + address = ":8000" + [entryPoints.web.transport.lifeCycle] + requestAcceptGraceTimeout = "10s" [entryPoints.traefik] - address = ":8001" -[entryPoints.traefik.transport.lifeCycle] - RequestAcceptGraceTimeout = "10s" + address = ":8001" + [entryPoints.traefik.transport.lifeCycle] + requestAcceptGraceTimeout = "10s" [ping] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router] - Service = "service" - Rule = "Path(`/service`)" + service = "service" + rule = "Path(`/service`)" [http.services] - [http.services.service] - [http.services.service.LoadBalancer] - - [[http.services.service.LoadBalancer.Servers]] - URL = "{{.Server}}" + [http.services.service.loadBalancer] + [[http.services.service.loadBalancer.servers]] + url = "{{.Server}}" diff --git a/integration/fixtures/rest/simple.toml b/integration/fixtures/rest/simple.toml index 0d3dbafcd..575c6e2e4 100644 --- a/integration/fixtures/rest/simple.toml +++ b/integration/fixtures/rest/simple.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] @@ -12,4 +12,4 @@ level = "DEBUG" [api] [providers] - [providers.rest] + [providers.rest] diff --git a/integration/fixtures/retry/simple.toml b/integration/fixtures/retry/simple.toml index 44f4a2577..30cb722d0 100644 --- a/integration/fixtures/retry/simple.toml +++ b/integration/fixtures/retry/simple.toml @@ -1,34 +1,36 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Middlewares = [ "retry" ] - Rule = "PathPrefix(`/`)" + service = "service1" + middlewares = [ "retry" ] + rule = "PathPrefix(`/`)" -[http.middlewares.retry.Retry] - Attempts = 3 +[http.middlewares.retry.retry] + attempts = 3 [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://{{.WhoamiEndpoint}}:8080" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.WhoamiEndpoint}}:8080" - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://{{.WhoamiEndpoint}}:80" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.WhoamiEndpoint}}:80" diff --git a/integration/fixtures/simple_auth.toml b/integration/fixtures/simple_auth.toml index 4796ca6b4..f17b5c88e 100644 --- a/integration/fixtures/simple_auth.toml +++ b/integration/fixtures/simple_auth.toml @@ -1,24 +1,24 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [entryPoints.traefik] - address = ":8001" + address = ":8001" [api] - middlewares = ["authentication@file"] + middlewares = ["authentication@file"] [ping] [providers.file] [http.middlewares] - [http.middlewares.authentication.basicauth] - users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] + [http.middlewares.authentication.basicAuth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] diff --git a/integration/fixtures/simple_default.toml b/integration/fixtures/simple_default.toml index a97b07a01..47147bb82 100644 --- a/integration/fixtures/simple_default.toml +++ b/integration/fixtures/simple_default.toml @@ -1,7 +1,7 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" diff --git a/integration/fixtures/simple_hostresolver.toml b/integration/fixtures/simple_hostresolver.toml index 859edf47b..77627f89b 100644 --- a/integration/fixtures/simple_hostresolver.toml +++ b/integration/fixtures/simple_hostresolver.toml @@ -1,21 +1,21 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] [providers] - [providers.docker] - exposedByDefault = false - defaultRule = "Host(`{{ normalize .Name }}.docker.local`)" - watch = true + [providers.docker] + exposedByDefault = false + defaultRule = "Host(`{{ normalize .Name }}.docker.local`)" + watch = true [hostResolver] -cnameFlattening = true + cnameFlattening = true diff --git a/integration/fixtures/simple_stats.toml b/integration/fixtures/simple_stats.toml index f2202d92c..bb9da6f3f 100644 --- a/integration/fixtures/simple_stats.toml +++ b/integration/fixtures/simple_stats.toml @@ -1,37 +1,36 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] -[providers] - [providers.file] +[providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - EntryPoints = ["web"] - Service = "service1" - Rule = "PathPrefix(`/whoami`)" + entryPoints = ["web"] + service = "service1" + rule = "PathPrefix(`/whoami`)" [http.routers.router2] - EntryPoints = ["traefik"] - Service = "service2" - Rule = "PathPrefix(`/whoami`)" + entryPoints = ["traefik"] + service = "service2" + rule = "PathPrefix(`/whoami`)" [http.services] - [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "{{ .Server1 }}" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "{{ .Server1 }}" - [http.services.service2] - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "{{ .Server2 }}" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "{{ .Server2 }}" diff --git a/integration/fixtures/simple_web.toml b/integration/fixtures/simple_web.toml index de39fbbdf..8751d9479 100644 --- a/integration/fixtures/simple_web.toml +++ b/integration/fixtures/simple_web.toml @@ -1,12 +1,12 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] diff --git a/integration/fixtures/simple_whitelist.toml b/integration/fixtures/simple_whitelist.toml index a6a456664..bef0e455d 100644 --- a/integration/fixtures/simple_whitelist.toml +++ b/integration/fixtures/simple_whitelist.toml @@ -1,17 +1,17 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" - [entryPoints.web.ForwardedHeaders] - insecure=true + address = ":8000" + [entryPoints.web.ForwardedHeaders] + insecure=true [api] [providers] - [providers.docker] + [providers.docker] diff --git a/integration/fixtures/tcp/catch-all-no-tls-with-https.toml b/integration/fixtures/tcp/catch-all-no-tls-with-https.toml index da1c0b62e..5f4c79900 100644 --- a/integration/fixtures/tcp/catch-all-no-tls-with-https.toml +++ b/integration/fixtures/tcp/catch-all-no-tls-with-https.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.tcp] @@ -13,28 +13,29 @@ level = "DEBUG" [providers.file] -[tcp] - [tcp.routers] - [tcp.routers.to-whoami-no-tls] - entryPoints = ["tcp"] - rule="HostSNI(`*`)" - service = "whoami-no-tls" +## dynamic configuration ## - [tcp.services] - [tcp.services.whoami-no-tls.loadbalancer] - [[tcp.services.whoami-no-tls.loadbalancer.servers]] - address = "localhost:8086" +[tcp] + [tcp.routers] + [tcp.routers.to-whoami-no-tls] + entryPoints = ["tcp"] + rule = "HostSNI(`*`)" + service = "whoami-no-tls" + + [tcp.services] + [tcp.services.whoami-no-tls.loadBalancer] + [[tcp.services.whoami-no-tls.loadBalancer.servers]] + address = "localhost:8086" [http] - [http.routers] - [http.routers.to-whoami] - entryPoints = ["tcp"] - rule="PathPrefix(`/`)" - service = "whoami" - [http.routers.to-whoami.tls] + [http.routers] + [http.routers.to-whoami] + entryPoints = ["tcp"] + rule="PathPrefix(`/`)" + service = "whoami" + [http.routers.to-whoami.tls] - - [http.services] - [http.services.whoami.loadbalancer] - [[http.services.whoami.loadbalancer.servers]] - url = "http://localhost:8085" + [http.services] + [http.services.whoami.loadBalancer] + [[http.services.whoami.loadBalancer.servers]] + url = "http://localhost:8085" diff --git a/integration/fixtures/tcp/catch-all-no-tls.toml b/integration/fixtures/tcp/catch-all-no-tls.toml index 6bd5fd5d0..efca7631d 100644 --- a/integration/fixtures/tcp/catch-all-no-tls.toml +++ b/integration/fixtures/tcp/catch-all-no-tls.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.tcp] @@ -13,14 +13,16 @@ level = "DEBUG" [providers.file] -[tcp] - [tcp.routers] - [tcp.routers.to-whoami-no-tls] - entryPoints = ["tcp"] - rule="HostSNI(`*`)" - service = "whoami-no-tls" +## dynamic configuration ## - [tcp.services] - [tcp.services.whoami-no-tls.loadbalancer] - [[tcp.services.whoami-no-tls.loadbalancer.servers]] - address = "localhost:8086" +[tcp] + [tcp.routers] + [tcp.routers.to-whoami-no-tls] + entryPoints = ["tcp"] + rule = "HostSNI(`*`)" + service = "whoami-no-tls" + + [tcp.services] + [tcp.services.whoami-no-tls.loadBalancer] + [[tcp.services.whoami-no-tls.loadBalancer.servers]] + address = "localhost:8086" diff --git a/integration/fixtures/tcp/mixed.toml b/integration/fixtures/tcp/mixed.toml index a94b7c640..9bca88eaf 100644 --- a/integration/fixtures/tcp/mixed.toml +++ b/integration/fixtures/tcp/mixed.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.tcp] @@ -13,56 +13,58 @@ level = "DEBUG" [providers.file] +## dynamic configuration ## + [http] - [http.routers] - [http.routers.my-router] - rule = "Path(`/test`)" - service = "whoami" - entrypoint=["tcp"] - + [http.routers] + [http.routers.my-router] + rule = "Path(`/test`)" + service = "whoami" + entrypoint=["tcp"] + [http.routers.my-https-router] - entryPoints=["tcp"] - rule = "Path(`/whoami/`)" - service = "whoami" - [http.routers.my-https-router.tls] + entryPoints=["tcp"] + rule = "Path(`/whoami/`)" + service = "whoami" + [http.routers.my-https-router.tls] - [http.services] - [http.services.whoami.loadbalancer] - [[http.services.whoami.loadbalancer.servers]] - url = "http://localhost:8085" + [http.services] + [http.services.whoami.loadBalancer] + [[http.services.whoami.loadBalancer.servers]] + url = "http://localhost:8085" [tcp] - [tcp.routers] - [tcp.routers.to-whoami-a] - rule = "HostSNI(`whoami-a.test`)" - service = "whoami-a" - entryPoints = [ "tcp" ] - [tcp.routers.to-whoami-a.tls] - passthrough=true + [tcp.routers] + [tcp.routers.to-whoami-a] + rule = "HostSNI(`whoami-a.test`)" + service = "whoami-a" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-a.tls] + passthrough=true - [tcp.routers.to-whoami-b] - rule = "HostSNI(`whoami-b.test`)" - service = "whoami-b" - entryPoints = [ "tcp" ] - [tcp.routers.to-whoami-b.tls] - passthrough=true + [tcp.routers.to-whoami-b] + rule = "HostSNI(`whoami-b.test`)" + service = "whoami-b" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-b.tls] + passthrough=true - [tcp.routers.to-whoami-no-cert] - rule = "HostSNI(`whoami-c.test`)" - service = "whoami-no-cert" - entryPoints = [ "tcp" ] - [tcp.routers.to-whoami-no-cert.tls] + [tcp.routers.to-whoami-no-cert] + rule = "HostSNI(`whoami-c.test`)" + service = "whoami-no-cert" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-no-cert.tls] - [tcp.services.whoami-a.loadbalancer] - [[tcp.services.whoami-a.loadbalancer.servers]] - address = "localhost:8081" + [tcp.services.whoami-a.loadBalancer] + [[tcp.services.whoami-a.loadBalancer.servers]] + address = "localhost:8081" - [tcp.services.whoami-b.loadbalancer] - [[tcp.services.whoami-b.loadbalancer.servers]] - address = "localhost:8082" + [tcp.services.whoami-b.loadBalancer] + [[tcp.services.whoami-b.loadBalancer.servers]] + address = "localhost:8082" - [tcp.services.whoami-no-cert.loadbalancer] - [[tcp.services.whoami-no-cert.loadbalancer.servers]] - address = "localhost:8083" + [tcp.services.whoami-no-cert.loadBalancer] + [[tcp.services.whoami-no-cert.loadBalancer.servers]] + address = "localhost:8083" [[tls.certificates]] certFile = "fixtures/tcp/whoami-c.crt" diff --git a/integration/fixtures/tcp/multi-tls-options.toml b/integration/fixtures/tcp/multi-tls-options.toml index 5551a4088..517fdeddc 100644 --- a/integration/fixtures/tcp/multi-tls-options.toml +++ b/integration/fixtures/tcp/multi-tls-options.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.tcp] @@ -13,27 +13,29 @@ level = "DEBUG" [providers.file] +## dynamic configuration ## + [tcp] - [tcp.routers] - [tcp.routers.to-whoami-no-cert] - rule = "HostSNI(`whoami-c.test`)" - service = "whoami-no-cert" - entryPoints = [ "tcp" ] - [tcp.routers.to-whoami-no-cert.tls] - options = "foo" + [tcp.routers] + [tcp.routers.to-whoami-no-cert] + rule = "HostSNI(`whoami-c.test`)" + service = "whoami-no-cert" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-no-cert.tls] + options = "foo" - [tcp.routers.to-whoami-sni-strict] - rule = "HostSNI(`whoami-d.test`)" - service = "whoami-no-cert" - entryPoints = [ "tcp" ] - [tcp.routers.to-whoami-sni-strict.tls] - options = "bar" + [tcp.routers.to-whoami-sni-strict] + rule = "HostSNI(`whoami-d.test`)" + service = "whoami-no-cert" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-sni-strict.tls] + options = "bar" - [tcp.services.whoami-no-cert] - [tcp.services.whoami-no-cert.loadbalancer] - method = "wrr" - [[tcp.services.whoami-no-cert.loadbalancer.servers]] - address = "localhost:8083" + [tcp.services.whoami-no-cert] + [tcp.services.whoami-no-cert.loadBalancer] + method = "wrr" + [[tcp.services.whoami-no-cert.loadBalancer.servers]] + address = "localhost:8083" [tls.options] diff --git a/integration/fixtures/tcp/non-tls-fallback.toml b/integration/fixtures/tcp/non-tls-fallback.toml index 37ff13045..173086e1b 100644 --- a/integration/fixtures/tcp/non-tls-fallback.toml +++ b/integration/fixtures/tcp/non-tls-fallback.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.tcp] @@ -14,45 +14,45 @@ level = "DEBUG" [providers.file] [tcp] - [tcp.routers] - [tcp.routers.to-whoami-a] - rule = "HostSNI(`whoami-a.test`)" - service = "whoami-a" - entryPoints = [ "tcp" ] - [tcp.routers.to-whoami-a.tls] - passthrough=true + [tcp.routers] + [tcp.routers.to-whoami-a] + rule = "HostSNI(`whoami-a.test`)" + service = "whoami-a" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-a.tls] + passthrough=true - [tcp.routers.to-whoami-b] - rule = "HostSNI(`whoami-b.test`)" - service = "whoami-b" - entryPoints = [ "tcp" ] - [tcp.routers.to-whoami-b.tls] - passthrough=true + [tcp.routers.to-whoami-b] + rule = "HostSNI(`whoami-b.test`)" + service = "whoami-b" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-b.tls] + passthrough=true - [tcp.routers.to-whoami-no-cert] - rule = "HostSNI(`whoami-c.test`)" - service = "whoami-no-cert" - entryPoints = [ "tcp" ] - [tcp.routers.to-whoami-no-cert.tls] + [tcp.routers.to-whoami-no-cert] + rule = "HostSNI(`whoami-c.test`)" + service = "whoami-no-cert" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-no-cert.tls] - [tcp.routers.to-whoami-no-tls] - entryPoints = ["tcp"] - rule="HostSNI(`*`)" - service = "whoami-no-tls" + [tcp.routers.to-whoami-no-tls] + entryPoints = ["tcp"] + rule="HostSNI(`*`)" + service = "whoami-no-tls" - [tcp.services] - [tcp.services.whoami-no-tls.loadbalancer] - [[tcp.services.whoami-no-tls.loadbalancer.servers]] - address = "localhost:8084" + [tcp.services] + [tcp.services.whoami-no-tls.loadBalancer] + [[tcp.services.whoami-no-tls.loadBalancer.servers]] + address = "localhost:8084" - [tcp.services.whoami-a.loadbalancer] - [[tcp.services.whoami-a.loadbalancer.servers]] - address = "localhost:8081" + [tcp.services.whoami-a.loadBalancer] + [[tcp.services.whoami-a.loadBalancer.servers]] + address = "localhost:8081" - [tcp.services.whoami-b.loadbalancer] - [[tcp.services.whoami-b.loadbalancer.servers]] - address = "localhost:8082" + [tcp.services.whoami-b.loadBalancer] + [[tcp.services.whoami-b.loadBalancer.servers]] + address = "localhost:8082" - [tcp.services.whoami-no-cert.loadbalancer] - [[tcp.services.whoami-no-cert.loadbalancer.servers]] - address = "localhost:8083" + [tcp.services.whoami-no-cert.loadBalancer] + [[tcp.services.whoami-no-cert.loadBalancer.servers]] + address = "localhost:8083" diff --git a/integration/fixtures/tcp/non-tls.toml b/integration/fixtures/tcp/non-tls.toml index 4cf36eade..c7ba8297f 100644 --- a/integration/fixtures/tcp/non-tls.toml +++ b/integration/fixtures/tcp/non-tls.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.tcp] @@ -13,14 +13,16 @@ level = "DEBUG" [providers.file] -[tcp] - [tcp.routers] - [tcp.routers.to-whoami-no-tls] - entryPoints = ["tcp"] - rule="HostSNI(`*`)" - service = "whoami-no-tls" +## dynamic configuration ## - [tcp.services] - [tcp.services.whoami-no-tls.loadbalancer] - [[tcp.services.whoami-no-tls.loadbalancer.servers]] - address = "localhost:8084" +[tcp] + [tcp.routers] + [tcp.routers.to-whoami-no-tls] + entryPoints = ["tcp"] + rule="HostSNI(`*`)" + service = "whoami-no-tls" + + [tcp.services] + [tcp.services.whoami-no-tls.loadBalancer] + [[tcp.services.whoami-no-tls.loadBalancer.servers]] + address = "localhost:8084" diff --git a/integration/fixtures/timeout/forwarding_timeouts.toml b/integration/fixtures/timeout/forwarding_timeouts.toml index 04d80e14f..5d123d18d 100644 --- a/integration/fixtures/timeout/forwarding_timeouts.toml +++ b/integration/fixtures/timeout/forwarding_timeouts.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport.forwardingTimeouts] dialTimeout = "300ms" @@ -19,24 +19,26 @@ level = "DEBUG" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Path(`/dialTimeout`)" + service = "service1" + rule = "Path(`/dialTimeout`)" [http.routers.router2] - Service = "service2" - Rule = "Path(`/responseHeaderTimeout`)" + service = "service2" + rule = "Path(`/responseHeaderTimeout`)" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://50.255.255.1" + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "http://50.255.255.1" [http.services.service2] - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "http://{{.TimeoutEndpoint}}:9000" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "http://{{.TimeoutEndpoint}}:9000" diff --git a/integration/fixtures/timeout/keepalive.toml b/integration/fixtures/timeout/keepalive.toml index c01dce754..d79e04786 100644 --- a/integration/fixtures/timeout/keepalive.toml +++ b/integration/fixtures/timeout/keepalive.toml @@ -1,31 +1,33 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport.forwardingTimeouts] idleConnTimeout = "{{ .IdleConnTimeout }}" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "keepalive" - Rule = "PathPrefix(`/keepalive`)" + service = "keepalive" + rule = "PathPrefix(`/keepalive`)" [http.services] [http.services.keepalive] - [http.services.keepalive.LoadBalancer] + [http.services.keepalive.loadBalancer] passHostHeader = true - [[http.services.keepalive.LoadBalancer.Servers]] - URL = "{{ .KeepAliveServer }}" - Weight = 1 + [[http.services.keepalive.loadBalancer.servers]] + url = "{{ .KeepAliveServer }}" + weight = 1 diff --git a/integration/fixtures/tlsclientheaders/simple.toml b/integration/fixtures/tlsclientheaders/simple.toml index 26c2cbe7b..90fed2166 100644 --- a/integration/fixtures/tlsclientheaders/simple.toml +++ b/integration/fixtures/tlsclientheaders/simple.toml @@ -16,17 +16,18 @@ [providers] [providers.docker] - endpoint = "unix:///var/run/docker.sock" watch = true [providers.file] +## dynamic configuration ## + [tls.options] - [tls.options.default.ClientCA] + [tls.options.default.clientCA] files = [ """{{ .RootCertContent }}""" ] optional = false [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = """{{ .ServerCertContent }}""" keyFile = """{{ .ServerKeyContent }}""" diff --git a/integration/fixtures/tracing/simple-jaeger.toml b/integration/fixtures/tracing/simple-jaeger.toml index 1a830f661..53435ad88 100644 --- a/integration/fixtures/tracing/simple-jaeger.toml +++ b/integration/fixtures/tracing/simple-jaeger.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [api] @@ -20,7 +20,9 @@ level = "DEBUG" localAgentHostPort = "{{.IP}}:6831" [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] @@ -38,36 +40,36 @@ level = "DEBUG" [http.middlewares] [http.middlewares.retry.retry] - attempts = 3 - [http.middlewares.basic-auth.BasicAuth] - users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] - [http.middlewares.ratelimit.RateLimit] - extractorfunc = "client.ip" - [http.middlewares.ratelimit.RateLimit.rateset.rateset1] - period = "60s" - average = 4 - burst = 5 - [http.middlewares.ratelimit.RateLimit.rateset.rateset2] - period = "3s" - average = 1 - burst = 2 + attempts = 3 + [http.middlewares.basic-auth.basicAuth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] + [http.middlewares.ratelimit.rateLimit] + extractorfunc = "client.ip" + [http.middlewares.ratelimit.rateLimit.rateSet.rateset1] + period = "60s" + average = 4 + burst = 5 + [http.middlewares.ratelimit.rateLimit.rateSet.rateset2] + period = "3s" + average = 1 + burst = 2 [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] passHostHeader = true - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" [http.services.service2] passHostHeader = true - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" [http.services.service3] passHostHeader = true - [http.services.service3.LoadBalancer] - [[http.services.service3.LoadBalancer.Servers]] - URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" + [http.services.service3.loadBalancer] + [[http.services.service3.loadBalancer.servers]] + url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" diff --git a/integration/fixtures/tracing/simple-zipkin.toml b/integration/fixtures/tracing/simple-zipkin.toml index e557fc122..b1f14bf37 100644 --- a/integration/fixtures/tracing/simple-zipkin.toml +++ b/integration/fixtures/tracing/simple-zipkin.toml @@ -1,9 +1,9 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [api] @@ -18,54 +18,55 @@ level = "DEBUG" debug = true [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Middlewares = ["retry", "ratelimit"] - Rule = "Path(`/ratelimit`)" + service = "service1" + middlewares = ["retry", "ratelimit"] + rule = "Path(`/ratelimit`)" [http.routers.router2] - Service = "service2" - Middlewares = ["retry"] - Rule = "Path(`/retry`)" + service = "service2" + middlewares = ["retry"] + rule = "Path(`/retry`)" [http.routers.router3] - Service = "service3" - Middlewares = ["retry", "basic-auth"] - Rule = "Path(`/auth`)" + service = "service3" + middlewares = ["retry", "basic-auth"] + rule = "Path(`/auth`)" [http.middlewares] [http.middlewares.retry.retry] - attempts = 3 - [http.middlewares.basic-auth.BasicAuth] - users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] - [http.middlewares.ratelimit.RateLimit] - extractorfunc = "client.ip" - [http.middlewares.ratelimit.RateLimit.rateset.rateset1] - period = "60s" - average = 4 - burst = 5 - [http.middlewares.ratelimit.RateLimit.rateset.rateset2] - period = "3s" - average = 1 - burst = 2 - + attempts = 3 + [http.middlewares.basic-auth.basicAuth] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] + [http.middlewares.ratelimit.rateLimit] + extractorfunc = "client.ip" + [http.middlewares.ratelimit.rateLimit.rateSet.rateset1] + period = "60s" + average = 4 + burst = 5 + [http.middlewares.ratelimit.rateLimit.rateSet.rateset2] + period = "3s" + average = 1 + burst = 2 [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] passHostHeader = true - [[http.services.service1.LoadBalancer.Servers]] - URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" + [[http.services.service1.loadBalancer.servers]] + url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" [http.services.service2] passHostHeader = true - [http.services.service2.LoadBalancer] - [[http.services.service2.LoadBalancer.Servers]] - URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" + [http.services.service2.loadBalancer] + [[http.services.service2.loadBalancer.servers]] + url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" [http.services.service3] passHostHeader = true - [http.services.service3.LoadBalancer] - [[http.services.service3.LoadBalancer.Servers]] - URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" + [http.services.service3.loadBalancer] + [[http.services.service3.loadBalancer.servers]] + url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" diff --git a/integration/fixtures/traefik_log_config.toml b/integration/fixtures/traefik_log_config.toml index d5bcf259b..e7b077c61 100644 --- a/integration/fixtures/traefik_log_config.toml +++ b/integration/fixtures/traefik_log_config.toml @@ -1,23 +1,23 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" -filePath = "traefik.log" + level = "DEBUG" + filePath = "traefik.log" [accessLog] filePath = "access.log" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] dashboard = false [providers] - [providers.docker] - exposedByDefault = false - defaultRule = "Host(`{{ normalize .Name }}.docker.local`)" - watch = true + [providers.docker] + exposedByDefault = false + defaultRule = "Host(`{{ normalize .Name }}.docker.local`)" + watch = true diff --git a/integration/fixtures/websocket/config.toml b/integration/fixtures/websocket/config.toml index 5bd199180..066155d9b 100644 --- a/integration/fixtures/websocket/config.toml +++ b/integration/fixtures/websocket/config.toml @@ -1,27 +1,29 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":8000" + address = ":8000" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "PathPrefix(`/ws`)" + service = "service1" + rule = "PathPrefix(`/ws`)" [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] + [http.services.service1.loadBalancer] passHostHeader = true - [[http.services.service1.LoadBalancer.Servers]] - URL = "{{ .WebsocketServer }}" + [[http.services.service1.loadBalancer.servers]] + url = "{{ .WebsocketServer }}" diff --git a/integration/fixtures/websocket/config_https.toml b/integration/fixtures/websocket/config_https.toml index a1fa2f43a..f020fa71d 100644 --- a/integration/fixtures/websocket/config_https.toml +++ b/integration/fixtures/websocket/config_https.toml @@ -1,36 +1,38 @@ [global] -checkNewVersion = false -sendAnonymousUsage = false + checkNewVersion = false + sendAnonymousUsage = false [log] -level = "DEBUG" + level = "DEBUG" [serversTransport] -insecureSkipVerify=true + insecureSkipVerify=true [entryPoints] [entryPoints.wss] - address = ":8000" + address = ":8000" [api] [providers] - [providers.file] + [providers.file] + +## dynamic configuration ## [http.routers] [http.routers.router1] - Service = "service1" - Rule = "Path(`/echo`,`/ws`)" + service = "service1" + rule = "Path(`/echo`,`/ws`)" [http.routers.router1.tls] [http.services] [http.services.service1] - [http.services.service1.LoadBalancer] - PassHostHeader = true - [[http.services.service1.LoadBalancer.Servers]] - URL = "{{ .WebsocketServer }}" + [http.services.service1.loadBalancer] + passHostHeader = true + [[http.services.service1.loadBalancer.servers]] + url = "{{ .WebsocketServer }}" [tls.stores] - [tls.stores.default.DefaultCertificate] + [tls.stores.default.defaultCertificate] certFile = "resources/tls/local.cert" keyFile = "resources/tls/local.key" diff --git a/integration/testdata/rawdata-crd.json b/integration/testdata/rawdata-crd.json index 3e09587f5..c6c9e1b25 100644 --- a/integration/testdata/rawdata-crd.json +++ b/integration/testdata/rawdata-crd.json @@ -36,7 +36,7 @@ }, "services": { "default/test.crd-6b204d94623b3df4370c@kubernetescrd": { - "loadbalancer": { + "loadBalancer": { "servers": [ { "url": "http://10.42.0.3:80" @@ -56,7 +56,7 @@ } }, "default/test2.crd-23c7f4c450289ee29016@kubernetescrd": { - "loadbalancer": { + "loadBalancer": { "servers": [ { "url": "http://10.42.0.3:80" @@ -91,7 +91,7 @@ }, "tcpServices": { "default/test3.crd-673acf455cb2dab0b43a@kubernetescrd": { - "loadbalancer": { + "loadBalancer": { "servers": [ { "address": "10.42.0.4:8080" diff --git a/integration/testdata/rawdata-ingress.json b/integration/testdata/rawdata-ingress.json index de6c54952..c22fdf46e 100644 --- a/integration/testdata/rawdata-ingress.json +++ b/integration/testdata/rawdata-ingress.json @@ -1,14 +1,13 @@ { "routers": { "whoami-test/whoami@kubernetes": { - "entryPoints": null, "service": "default/whoami/http", "rule": "Host(`whoami.test`) \u0026\u0026 PathPrefix(`/whoami`)" } }, "services": { "default/whoami/http@kubernetes": { - "loadbalancer": { + "loadBalancer": { "servers": [ { "url": "http://10.42.0.2:80" diff --git a/pkg/anonymize/anonymize_config_test.go b/pkg/anonymize/anonymize_config_test.go index 928d4254a..2f15468ad 100644 --- a/pkg/anonymize/anonymize_config_test.go +++ b/pkg/anonymize/anonymize_config_test.go @@ -199,7 +199,7 @@ func TestDo_globalConfiguration(t *testing.T) { EntryPoint: "MyEntryPoint", Middlewares: []string{"m1", "m2"}, }, - Datadog: &types.Datadog{ + DataDog: &types.DataDog{ Address: "localhost:8181", PushInterval: 12, }, diff --git a/pkg/api/handler_test.go b/pkg/api/handler_test.go index 6794b977c..ce10158a2 100644 --- a/pkg/api/handler_test.go +++ b/pkg/api/handler_test.go @@ -895,7 +895,6 @@ func TestHandlerHTTP_API(t *testing.T) { assert.JSONEq(t, string(data), string(contents)) }) } - } func TestHandler_Configuration(t *testing.T) { diff --git a/pkg/api/testdata/getrawdata.json b/pkg/api/testdata/getrawdata.json index 736104e97..7e238245b 100644 --- a/pkg/api/testdata/getrawdata.json +++ b/pkg/api/testdata/getrawdata.json @@ -54,7 +54,7 @@ }, "services": { "foo-service@myprovider": { - "loadbalancer": { + "loadBalancer": { "servers": [ { "url": "http://127.0.0.1" @@ -86,7 +86,7 @@ }, "tcpServices": { "tcpfoo-service@myprovider": { - "loadbalancer": { + "loadBalancer": { "servers": [ { "address": "127.0.0.1" diff --git a/pkg/api/testdata/service-bar.json b/pkg/api/testdata/service-bar.json index a67023582..529e3382a 100644 --- a/pkg/api/testdata/service-bar.json +++ b/pkg/api/testdata/service-bar.json @@ -1,5 +1,5 @@ { - "loadbalancer": { + "loadBalancer": { "passHostHeader": false, "servers": [ { diff --git a/pkg/api/testdata/services-page2.json b/pkg/api/testdata/services-page2.json index 13e676ea9..2f5dce034 100644 --- a/pkg/api/testdata/services-page2.json +++ b/pkg/api/testdata/services-page2.json @@ -1,6 +1,6 @@ [ { - "loadbalancer": { + "loadBalancer": { "passHostHeader": false, "servers": [ { diff --git a/pkg/api/testdata/services.json b/pkg/api/testdata/services.json index ceb1fc381..9abd426f8 100644 --- a/pkg/api/testdata/services.json +++ b/pkg/api/testdata/services.json @@ -1,6 +1,6 @@ [ { - "loadbalancer": { + "loadBalancer": { "passHostHeader": false, "servers": [ { @@ -19,7 +19,7 @@ ] }, { - "loadbalancer": { + "loadBalancer": { "passHostHeader": false, "servers": [ { diff --git a/pkg/api/testdata/tcpservice-bar.json b/pkg/api/testdata/tcpservice-bar.json index 31f3f9405..114f0b74b 100644 --- a/pkg/api/testdata/tcpservice-bar.json +++ b/pkg/api/testdata/tcpservice-bar.json @@ -1,5 +1,5 @@ { - "loadbalancer": { + "loadBalancer": { "servers": [ { "address": "127.0.0.1:2345" diff --git a/pkg/api/testdata/tcpservices-page2.json b/pkg/api/testdata/tcpservices-page2.json index 0a5bf6940..345151040 100644 --- a/pkg/api/testdata/tcpservices-page2.json +++ b/pkg/api/testdata/tcpservices-page2.json @@ -1,6 +1,6 @@ [ { - "loadbalancer": { + "loadBalancer": { "servers": [ { "address": "127.0.0.2:2345" diff --git a/pkg/api/testdata/tcpservices.json b/pkg/api/testdata/tcpservices.json index e9820643c..4df6dc8b7 100644 --- a/pkg/api/testdata/tcpservices.json +++ b/pkg/api/testdata/tcpservices.json @@ -1,6 +1,6 @@ [ { - "loadbalancer": { + "loadBalancer": { "servers": [ { "address": "127.0.0.1:2345" @@ -15,7 +15,7 @@ ] }, { - "loadbalancer": { + "loadBalancer": { "servers": [ { "address": "127.0.0.2:2345" diff --git a/pkg/config/dyn_config.go b/pkg/config/dyn_config.go index 032cff288..634fad4de 100644 --- a/pkg/config/dyn_config.go +++ b/pkg/config/dyn_config.go @@ -1,57 +1,98 @@ package config import ( - "crypto/tls" - "crypto/x509" - "fmt" - "io/ioutil" - "os" "reflect" traefiktls "github.com/containous/traefik/pkg/tls" ) +// Message holds configuration information exchanged between parts of traefik. +type Message struct { + ProviderName string + Configuration *Configuration +} + +// Configurations is for currentConfigurations Map. +type Configurations map[string]*Configuration + +// Configuration is the root of the dynamic configuration +type Configuration struct { + HTTP *HTTPConfiguration `json:"http,omitempty" toml:"http,omitempty" yaml:"http,omitempty"` + TCP *TCPConfiguration `json:"tcp,omitempty" toml:"tcp,omitempty" yaml:"tcp,omitempty"` + TLS *TLSConfiguration `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty"` +} + +// TLSConfiguration contains all the configuration parameters of a TLS connection. +type TLSConfiguration struct { + Certificates []*traefiktls.CertAndStores `json:"-" toml:"certificates,omitempty" yaml:"certificates,omitempty" label:"-"` + Options map[string]traefiktls.Options `json:"options,omitempty" toml:"options,omitempty" yaml:"options,omitempty"` + Stores map[string]traefiktls.Store `json:"stores,omitempty" toml:"stores,omitempty" yaml:"stores,omitempty"` +} + +// HTTPConfiguration contains all the HTTP configuration parameters. +type HTTPConfiguration struct { + Routers map[string]*Router `json:"routers,omitempty" toml:"routers,omitempty" yaml:"routers,omitempty"` + Middlewares map[string]*Middleware `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty"` + Services map[string]*Service `json:"services,omitempty" toml:"services,omitempty" yaml:"services,omitempty"` +} + +// TCPConfiguration contains all the TCP configuration parameters. +type TCPConfiguration struct { + Routers map[string]*TCPRouter `json:"routers,omitempty" toml:"routers,omitempty" yaml:"routers,omitempty"` + Services map[string]*TCPService `json:"services,omitempty" toml:"services,omitempty" yaml:"services,omitempty"` +} + +// Service holds a service configuration (can only be of one type at the same time). +type Service struct { + LoadBalancer *LoadBalancerService `json:"loadBalancer,omitempty" toml:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"` +} + +// TCPService holds a tcp service configuration (can only be of one type at the same time). +type TCPService struct { + LoadBalancer *TCPLoadBalancerService `json:"loadBalancer,omitempty" toml:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"` +} + // Router holds the router configuration. type Router struct { - EntryPoints []string `json:"entryPoints"` - Middlewares []string `json:"middlewares,omitempty" toml:",omitempty"` - Service string `json:"service,omitempty" toml:",omitempty"` - Rule string `json:"rule,omitempty" toml:",omitempty"` - Priority int `json:"priority,omitempty" toml:"priority,omitzero"` - TLS *RouterTLSConfig `json:"tls,omitempty" toml:"tls,omitzero" label:"allowEmpty"` + EntryPoints []string `json:"entryPoints,omitempty" toml:"entryPoints,omitempty" yaml:"entryPoints,omitempty"` + Middlewares []string `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty"` + Service string `json:"service,omitempty" toml:"service,omitempty" yaml:"service,omitempty"` + Rule string `json:"rule,omitempty" toml:"rule,omitempty" yaml:"rule,omitempty"` + Priority int `json:"priority,omitempty" toml:"priority,omitempty,omitzero" yaml:"priority,omitempty"` + TLS *RouterTLSConfig `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty"` } // RouterTLSConfig holds the TLS configuration for a router type RouterTLSConfig struct { - Options string `json:"options,omitempty" toml:"options,omitzero"` + Options string `json:"options,omitempty" toml:"options,omitempty" yaml:"options,omitempty"` } // TCPRouter holds the router configuration. type TCPRouter struct { - EntryPoints []string `json:"entryPoints"` - Service string `json:"service,omitempty" toml:",omitempty"` - Rule string `json:"rule,omitempty" toml:",omitempty"` - TLS *RouterTCPTLSConfig `json:"tls,omitempty" toml:"tls,omitzero" label:"allowEmpty"` + EntryPoints []string `json:"entryPoints,omitempty" toml:"entryPoints,omitempty" yaml:"entryPoints,omitempty"` + Service string `json:"service,omitempty" toml:"service,omitempty" yaml:"service,omitempty"` + Rule string `json:"rule,omitempty" toml:"rule,omitempty" yaml:"rule,omitempty"` + TLS *RouterTCPTLSConfig `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty"` } // RouterTCPTLSConfig holds the TLS configuration for a router type RouterTCPTLSConfig struct { - Passthrough bool `json:"passthrough" toml:"passthrough,omitzero"` - Options string `json:"options,omitempty" toml:"options,omitzero"` + Passthrough bool `json:"passthrough" toml:"passthrough" yaml:"passthrough"` + Options string `json:"options,omitempty" toml:"options,omitempty" yaml:"options,omitempty"` } // LoadBalancerService holds the LoadBalancerService configuration. type LoadBalancerService struct { - Stickiness *Stickiness `json:"stickiness,omitempty" toml:",omitempty" label:"allowEmpty"` - Servers []Server `json:"servers,omitempty" toml:",omitempty" label-slice-as-struct:"server"` - HealthCheck *HealthCheck `json:"healthCheck,omitempty" toml:",omitempty"` - PassHostHeader bool `json:"passHostHeader" toml:",omitempty"` - ResponseForwarding *ResponseForwarding `json:"forwardingResponse,omitempty" toml:",omitempty"` + Stickiness *Stickiness `json:"stickiness,omitempty" toml:"stickiness,omitempty" yaml:"stickiness,omitempty" label:"allowEmpty"` + Servers []Server `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server"` + HealthCheck *HealthCheck `json:"healthCheck,omitempty" toml:"healthCheck,omitempty" yaml:"healthCheck,omitempty"` + PassHostHeader bool `json:"passHostHeader" toml:"passHostHeader" yaml:"passHostHeader"` + ResponseForwarding *ResponseForwarding `json:"responseForwarding,omitempty" toml:"responseForwarding,omitempty" yaml:"responseForwarding,omitempty"` } // TCPLoadBalancerService holds the LoadBalancerService configuration. type TCPLoadBalancerService struct { - Servers []TCPServer `json:"servers,omitempty" toml:",omitempty" label-slice-as-struct:"server"` + Servers []TCPServer `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server" label-slice-as-struct:"server"` } // Mergeable tells if the given service is mergeable. @@ -95,27 +136,27 @@ func (l *LoadBalancerService) SetDefaults() { // ResponseForwarding holds configuration for the forward of the response. type ResponseForwarding struct { - FlushInterval string `json:"flushInterval,omitempty" toml:",omitempty"` + FlushInterval string `json:"flushInterval,omitempty" toml:"flushInterval,omitempty" yaml:"flushInterval,omitempty"` } // Stickiness holds the stickiness configuration. type Stickiness struct { - CookieName string `json:"cookieName,omitempty" toml:",omitempty"` - SecureCookie bool `json:"secureCookie,omitempty" toml:",omitempty"` - HTTPOnlyCookie bool `json:"httpOnlyCookie,omitempty" toml:",omitempty"` + CookieName string `json:"cookieName,omitempty" toml:"cookieName,omitempty" yaml:"cookieName,omitempty"` + SecureCookie bool `json:"secureCookie,omitempty" toml:"secureCookie,omitempty" yaml:"secureCookie,omitempty"` + HTTPOnlyCookie bool `json:"httpOnlyCookie,omitempty" toml:"httpOnlyCookie,omitempty" yaml:"httpOnlyCookie,omitempty"` } // Server holds the server configuration. type Server struct { - URL string `json:"url" label:"-"` - Scheme string `toml:"-" json:"-"` - Port string `toml:"-" json:"-"` + URL string `json:"url,omitempty" toml:"url,omitempty" yaml:"url,omitempty" label:"-"` + Scheme string `toml:"-" json:"-" yaml:"-"` + Port string `toml:"-" json:"-" yaml:"-"` } // TCPServer holds a TCP Server configuration type TCPServer struct { - Address string `json:"address" label:"-"` - Port string `toml:"-" json:"-"` + Address string `json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty" label:"-"` + Port string `toml:"-" json:"-" yaml:"-"` } // SetDefaults Default values for a Server. @@ -125,128 +166,13 @@ func (s *Server) SetDefaults() { // HealthCheck holds the HealthCheck configuration. type HealthCheck struct { - Scheme string `json:"scheme,omitempty" toml:",omitempty"` - Path string `json:"path,omitempty" toml:",omitempty"` - Port int `json:"port,omitempty" toml:",omitempty,omitzero"` + Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty"` + Path string `json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty"` + Port int `json:"port,omitempty" toml:"port,omitempty,omitzero" yaml:"port,omitempty"` // FIXME change string to types.Duration - Interval string `json:"interval,omitempty" toml:",omitempty"` + Interval string `json:"interval,omitempty" toml:"interval,omitempty" yaml:"interval,omitempty"` // FIXME change string to types.Duration - Timeout string `json:"timeout,omitempty" toml:",omitempty"` - Hostname string `json:"hostname,omitempty" toml:",omitempty"` - Headers map[string]string `json:"headers,omitempty" toml:",omitempty"` -} - -// CreateTLSConfig creates a TLS config from ClientTLS structures. -func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) { - if clientTLS == nil { - return nil, nil - } - - var err error - caPool := x509.NewCertPool() - clientAuth := tls.NoClientCert - if clientTLS.CA != "" { - var ca []byte - if _, errCA := os.Stat(clientTLS.CA); errCA == nil { - ca, err = ioutil.ReadFile(clientTLS.CA) - if err != nil { - return nil, fmt.Errorf("failed to read CA. %s", err) - } - } else { - ca = []byte(clientTLS.CA) - } - - if !caPool.AppendCertsFromPEM(ca) { - return nil, fmt.Errorf("failed to parse CA") - } - - if clientTLS.CAOptional { - clientAuth = tls.VerifyClientCertIfGiven - } else { - clientAuth = tls.RequireAndVerifyClientCert - } - } - - cert := tls.Certificate{} - _, errKeyIsFile := os.Stat(clientTLS.Key) - - if !clientTLS.InsecureSkipVerify && (len(clientTLS.Cert) == 0 || len(clientTLS.Key) == 0) { - return nil, fmt.Errorf("TLS Certificate or Key file must be set when TLS configuration is created") - } - - if len(clientTLS.Cert) > 0 && len(clientTLS.Key) > 0 { - if _, errCertIsFile := os.Stat(clientTLS.Cert); errCertIsFile == nil { - if errKeyIsFile == nil { - cert, err = tls.LoadX509KeyPair(clientTLS.Cert, clientTLS.Key) - if err != nil { - return nil, fmt.Errorf("failed to load TLS keypair: %v", err) - } - } else { - return nil, fmt.Errorf("tls cert is a file, but tls key is not") - } - } else { - if errKeyIsFile != nil { - cert, err = tls.X509KeyPair([]byte(clientTLS.Cert), []byte(clientTLS.Key)) - if err != nil { - return nil, fmt.Errorf("failed to load TLS keypair: %v", err) - - } - } else { - return nil, fmt.Errorf("TLS key is a file, but tls cert is not") - } - } - } - - return &tls.Config{ - Certificates: []tls.Certificate{cert}, - RootCAs: caPool, - InsecureSkipVerify: clientTLS.InsecureSkipVerify, - ClientAuth: clientAuth, - }, nil -} - -// Message holds configuration information exchanged between parts of traefik. -type Message struct { - ProviderName string - Configuration *Configuration -} - -// Configuration is the root of the dynamic configuration -type Configuration struct { - HTTP *HTTPConfiguration - TCP *TCPConfiguration - TLS *TLSConfiguration -} - -// TLSConfiguration contains all the configuration parameters of a TLS connection. -type TLSConfiguration struct { - Certificates []*traefiktls.CertAndStores `json:"-" label:"-" yaml:"certificates"` - Options map[string]traefiktls.Options - Stores map[string]traefiktls.Store -} - -// Configurations is for currentConfigurations Map. -type Configurations map[string]*Configuration - -// HTTPConfiguration contains all the HTTP configuration parameters. -type HTTPConfiguration struct { - Routers map[string]*Router `json:"routers,omitempty" toml:",omitempty"` - Middlewares map[string]*Middleware `json:"middlewares,omitempty" toml:",omitempty"` - Services map[string]*Service `json:"services,omitempty" toml:",omitempty"` -} - -// TCPConfiguration contains all the TCP configuration parameters. -type TCPConfiguration struct { - Routers map[string]*TCPRouter `json:"routers,omitempty" toml:",omitempty"` - Services map[string]*TCPService `json:"services,omitempty" toml:",omitempty"` -} - -// Service holds a service configuration (can only be of one type at the same time). -type Service struct { - LoadBalancer *LoadBalancerService `json:"loadbalancer,omitempty" toml:",omitempty,omitzero"` -} - -// TCPService holds a tcp service configuration (can only be of one type at the same time). -type TCPService struct { - LoadBalancer *TCPLoadBalancerService `json:"loadbalancer,omitempty" toml:",omitempty,omitzero"` + Timeout string `json:"timeout,omitempty" toml:"timeout,omitempty" yaml:"timeout,omitempty"` + Hostname string `json:"hostname,omitempty" toml:"hostname,omitempty" yaml:"hostname,omitempty"` + Headers map[string]string `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty"` } diff --git a/pkg/config/file/file_node_test.go b/pkg/config/file/file_node_test.go index a8e1cb7a9..2a54fb47f 100644 --- a/pkg/config/file/file_node_test.go +++ b/pkg/config/file/file_node_test.go @@ -67,267 +67,235 @@ func Test_decodeFileToNode_Toml(t *testing.T) { expected := &parser.Node{ Name: "traefik", Children: []*parser.Node{ - {Name: "ACME", - Children: []*parser.Node{ - {Name: "ACMELogging", Value: "true"}, - {Name: "CAServer", Value: "foobar"}, - {Name: "DNSChallenge", Children: []*parser.Node{ - {Name: "DelayBeforeCheck", Value: "42"}, - {Name: "DisablePropagationCheck", Value: "true"}, - {Name: "Provider", Value: "foobar"}, - {Name: "Resolvers", Value: "foobar,foobar"}, - }}, - {Name: "Domains", Children: []*parser.Node{ - {Name: "[0]", Children: []*parser.Node{ - {Name: "Main", Value: "foobar"}, - {Name: "SANs", Value: "foobar,foobar"}, - }}, - {Name: "[1]", Children: []*parser.Node{ - {Name: "Main", Value: "foobar"}, - {Name: "SANs", Value: "foobar,foobar"}, - }}, - }}, - {Name: "Email", Value: "foobar"}, - {Name: "EntryPoint", Value: "foobar"}, - {Name: "HTTPChallenge", Children: []*parser.Node{ - {Name: "EntryPoint", Value: "foobar"}}}, - {Name: "KeyType", Value: "foobar"}, - {Name: "OnHostRule", Value: "true"}, - {Name: "Storage", Value: "foobar"}, - {Name: "TLSChallenge"}, - }, - }, - {Name: "API", Children: []*parser.Node{ - {Name: "Dashboard", Value: "true"}, - {Name: "EntryPoint", Value: "foobar"}, - {Name: "Middlewares", Value: "foobar,foobar"}, - {Name: "Statistics", Children: []*parser.Node{ - {Name: "RecentErrors", Value: "42"}}}}}, - {Name: "AccessLog", Children: []*parser.Node{ - {Name: "BufferingSize", Value: "42"}, - {Name: "Fields", Children: []*parser.Node{ - {Name: "DefaultMode", Value: "foobar"}, - {Name: "Headers", Children: []*parser.Node{ - {Name: "DefaultMode", Value: "foobar"}, - {Name: "Names", Children: []*parser.Node{ + {Name: "accessLog", Children: []*parser.Node{ + {Name: "bufferingSize", Value: "42"}, + {Name: "fields", Children: []*parser.Node{ + {Name: "defaultMode", Value: "foobar"}, + {Name: "headers", Children: []*parser.Node{ + {Name: "defaultMode", Value: "foobar"}, + {Name: "names", Children: []*parser.Node{ {Name: "name0", Value: "foobar"}, {Name: "name1", Value: "foobar"}}}}}, - {Name: "Names", Children: []*parser.Node{ + {Name: "names", Children: []*parser.Node{ {Name: "name0", Value: "foobar"}, {Name: "name1", Value: "foobar"}}}}}, - {Name: "FilePath", Value: "foobar"}, - {Name: "Filters", Children: []*parser.Node{ - {Name: "MinDuration", Value: "42"}, - {Name: "RetryAttempts", Value: "true"}, - {Name: "StatusCodes", Value: "foobar,foobar"}}}, - {Name: "Format", Value: "foobar"}}}, - {Name: "EntryPoints", Children: []*parser.Node{ + {Name: "filePath", Value: "foobar"}, + {Name: "filters", Children: []*parser.Node{ + {Name: "minDuration", Value: "42"}, + {Name: "retryAttempts", Value: "true"}, + {Name: "statusCodes", Value: "foobar,foobar"}}}, + {Name: "format", Value: "foobar"}}}, + {Name: "acme", + Children: []*parser.Node{ + {Name: "acmeLogging", Value: "true"}, + {Name: "caServer", Value: "foobar"}, + {Name: "dnsChallenge", Children: []*parser.Node{ + {Name: "delayBeforeCheck", Value: "42"}, + {Name: "disablePropagationCheck", Value: "true"}, + {Name: "provider", Value: "foobar"}, + {Name: "resolvers", Value: "foobar,foobar"}, + }}, + {Name: "domains", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "main", Value: "foobar"}, + {Name: "sans", Value: "foobar,foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "main", Value: "foobar"}, + {Name: "sans", Value: "foobar,foobar"}, + }}, + }}, + {Name: "email", Value: "foobar"}, + {Name: "entryPoint", Value: "foobar"}, + {Name: "httpChallenge", Children: []*parser.Node{ + {Name: "entryPoint", Value: "foobar"}}}, + {Name: "keyType", Value: "foobar"}, + {Name: "onHostRule", Value: "true"}, + {Name: "storage", Value: "foobar"}, + {Name: "tlsChallenge"}, + }, + }, + {Name: "api", Children: []*parser.Node{ + {Name: "dashboard", Value: "true"}, + {Name: "entryPoint", Value: "foobar"}, + {Name: "middlewares", Value: "foobar,foobar"}, + {Name: "statistics", Children: []*parser.Node{ + {Name: "recentErrors", Value: "42"}}}}}, + {Name: "entryPoints", Children: []*parser.Node{ {Name: "EntryPoint0", Children: []*parser.Node{ - {Name: "Address", Value: "foobar"}, - {Name: "ForwardedHeaders", Children: []*parser.Node{ - {Name: "Insecure", Value: "true"}, - {Name: "TrustedIPs", Value: "foobar,foobar"}}}, - {Name: "ProxyProtocol", Children: []*parser.Node{ - {Name: "Insecure", Value: "true"}, - {Name: "TrustedIPs", Value: "foobar,foobar"}}}, - {Name: "Transport", Children: []*parser.Node{ - {Name: "LifeCycle", Children: []*parser.Node{ - {Name: "GraceTimeOut", Value: "42"}, - {Name: "RequestAcceptGraceTimeout", Value: "42"}}}, - {Name: "RespondingTimeouts", Children: []*parser.Node{ - {Name: "IdleTimeout", Value: "42"}, - {Name: "ReadTimeout", Value: "42"}, - {Name: "WriteTimeout", Value: "42"}}}}}}}}}, - {Name: "Global", Children: []*parser.Node{ - {Name: "CheckNewVersion", Value: "true"}, - {Name: "Debug", Value: "true"}, - {Name: "SendAnonymousUsage", Value: "true"}}}, - {Name: "HostResolver", Children: []*parser.Node{ - {Name: "CnameFlattening", Value: "true"}, - {Name: "ResolvConfig", Value: "foobar"}, - {Name: "ResolvDepth", Value: "42"}}}, - {Name: "Log", Children: []*parser.Node{ - {Name: "FilePath", Value: "foobar"}, - {Name: "Format", Value: "foobar"}, - {Name: "Level", Value: "foobar"}}}, - {Name: "Metrics", Children: []*parser.Node{ - {Name: "Datadog", Children: []*parser.Node{ - {Name: "Address", Value: "foobar"}, - {Name: "PushInterval", Value: "10s"}}}, - {Name: "InfluxDB", Children: []*parser.Node{ - {Name: "Address", Value: "foobar"}, - {Name: "Database", Value: "foobar"}, - {Name: "Password", Value: "foobar"}, - {Name: "Protocol", Value: "foobar"}, - {Name: "PushInterval", Value: "10s"}, - {Name: "RetentionPolicy", Value: "foobar"}, - {Name: "Username", Value: "foobar"}}}, - {Name: "Prometheus", Children: []*parser.Node{ - {Name: "Buckets", Value: "42,42"}, - {Name: "EntryPoint", Value: "foobar"}, - {Name: "Middlewares", Value: "foobar,foobar"}}}, - {Name: "StatsD", Children: []*parser.Node{ - {Name: "Address", Value: "foobar"}, - {Name: "PushInterval", Value: "10s"}}}}}, - {Name: "Ping", Children: []*parser.Node{ - {Name: "EntryPoint", Value: "foobar"}, - {Name: "Middlewares", Value: "foobar,foobar"}}}, - {Name: "Providers", Children: []*parser.Node{ - {Name: "Docker", Children: []*parser.Node{ - {Name: "Constraints", Children: []*parser.Node{ - {Name: "[0]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - {Name: "[1]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - }}, - {Name: "DefaultRule", Value: "foobar"}, - {Name: "Endpoint", Value: "foobar"}, - {Name: "ExposedByDefault", Value: "true"}, - {Name: "Network", Value: "foobar"}, - {Name: "SwarmMode", Value: "true"}, - {Name: "SwarmModeRefreshSeconds", Value: "42"}, - {Name: "TLS", Children: []*parser.Node{ - {Name: "CA", Value: "foobar"}, - {Name: "CAOptional", Value: "true"}, - {Name: "Cert", Value: "foobar"}, - {Name: "InsecureSkipVerify", Value: "true"}, - {Name: "Key", Value: "foobar"}}}, - {Name: "UseBindPortIP", Value: "true"}, - {Name: "Watch", Value: "true"}}}, - {Name: "File", Children: []*parser.Node{ - {Name: "DebugLogGeneratedTemplate", Value: "true"}, - {Name: "Directory", Value: "foobar"}, - {Name: "Filename", Value: "foobar"}, - {Name: "TraefikFile", Value: "foobar"}, - {Name: "Watch", Value: "true"}}}, - {Name: "Kubernetes", Children: []*parser.Node{ - {Name: "CertAuthFilePath", Value: "foobar"}, - {Name: "DisablePassHostHeaders", Value: "true"}, - {Name: "Endpoint", Value: "foobar"}, - {Name: "IngressClass", Value: "foobar"}, - {Name: "IngressEndpoint", Children: []*parser.Node{ - {Name: "Hostname", Value: "foobar"}, - {Name: "IP", Value: "foobar"}, - {Name: "PublishedService", Value: "foobar"}}}, - {Name: "LabelSelector", Value: "foobar"}, - {Name: "Namespaces", Value: "foobar,foobar"}, - {Name: "Token", Value: "foobar"}}}, - {Name: "KubernetesCRD", + {Name: "address", Value: "foobar"}, + {Name: "forwardedHeaders", Children: []*parser.Node{ + {Name: "insecure", Value: "true"}, + {Name: "trustedIPs", Value: "foobar,foobar"}}}, + {Name: "proxyProtocol", Children: []*parser.Node{ + {Name: "insecure", Value: "true"}, + {Name: "trustedIPs", Value: "foobar,foobar"}}}, + {Name: "transport", Children: []*parser.Node{ + {Name: "lifeCycle", Children: []*parser.Node{ + {Name: "graceTimeOut", Value: "42"}, + {Name: "requestAcceptGraceTimeout", Value: "42"}}}, + {Name: "respondingTimeouts", Children: []*parser.Node{ + {Name: "idleTimeout", Value: "42"}, + {Name: "readTimeout", Value: "42"}, + {Name: "writeTimeout", Value: "42"}}}}}}}}}, + {Name: "global", Children: []*parser.Node{ + {Name: "checkNewVersion", Value: "true"}, + {Name: "sendAnonymousUsage", Value: "true"}}}, + {Name: "hostResolver", Children: []*parser.Node{ + {Name: "cnameFlattening", Value: "true"}, + {Name: "resolvConfig", Value: "foobar"}, + {Name: "resolvDepth", Value: "42"}}}, + {Name: "log", Children: []*parser.Node{ + {Name: "filePath", Value: "foobar"}, + {Name: "format", Value: "foobar"}, + {Name: "level", Value: "foobar"}}}, + {Name: "metrics", Children: []*parser.Node{ + {Name: "dataDog", Children: []*parser.Node{ + {Name: "address", Value: "foobar"}, + {Name: "pushInterval", Value: "10s"}}}, + {Name: "influxDB", Children: []*parser.Node{ + {Name: "address", Value: "foobar"}, + {Name: "database", Value: "foobar"}, + {Name: "password", Value: "foobar"}, + {Name: "protocol", Value: "foobar"}, + {Name: "pushInterval", Value: "10s"}, + {Name: "retentionPolicy", Value: "foobar"}, + {Name: "username", Value: "foobar"}}}, + {Name: "prometheus", Children: []*parser.Node{ + {Name: "buckets", Value: "42,42"}, + {Name: "entryPoint", Value: "foobar"}, + {Name: "middlewares", Value: "foobar,foobar"}}}, + {Name: "statsD", Children: []*parser.Node{ + {Name: "address", Value: "foobar"}, + {Name: "pushInterval", Value: "10s"}}}}}, + {Name: "ping", Children: []*parser.Node{ + {Name: "entryPoint", Value: "foobar"}, + {Name: "middlewares", Value: "foobar,foobar"}}}, + {Name: "providers", Children: []*parser.Node{ + {Name: "docker", Children: []*parser.Node{ + {Name: "constraints", Value: "foobar"}, + {Name: "defaultRule", Value: "foobar"}, + {Name: "endpoint", Value: "foobar"}, + {Name: "exposedByDefault", Value: "true"}, + {Name: "network", Value: "foobar"}, + {Name: "swarmMode", Value: "true"}, + {Name: "swarmModeRefreshSeconds", Value: "42"}, + {Name: "tls", Children: []*parser.Node{ + {Name: "ca", Value: "foobar"}, + {Name: "caOptional", Value: "true"}, + {Name: "cert", Value: "foobar"}, + {Name: "insecureSkipVerify", Value: "true"}, + {Name: "key", Value: "foobar"}}}, + {Name: "useBindPortIP", Value: "true"}, + {Name: "watch", Value: "true"}}}, + {Name: "file", Children: []*parser.Node{ + {Name: "debugLogGeneratedTemplate", Value: "true"}, + {Name: "directory", Value: "foobar"}, + {Name: "filename", Value: "foobar"}, + {Name: "traefikFile", Value: "foobar"}, + {Name: "watch", Value: "true"}}}, + {Name: "kubernetes", Children: []*parser.Node{ + {Name: "certAuthFilePath", Value: "foobar"}, + {Name: "disablePassHostHeaders", Value: "true"}, + {Name: "endpoint", Value: "foobar"}, + {Name: "ingressClass", Value: "foobar"}, + {Name: "ingressEndpoint", Children: []*parser.Node{ + {Name: "hostname", Value: "foobar"}, + {Name: "ip", Value: "foobar"}, + {Name: "publishedService", Value: "foobar"}}}, + {Name: "labelSelector", Value: "foobar"}, + {Name: "namespaces", Value: "foobar,foobar"}, + {Name: "token", Value: "foobar"}}}, + {Name: "kubernetesCRD", Children: []*parser.Node{ - {Name: "CertAuthFilePath", Value: "foobar"}, - {Name: "DisablePassHostHeaders", Value: "true"}, - {Name: "Endpoint", Value: "foobar"}, - {Name: "IngressClass", Value: "foobar"}, - {Name: "LabelSelector", Value: "foobar"}, - {Name: "Namespaces", Value: "foobar,foobar"}, - {Name: "Token", Value: "foobar"}}}, - {Name: "Marathon", Children: []*parser.Node{ - {Name: "Basic", Children: []*parser.Node{ - {Name: "HTTPBasicAuthUser", Value: "foobar"}, - {Name: "HTTPBasicPassword", Value: "foobar"}}}, - {Name: "Constraints", Children: []*parser.Node{ - {Name: "[0]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - {Name: "[1]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - }}, - {Name: "DCOSToken", Value: "foobar"}, - {Name: "DefaultRule", Value: "foobar"}, - {Name: "DialerTimeout", Value: "42"}, - {Name: "Endpoint", Value: "foobar"}, - {Name: "ExposedByDefault", Value: "true"}, - {Name: "ForceTaskHostname", Value: "true"}, - {Name: "KeepAlive", Value: "42"}, - {Name: "RespectReadinessChecks", Value: "true"}, - {Name: "ResponseHeaderTimeout", Value: "42"}, - {Name: "TLS", Children: []*parser.Node{ - {Name: "CA", Value: "foobar"}, - {Name: "CAOptional", Value: "true"}, - {Name: "Cert", Value: "foobar"}, - {Name: "InsecureSkipVerify", Value: "true"}, - {Name: "Key", Value: "foobar"}}}, - {Name: "TLSHandshakeTimeout", Value: "42"}, - {Name: "Trace", Value: "true"}, - {Name: "Watch", Value: "true"}}}, - {Name: "ProvidersThrottleDuration", Value: "42"}, - {Name: "Rancher", Children: []*parser.Node{ - {Name: "Constraints", Children: []*parser.Node{ - {Name: "[0]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - {Name: "[1]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - }}, - {Name: "DefaultRule", Value: "foobar"}, - {Name: "EnableServiceHealthFilter", Value: "true"}, - {Name: "ExposedByDefault", Value: "true"}, - {Name: "IntervalPoll", Value: "true"}, - {Name: "Prefix", Value: "foobar"}, - {Name: "RefreshSeconds", Value: "42"}, - {Name: "Watch", Value: "true"}}}, - {Name: "Rest", Children: []*parser.Node{ - {Name: "EntryPoint", Value: "foobar"}}}}}, - {Name: "ServersTransport", Children: []*parser.Node{ - {Name: "ForwardingTimeouts", Children: []*parser.Node{ - {Name: "DialTimeout", Value: "42"}, - {Name: "ResponseHeaderTimeout", Value: "42"}}}, - {Name: "InsecureSkipVerify", Value: "true"}, - {Name: "MaxIdleConnsPerHost", Value: "42"}, - {Name: "RootCAs", Value: "foobar,foobar"}}}, - {Name: "Tracing", Children: []*parser.Node{ - {Name: "DataDog", Children: []*parser.Node{ - {Name: "BagagePrefixHeaderName", Value: "foobar"}, - {Name: "Debug", Value: "true"}, - {Name: "GlobalTag", Value: "foobar"}, - {Name: "LocalAgentHostPort", Value: "foobar"}, - {Name: "ParentIDHeaderName", Value: "foobar"}, - {Name: "PrioritySampling", Value: "true"}, - {Name: "SamplingPriorityHeaderName", Value: "foobar"}, - {Name: "TraceIDHeaderName", Value: "foobar"}}}, - {Name: "Haystack", Children: []*parser.Node{ - {Name: "GlobalTag", Value: "foobar"}, - {Name: "LocalAgentHost", Value: "foobar"}, - {Name: "LocalAgentPort", Value: "42"}, - {Name: "ParentIDHeaderName", Value: "foobar"}, - {Name: "SpanIDHeaderName", Value: "foobar"}, - {Name: "TraceIDHeaderName", Value: "foobar"}}}, - {Name: "Instana", Children: []*parser.Node{ - {Name: "LocalAgentHost", Value: "foobar"}, - {Name: "LocalAgentPort", Value: "42"}, - {Name: "LogLevel", Value: "foobar"}}}, - {Name: "Jaeger", Children: []*parser.Node{ - {Name: "Gen128Bit", Value: "true"}, - {Name: "LocalAgentHostPort", Value: "foobar"}, - {Name: "Propagation", Value: "foobar"}, - {Name: "SamplingParam", Value: "42"}, - {Name: "SamplingServerURL", Value: "foobar"}, - {Name: "SamplingType", Value: "foobar"}, - {Name: "TraceContextHeaderName", Value: "foobar"}}}, - {Name: "ServiceName", Value: "foobar"}, - {Name: "SpanNameLimit", Value: "42"}, - {Name: "Zipkin", Children: []*parser.Node{ - {Name: "Debug", Value: "true"}, - {Name: "HTTPEndpoint", Value: "foobar"}, - {Name: "ID128Bit", Value: "true"}, - {Name: "SameSpan", Value: "true"}, - {Name: "SampleRate", Value: "42"}}}}}}, + {Name: "certAuthFilePath", Value: "foobar"}, + {Name: "disablePassHostHeaders", Value: "true"}, + {Name: "endpoint", Value: "foobar"}, + {Name: "ingressClass", Value: "foobar"}, + {Name: "labelSelector", Value: "foobar"}, + {Name: "namespaces", Value: "foobar,foobar"}, + {Name: "token", Value: "foobar"}}}, + {Name: "marathon", Children: []*parser.Node{ + {Name: "basic", Children: []*parser.Node{ + {Name: "httpBasicAuthUser", Value: "foobar"}, + {Name: "httpBasicPassword", Value: "foobar"}}}, + {Name: "constraints", Value: "foobar"}, + {Name: "dcosToken", Value: "foobar"}, + {Name: "defaultRule", Value: "foobar"}, + {Name: "dialerTimeout", Value: "42"}, + {Name: "endpoint", Value: "foobar"}, + {Name: "exposedByDefault", Value: "true"}, + {Name: "forceTaskHostname", Value: "true"}, + {Name: "keepAlive", Value: "42"}, + {Name: "respectReadinessChecks", Value: "true"}, + {Name: "responseHeaderTimeout", Value: "42"}, + {Name: "tls", Children: []*parser.Node{ + {Name: "ca", Value: "foobar"}, + {Name: "caOptional", Value: "true"}, + {Name: "cert", Value: "foobar"}, + {Name: "insecureSkipVerify", Value: "true"}, + {Name: "key", Value: "foobar"}}}, + {Name: "tlsHandshakeTimeout", Value: "42"}, + {Name: "trace", Value: "true"}, + {Name: "watch", Value: "true"}}}, + {Name: "providersThrottleDuration", Value: "42"}, + {Name: "rancher", Children: []*parser.Node{ + {Name: "constraints", Value: "foobar"}, + {Name: "defaultRule", Value: "foobar"}, + {Name: "enableServiceHealthFilter", Value: "true"}, + {Name: "exposedByDefault", Value: "true"}, + {Name: "intervalPoll", Value: "true"}, + {Name: "prefix", Value: "foobar"}, + {Name: "refreshSeconds", Value: "42"}, + {Name: "watch", Value: "true"}}}, + {Name: "rest", Children: []*parser.Node{ + {Name: "entryPoint", Value: "foobar"}}}}}, + {Name: "serversTransport", Children: []*parser.Node{ + {Name: "forwardingTimeouts", Children: []*parser.Node{ + {Name: "dialTimeout", Value: "42"}, + {Name: "idleConnTimeout", Value: "42"}, + {Name: "responseHeaderTimeout", Value: "42"}}}, + {Name: "insecureSkipVerify", Value: "true"}, + {Name: "maxIdleConnsPerHost", Value: "42"}, + {Name: "rootCAs", Value: "foobar,foobar"}}}, + {Name: "tracing", Children: []*parser.Node{ + {Name: "dataDog", Children: []*parser.Node{ + {Name: "bagagePrefixHeaderName", Value: "foobar"}, + {Name: "debug", Value: "true"}, + {Name: "globalTag", Value: "foobar"}, + {Name: "localAgentHostPort", Value: "foobar"}, + {Name: "parentIDHeaderName", Value: "foobar"}, + {Name: "prioritySampling", Value: "true"}, + {Name: "samplingPriorityHeaderName", Value: "foobar"}, + {Name: "traceIDHeaderName", Value: "foobar"}}}, + {Name: "haystack", Children: []*parser.Node{ + {Name: "globalTag", Value: "foobar"}, + {Name: "localAgentHost", Value: "foobar"}, + {Name: "localAgentPort", Value: "42"}, + {Name: "parentIDHeaderName", Value: "foobar"}, + {Name: "spanIDHeaderName", Value: "foobar"}, + {Name: "traceIDHeaderName", Value: "foobar"}}}, + {Name: "instana", Children: []*parser.Node{ + {Name: "localAgentHost", Value: "foobar"}, + {Name: "localAgentPort", Value: "42"}, + {Name: "logLevel", Value: "foobar"}}}, + {Name: "jaeger", Children: []*parser.Node{ + {Name: "gen128Bit", Value: "true"}, + {Name: "localAgentHostPort", Value: "foobar"}, + {Name: "propagation", Value: "foobar"}, + {Name: "samplingParam", Value: "42"}, + {Name: "samplingServerURL", Value: "foobar"}, + {Name: "samplingType", Value: "foobar"}, + {Name: "traceContextHeaderName", Value: "foobar"}}}, + {Name: "serviceName", Value: "foobar"}, + {Name: "spanNameLimit", Value: "42"}, + {Name: "zipkin", Children: []*parser.Node{ + {Name: "debug", Value: "true"}, + {Name: "httpEndpoint", Value: "foobar"}, + {Name: "id128Bit", Value: "true"}, + {Name: "sameSpan", Value: "true"}, + {Name: "sampleRate", Value: "42"}}}}}, + }, } assert.Equal(t, expected, node) @@ -342,267 +310,235 @@ func Test_decodeFileToNode_Yaml(t *testing.T) { expected := &parser.Node{ Name: "traefik", Children: []*parser.Node{ - {Name: "ACME", - Children: []*parser.Node{ - {Name: "ACMELogging", Value: "true"}, - {Name: "CAServer", Value: "foobar"}, - {Name: "DNSChallenge", Children: []*parser.Node{ - {Name: "DelayBeforeCheck", Value: "42"}, - {Name: "DisablePropagationCheck", Value: "true"}, - {Name: "Provider", Value: "foobar"}, - {Name: "Resolvers", Value: "foobar,foobar"}, - }}, - {Name: "Domains", Children: []*parser.Node{ - {Name: "[0]", Children: []*parser.Node{ - {Name: "Main", Value: "foobar"}, - {Name: "SANs", Value: "foobar,foobar"}, - }}, - {Name: "[1]", Children: []*parser.Node{ - {Name: "Main", Value: "foobar"}, - {Name: "SANs", Value: "foobar,foobar"}, - }}, - }}, - {Name: "Email", Value: "foobar"}, - {Name: "EntryPoint", Value: "foobar"}, - {Name: "HTTPChallenge", Children: []*parser.Node{ - {Name: "EntryPoint", Value: "foobar"}}}, - {Name: "KeyType", Value: "foobar"}, - {Name: "OnHostRule", Value: "true"}, - {Name: "Storage", Value: "foobar"}, - {Name: "TLSChallenge"}, - }, - }, - {Name: "API", Children: []*parser.Node{ - {Name: "Dashboard", Value: "true"}, - {Name: "EntryPoint", Value: "foobar"}, - {Name: "Middlewares", Value: "foobar,foobar"}, - {Name: "Statistics", Children: []*parser.Node{ - {Name: "RecentErrors", Value: "42"}}}}}, - {Name: "AccessLog", Children: []*parser.Node{ - {Name: "BufferingSize", Value: "42"}, - {Name: "Fields", Children: []*parser.Node{ - {Name: "DefaultMode", Value: "foobar"}, - {Name: "Headers", Children: []*parser.Node{ - {Name: "DefaultMode", Value: "foobar"}, - {Name: "Names", Children: []*parser.Node{ + {Name: "accessLog", Children: []*parser.Node{ + {Name: "bufferingSize", Value: "42"}, + {Name: "fields", Children: []*parser.Node{ + {Name: "defaultMode", Value: "foobar"}, + {Name: "headers", Children: []*parser.Node{ + {Name: "defaultMode", Value: "foobar"}, + {Name: "names", Children: []*parser.Node{ {Name: "name0", Value: "foobar"}, {Name: "name1", Value: "foobar"}}}}}, - {Name: "Names", Children: []*parser.Node{ + {Name: "names", Children: []*parser.Node{ {Name: "name0", Value: "foobar"}, {Name: "name1", Value: "foobar"}}}}}, - {Name: "FilePath", Value: "foobar"}, - {Name: "Filters", Children: []*parser.Node{ - {Name: "MinDuration", Value: "42"}, - {Name: "RetryAttempts", Value: "true"}, - {Name: "StatusCodes", Value: "foobar,foobar"}}}, - {Name: "Format", Value: "foobar"}}}, - {Name: "EntryPoints", Children: []*parser.Node{ + {Name: "filePath", Value: "foobar"}, + {Name: "filters", Children: []*parser.Node{ + {Name: "minDuration", Value: "42"}, + {Name: "retryAttempts", Value: "true"}, + {Name: "statusCodes", Value: "foobar,foobar"}}}, + {Name: "format", Value: "foobar"}}}, + {Name: "acme", + Children: []*parser.Node{ + {Name: "acmeLogging", Value: "true"}, + {Name: "caServer", Value: "foobar"}, + {Name: "dnsChallenge", Children: []*parser.Node{ + {Name: "delayBeforeCheck", Value: "42"}, + {Name: "disablePropagationCheck", Value: "true"}, + {Name: "provider", Value: "foobar"}, + {Name: "resolvers", Value: "foobar,foobar"}, + }}, + {Name: "domains", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "main", Value: "foobar"}, + {Name: "sans", Value: "foobar,foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "main", Value: "foobar"}, + {Name: "sans", Value: "foobar,foobar"}, + }}, + }}, + {Name: "email", Value: "foobar"}, + {Name: "entryPoint", Value: "foobar"}, + {Name: "httpChallenge", Children: []*parser.Node{ + {Name: "entryPoint", Value: "foobar"}}}, + {Name: "keyType", Value: "foobar"}, + {Name: "onHostRule", Value: "true"}, + {Name: "storage", Value: "foobar"}, + {Name: "tlsChallenge"}, + }, + }, + {Name: "api", Children: []*parser.Node{ + {Name: "dashboard", Value: "true"}, + {Name: "entryPoint", Value: "foobar"}, + {Name: "middlewares", Value: "foobar,foobar"}, + {Name: "statistics", Children: []*parser.Node{ + {Name: "recentErrors", Value: "42"}}}}}, + {Name: "entryPoints", Children: []*parser.Node{ {Name: "EntryPoint0", Children: []*parser.Node{ - {Name: "Address", Value: "foobar"}, - {Name: "ForwardedHeaders", Children: []*parser.Node{ - {Name: "Insecure", Value: "true"}, - {Name: "TrustedIPs", Value: "foobar,foobar"}}}, - {Name: "ProxyProtocol", Children: []*parser.Node{ - {Name: "Insecure", Value: "true"}, - {Name: "TrustedIPs", Value: "foobar,foobar"}}}, - {Name: "Transport", Children: []*parser.Node{ - {Name: "LifeCycle", Children: []*parser.Node{ - {Name: "GraceTimeOut", Value: "42"}, - {Name: "RequestAcceptGraceTimeout", Value: "42"}}}, - {Name: "RespondingTimeouts", Children: []*parser.Node{ - {Name: "IdleTimeout", Value: "42"}, - {Name: "ReadTimeout", Value: "42"}, - {Name: "WriteTimeout", Value: "42"}}}}}}}}}, - {Name: "Global", Children: []*parser.Node{ - {Name: "CheckNewVersion", Value: "true"}, - {Name: "Debug", Value: "true"}, - {Name: "SendAnonymousUsage", Value: "true"}}}, - {Name: "HostResolver", Children: []*parser.Node{ - {Name: "CnameFlattening", Value: "true"}, - {Name: "ResolvConfig", Value: "foobar"}, - {Name: "ResolvDepth", Value: "42"}}}, - {Name: "Log", Children: []*parser.Node{ - {Name: "FilePath", Value: "foobar"}, - {Name: "Format", Value: "foobar"}, - {Name: "Level", Value: "foobar"}}}, - {Name: "Metrics", Children: []*parser.Node{ - {Name: "Datadog", Children: []*parser.Node{ - {Name: "Address", Value: "foobar"}, - {Name: "PushInterval", Value: "10s"}}}, - {Name: "InfluxDB", Children: []*parser.Node{ - {Name: "Address", Value: "foobar"}, - {Name: "Database", Value: "foobar"}, - {Name: "Password", Value: "foobar"}, - {Name: "Protocol", Value: "foobar"}, - {Name: "PushInterval", Value: "10s"}, - {Name: "RetentionPolicy", Value: "foobar"}, - {Name: "Username", Value: "foobar"}}}, - {Name: "Prometheus", Children: []*parser.Node{ - {Name: "Buckets", Value: "42,42"}, - {Name: "EntryPoint", Value: "foobar"}, - {Name: "Middlewares", Value: "foobar,foobar"}}}, - {Name: "StatsD", Children: []*parser.Node{ - {Name: "Address", Value: "foobar"}, - {Name: "PushInterval", Value: "10s"}}}}}, - {Name: "Ping", Children: []*parser.Node{ - {Name: "EntryPoint", Value: "foobar"}, - {Name: "Middlewares", Value: "foobar,foobar"}}}, - {Name: "Providers", Children: []*parser.Node{ - {Name: "Docker", Children: []*parser.Node{ - {Name: "Constraints", Children: []*parser.Node{ - {Name: "[0]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - {Name: "[1]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - }}, - {Name: "DefaultRule", Value: "foobar"}, - {Name: "Endpoint", Value: "foobar"}, - {Name: "ExposedByDefault", Value: "true"}, - {Name: "Network", Value: "foobar"}, - {Name: "SwarmMode", Value: "true"}, - {Name: "SwarmModeRefreshSeconds", Value: "42"}, - {Name: "TLS", Children: []*parser.Node{ - {Name: "CA", Value: "foobar"}, - {Name: "CAOptional", Value: "true"}, - {Name: "Cert", Value: "foobar"}, - {Name: "InsecureSkipVerify", Value: "true"}, - {Name: "Key", Value: "foobar"}}}, - {Name: "UseBindPortIP", Value: "true"}, - {Name: "Watch", Value: "true"}}}, - {Name: "File", Children: []*parser.Node{ - {Name: "DebugLogGeneratedTemplate", Value: "true"}, - {Name: "Directory", Value: "foobar"}, - {Name: "Filename", Value: "foobar"}, - {Name: "TraefikFile", Value: "foobar"}, - {Name: "Watch", Value: "true"}}}, - {Name: "Kubernetes", Children: []*parser.Node{ - {Name: "CertAuthFilePath", Value: "foobar"}, - {Name: "DisablePassHostHeaders", Value: "true"}, - {Name: "Endpoint", Value: "foobar"}, - {Name: "IngressClass", Value: "foobar"}, - {Name: "IngressEndpoint", Children: []*parser.Node{ - {Name: "Hostname", Value: "foobar"}, - {Name: "IP", Value: "foobar"}, - {Name: "PublishedService", Value: "foobar"}}}, - {Name: "LabelSelector", Value: "foobar"}, - {Name: "Namespaces", Value: "foobar,foobar"}, - {Name: "Token", Value: "foobar"}}}, - {Name: "KubernetesCRD", + {Name: "address", Value: "foobar"}, + {Name: "forwardedHeaders", Children: []*parser.Node{ + {Name: "insecure", Value: "true"}, + {Name: "trustedIPs", Value: "foobar,foobar"}}}, + {Name: "proxyProtocol", Children: []*parser.Node{ + {Name: "insecure", Value: "true"}, + {Name: "trustedIPs", Value: "foobar,foobar"}}}, + {Name: "transport", Children: []*parser.Node{ + {Name: "lifeCycle", Children: []*parser.Node{ + {Name: "graceTimeOut", Value: "42"}, + {Name: "requestAcceptGraceTimeout", Value: "42"}}}, + {Name: "respondingTimeouts", Children: []*parser.Node{ + {Name: "idleTimeout", Value: "42"}, + {Name: "readTimeout", Value: "42"}, + {Name: "writeTimeout", Value: "42"}}}}}}}}}, + {Name: "global", Children: []*parser.Node{ + {Name: "checkNewVersion", Value: "true"}, + {Name: "sendAnonymousUsage", Value: "true"}}}, + {Name: "hostResolver", Children: []*parser.Node{ + {Name: "cnameFlattening", Value: "true"}, + {Name: "resolvConfig", Value: "foobar"}, + {Name: "resolvDepth", Value: "42"}}}, + {Name: "log", Children: []*parser.Node{ + {Name: "filePath", Value: "foobar"}, + {Name: "format", Value: "foobar"}, + {Name: "level", Value: "foobar"}}}, + {Name: "metrics", Children: []*parser.Node{ + {Name: "dataDog", Children: []*parser.Node{ + {Name: "address", Value: "foobar"}, + {Name: "pushInterval", Value: "10s"}}}, + {Name: "influxDB", Children: []*parser.Node{ + {Name: "address", Value: "foobar"}, + {Name: "database", Value: "foobar"}, + {Name: "password", Value: "foobar"}, + {Name: "protocol", Value: "foobar"}, + {Name: "pushInterval", Value: "10s"}, + {Name: "retentionPolicy", Value: "foobar"}, + {Name: "username", Value: "foobar"}}}, + {Name: "prometheus", Children: []*parser.Node{ + {Name: "buckets", Value: "42,42"}, + {Name: "entryPoint", Value: "foobar"}, + {Name: "middlewares", Value: "foobar,foobar"}}}, + {Name: "statsD", Children: []*parser.Node{ + {Name: "address", Value: "foobar"}, + {Name: "pushInterval", Value: "10s"}}}}}, + {Name: "ping", Children: []*parser.Node{ + {Name: "entryPoint", Value: "foobar"}, + {Name: "middlewares", Value: "foobar,foobar"}}}, + {Name: "providers", Children: []*parser.Node{ + {Name: "docker", Children: []*parser.Node{ + {Name: "constraints", Value: "foobar"}, + {Name: "defaultRule", Value: "foobar"}, + {Name: "endpoint", Value: "foobar"}, + {Name: "exposedByDefault", Value: "true"}, + {Name: "network", Value: "foobar"}, + {Name: "swarmMode", Value: "true"}, + {Name: "swarmModeRefreshSeconds", Value: "42"}, + {Name: "tls", Children: []*parser.Node{ + {Name: "ca", Value: "foobar"}, + {Name: "caOptional", Value: "true"}, + {Name: "cert", Value: "foobar"}, + {Name: "insecureSkipVerify", Value: "true"}, + {Name: "key", Value: "foobar"}}}, + {Name: "useBindPortIP", Value: "true"}, + {Name: "watch", Value: "true"}}}, + {Name: "file", Children: []*parser.Node{ + {Name: "debugLogGeneratedTemplate", Value: "true"}, + {Name: "directory", Value: "foobar"}, + {Name: "filename", Value: "foobar"}, + {Name: "traefikFile", Value: "foobar"}, + {Name: "watch", Value: "true"}}}, + {Name: "kubernetes", Children: []*parser.Node{ + {Name: "certAuthFilePath", Value: "foobar"}, + {Name: "disablePassHostHeaders", Value: "true"}, + {Name: "endpoint", Value: "foobar"}, + {Name: "ingressClass", Value: "foobar"}, + {Name: "ingressEndpoint", Children: []*parser.Node{ + {Name: "hostname", Value: "foobar"}, + {Name: "ip", Value: "foobar"}, + {Name: "publishedService", Value: "foobar"}}}, + {Name: "labelSelector", Value: "foobar"}, + {Name: "namespaces", Value: "foobar,foobar"}, + {Name: "token", Value: "foobar"}}}, + {Name: "kubernetesCRD", Children: []*parser.Node{ - {Name: "CertAuthFilePath", Value: "foobar"}, - {Name: "DisablePassHostHeaders", Value: "true"}, - {Name: "Endpoint", Value: "foobar"}, - {Name: "IngressClass", Value: "foobar"}, - {Name: "LabelSelector", Value: "foobar"}, - {Name: "Namespaces", Value: "foobar,foobar"}, - {Name: "Token", Value: "foobar"}}}, - {Name: "Marathon", Children: []*parser.Node{ - {Name: "Basic", Children: []*parser.Node{ - {Name: "HTTPBasicAuthUser", Value: "foobar"}, - {Name: "HTTPBasicPassword", Value: "foobar"}}}, - {Name: "Constraints", Children: []*parser.Node{ - {Name: "[0]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - {Name: "[1]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - }}, - {Name: "DCOSToken", Value: "foobar"}, - {Name: "DefaultRule", Value: "foobar"}, - {Name: "DialerTimeout", Value: "42"}, - {Name: "Endpoint", Value: "foobar"}, - {Name: "ExposedByDefault", Value: "true"}, - {Name: "ForceTaskHostname", Value: "true"}, - {Name: "KeepAlive", Value: "42"}, - {Name: "RespectReadinessChecks", Value: "true"}, - {Name: "ResponseHeaderTimeout", Value: "42"}, - {Name: "TLS", Children: []*parser.Node{ - {Name: "CA", Value: "foobar"}, - {Name: "CAOptional", Value: "true"}, - {Name: "Cert", Value: "foobar"}, - {Name: "InsecureSkipVerify", Value: "true"}, - {Name: "Key", Value: "foobar"}}}, - {Name: "TLSHandshakeTimeout", Value: "42"}, - {Name: "Trace", Value: "true"}, - {Name: "Watch", Value: "true"}}}, - {Name: "ProvidersThrottleDuration", Value: "42"}, - {Name: "Rancher", Children: []*parser.Node{ - {Name: "Constraints", Children: []*parser.Node{ - {Name: "[0]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - {Name: "[1]", Children: []*parser.Node{ - {Name: "Key", Value: "foobar"}, - {Name: "MustMatch", Value: "true"}, - {Name: "Value", Value: "foobar"}, - }}, - }}, - {Name: "DefaultRule", Value: "foobar"}, - {Name: "EnableServiceHealthFilter", Value: "true"}, - {Name: "ExposedByDefault", Value: "true"}, - {Name: "IntervalPoll", Value: "true"}, - {Name: "Prefix", Value: "foobar"}, - {Name: "RefreshSeconds", Value: "42"}, - {Name: "Watch", Value: "true"}}}, - {Name: "Rest", Children: []*parser.Node{ - {Name: "EntryPoint", Value: "foobar"}}}}}, - {Name: "ServersTransport", Children: []*parser.Node{ - {Name: "ForwardingTimeouts", Children: []*parser.Node{ - {Name: "DialTimeout", Value: "42"}, - {Name: "ResponseHeaderTimeout", Value: "42"}}}, - {Name: "InsecureSkipVerify", Value: "true"}, - {Name: "MaxIdleConnsPerHost", Value: "42"}, - {Name: "RootCAs", Value: "foobar,foobar"}}}, - {Name: "Tracing", Children: []*parser.Node{ - {Name: "DataDog", Children: []*parser.Node{ - {Name: "BagagePrefixHeaderName", Value: "foobar"}, - {Name: "Debug", Value: "true"}, - {Name: "GlobalTag", Value: "foobar"}, - {Name: "LocalAgentHostPort", Value: "foobar"}, - {Name: "ParentIDHeaderName", Value: "foobar"}, - {Name: "PrioritySampling", Value: "true"}, - {Name: "SamplingPriorityHeaderName", Value: "foobar"}, - {Name: "TraceIDHeaderName", Value: "foobar"}}}, - {Name: "Haystack", Children: []*parser.Node{ - {Name: "GlobalTag", Value: "foobar"}, - {Name: "LocalAgentHost", Value: "foobar"}, - {Name: "LocalAgentPort", Value: "42"}, - {Name: "ParentIDHeaderName", Value: "foobar"}, - {Name: "SpanIDHeaderName", Value: "foobar"}, - {Name: "TraceIDHeaderName", Value: "foobar"}}}, - {Name: "Instana", Children: []*parser.Node{ - {Name: "LocalAgentHost", Value: "foobar"}, - {Name: "LocalAgentPort", Value: "42"}, - {Name: "LogLevel", Value: "foobar"}}}, - {Name: "Jaeger", Children: []*parser.Node{ - {Name: "Gen128Bit", Value: "true"}, - {Name: "LocalAgentHostPort", Value: "foobar"}, - {Name: "Propagation", Value: "foobar"}, - {Name: "SamplingParam", Value: "42"}, - {Name: "SamplingServerURL", Value: "foobar"}, - {Name: "SamplingType", Value: "foobar"}, - {Name: "TraceContextHeaderName", Value: "foobar"}}}, - {Name: "ServiceName", Value: "foobar"}, - {Name: "SpanNameLimit", Value: "42"}, - {Name: "Zipkin", Children: []*parser.Node{ - {Name: "Debug", Value: "true"}, - {Name: "HTTPEndpoint", Value: "foobar"}, - {Name: "ID128Bit", Value: "true"}, - {Name: "SameSpan", Value: "true"}, - {Name: "SampleRate", Value: "42"}}}}}}, + {Name: "certAuthFilePath", Value: "foobar"}, + {Name: "disablePassHostHeaders", Value: "true"}, + {Name: "endpoint", Value: "foobar"}, + {Name: "ingressClass", Value: "foobar"}, + {Name: "labelSelector", Value: "foobar"}, + {Name: "namespaces", Value: "foobar,foobar"}, + {Name: "token", Value: "foobar"}}}, + {Name: "marathon", Children: []*parser.Node{ + {Name: "basic", Children: []*parser.Node{ + {Name: "httpBasicAuthUser", Value: "foobar"}, + {Name: "httpBasicPassword", Value: "foobar"}}}, + {Name: "constraints", Value: "foobar"}, + {Name: "dcosToken", Value: "foobar"}, + {Name: "defaultRule", Value: "foobar"}, + {Name: "dialerTimeout", Value: "42"}, + {Name: "endpoint", Value: "foobar"}, + {Name: "exposedByDefault", Value: "true"}, + {Name: "forceTaskHostname", Value: "true"}, + {Name: "keepAlive", Value: "42"}, + {Name: "respectReadinessChecks", Value: "true"}, + {Name: "responseHeaderTimeout", Value: "42"}, + {Name: "tls", Children: []*parser.Node{ + {Name: "ca", Value: "foobar"}, + {Name: "caOptional", Value: "true"}, + {Name: "cert", Value: "foobar"}, + {Name: "insecureSkipVerify", Value: "true"}, + {Name: "key", Value: "foobar"}}}, + {Name: "tlsHandshakeTimeout", Value: "42"}, + {Name: "trace", Value: "true"}, + {Name: "watch", Value: "true"}}}, + {Name: "providersThrottleDuration", Value: "42"}, + {Name: "rancher", Children: []*parser.Node{ + {Name: "constraints", Value: "foobar"}, + {Name: "defaultRule", Value: "foobar"}, + {Name: "enableServiceHealthFilter", Value: "true"}, + {Name: "exposedByDefault", Value: "true"}, + {Name: "intervalPoll", Value: "true"}, + {Name: "prefix", Value: "foobar"}, + {Name: "refreshSeconds", Value: "42"}, + {Name: "watch", Value: "true"}}}, + {Name: "rest", Children: []*parser.Node{ + {Name: "entryPoint", Value: "foobar"}}}}}, + {Name: "serversTransport", Children: []*parser.Node{ + {Name: "forwardingTimeouts", Children: []*parser.Node{ + {Name: "dialTimeout", Value: "42"}, + {Name: "idleConnTimeout", Value: "42"}, + {Name: "responseHeaderTimeout", Value: "42"}}}, + {Name: "insecureSkipVerify", Value: "true"}, + {Name: "maxIdleConnsPerHost", Value: "42"}, + {Name: "rootCAs", Value: "foobar,foobar"}}}, + {Name: "tracing", Children: []*parser.Node{ + {Name: "dataDog", Children: []*parser.Node{ + {Name: "bagagePrefixHeaderName", Value: "foobar"}, + {Name: "debug", Value: "true"}, + {Name: "globalTag", Value: "foobar"}, + {Name: "localAgentHostPort", Value: "foobar"}, + {Name: "parentIDHeaderName", Value: "foobar"}, + {Name: "prioritySampling", Value: "true"}, + {Name: "samplingPriorityHeaderName", Value: "foobar"}, + {Name: "traceIDHeaderName", Value: "foobar"}}}, + {Name: "haystack", Children: []*parser.Node{ + {Name: "globalTag", Value: "foobar"}, + {Name: "localAgentHost", Value: "foobar"}, + {Name: "localAgentPort", Value: "42"}, + {Name: "parentIDHeaderName", Value: "foobar"}, + {Name: "spanIDHeaderName", Value: "foobar"}, + {Name: "traceIDHeaderName", Value: "foobar"}}}, + {Name: "instana", Children: []*parser.Node{ + {Name: "localAgentHost", Value: "foobar"}, + {Name: "localAgentPort", Value: "42"}, + {Name: "logLevel", Value: "foobar"}}}, + {Name: "jaeger", Children: []*parser.Node{ + {Name: "gen128Bit", Value: "true"}, + {Name: "localAgentHostPort", Value: "foobar"}, + {Name: "propagation", Value: "foobar"}, + {Name: "samplingParam", Value: "42"}, + {Name: "samplingServerURL", Value: "foobar"}, + {Name: "samplingType", Value: "foobar"}, + {Name: "traceContextHeaderName", Value: "foobar"}}}, + {Name: "serviceName", Value: "foobar"}, + {Name: "spanNameLimit", Value: "42"}, + {Name: "zipkin", Children: []*parser.Node{ + {Name: "debug", Value: "true"}, + {Name: "httpEndpoint", Value: "foobar"}, + {Name: "id128Bit", Value: "true"}, + {Name: "sameSpan", Value: "true"}, + {Name: "sampleRate", Value: "42"}}}}}, + }, } assert.Equal(t, expected, node) diff --git a/pkg/config/file/fixtures/sample.toml b/pkg/config/file/fixtures/sample.toml index 4cd6436ab..8db3b5093 100644 --- a/pkg/config/file/fixtures/sample.toml +++ b/pkg/config/file/fixtures/sample.toml @@ -1,543 +1,481 @@ -[Global] - Debug = true - CheckNewVersion = true - SendAnonymousUsage = true +[global] + checkNewVersion = true + sendAnonymousUsage = true -[ServersTransport] - InsecureSkipVerify = true - RootCAs = ["foobar", "foobar"] - MaxIdleConnsPerHost = 42 - [ServersTransport.ForwardingTimeouts] - DialTimeout = 42 - ResponseHeaderTimeout = 42 +[serversTransport] + insecureSkipVerify = true + rootCAs = ["foobar", "foobar"] + maxIdleConnsPerHost = 42 + [serversTransport.forwardingTimeouts] + dialTimeout = 42 + responseHeaderTimeout = 42 + idleConnTimeout = 42 -[EntryPoints] +[entryPoints] + [entryPoints.EntryPoint0] + address = "foobar" + [entryPoints.EntryPoint0.transport] + [entryPoints.EntryPoint0.transport.lifeCycle] + requestAcceptGraceTimeout = 42 + graceTimeOut = 42 + [entryPoints.EntryPoint0.transport.respondingTimeouts] + readTimeout = 42 + writeTimeout = 42 + idleTimeout = 42 + [entryPoints.EntryPoint0.proxyProtocol] + insecure = true + trustedIPs = ["foobar", "foobar"] + [entryPoints.EntryPoint0.forwardedHeaders] + insecure = true + trustedIPs = ["foobar", "foobar"] - [EntryPoints.EntryPoint0] - Address = "foobar" - [EntryPoints.EntryPoint0.Transport] - [EntryPoints.EntryPoint0.Transport.LifeCycle] - RequestAcceptGraceTimeout = 42 - GraceTimeOut = 42 - [EntryPoints.EntryPoint0.Transport.RespondingTimeouts] - ReadTimeout = 42 - WriteTimeout = 42 - IdleTimeout = 42 - [EntryPoints.EntryPoint0.ProxyProtocol] - Insecure = true - TrustedIPs = ["foobar", "foobar"] - [EntryPoints.EntryPoint0.ForwardedHeaders] - Insecure = true - TrustedIPs = ["foobar", "foobar"] +[providers] + providersThrottleDuration = 42 + [providers.docker] + constraints = "foobar" + watch = true + endpoint = "foobar" + defaultRule = "foobar" + exposedByDefault = true + useBindPortIP = true + swarmMode = true + network = "foobar" + swarmModeRefreshSeconds = 42 + [providers.docker.tls] + ca = "foobar" + caOptional = true + cert = "foobar" + key = "foobar" + insecureSkipVerify = true + [providers.file] + directory = "foobar" + watch = true + filename = "foobar" + debugLogGeneratedTemplate = true + traefikFile = "foobar" + [providers.marathon] + constraints = "foobar" + trace = true + watch = true + endpoint = "foobar" + defaultRule = "foobar" + exposedByDefault = true + dcosToken = "foobar" + dialerTimeout = 42 + responseHeaderTimeout = 42 + tlsHandshakeTimeout = 42 + keepAlive = 42 + forceTaskHostname = true + respectReadinessChecks = true + [providers.marathon.tls] + ca = "foobar" + caOptional = true + cert = "foobar" + key = "foobar" + insecureSkipVerify = true + [providers.marathon.basic] + httpBasicAuthUser = "foobar" + httpBasicPassword = "foobar" + [providers.kubernetes] + endpoint = "foobar" + token = "foobar" + certAuthFilePath = "foobar" + disablePassHostHeaders = true + namespaces = ["foobar", "foobar"] + labelSelector = "foobar" + ingressClass = "foobar" + [providers.kubernetes.ingressEndpoint] + ip = "foobar" + hostname = "foobar" + publishedService = "foobar" + [providers.kubernetesCRD] + endpoint = "foobar" + token = "foobar" + certAuthFilePath = "foobar" + disablePassHostHeaders = true + namespaces = ["foobar", "foobar"] + labelSelector = "foobar" + ingressClass = "foobar" + [providers.rest] + entryPoint = "foobar" + [providers.rancher] + constraints = "foobar" + watch = true + defaultRule = "foobar" + exposedByDefault = true + enableServiceHealthFilter = true + refreshSeconds = 42 + intervalPoll = true + prefix = "foobar" -[Providers] - ProvidersThrottleDuration = 42 +[api] + entryPoint = "foobar" + dashboard = true + middlewares = ["foobar", "foobar"] + [api.statistics] + recentErrors = 42 - [Providers.Docker] - Watch = true - Endpoint = "foobar" - DefaultRule = "foobar" - ExposedByDefault = true - UseBindPortIP = true - SwarmMode = true - Network = "foobar" - SwarmModeRefreshSeconds = 42 +[metrics] + [metrics.prometheus] + buckets = [42.0, 42.0] + entryPoint = "foobar" + middlewares = ["foobar", "foobar"] + [metrics.dataDog] + address = "foobar" + pushInterval = "10s" + [metrics.statsD] + address = "foobar" + pushInterval = "10s" + [metrics.influxDB] + address = "foobar" + protocol = "foobar" + pushInterval = "10s" + database = "foobar" + retentionPolicy = "foobar" + username = "foobar" + password = "foobar" - [[Providers.Docker.Constraints]] - Key = "foobar" - MustMatch = true - Value = "foobar" +[ping] + entryPoint = "foobar" + middlewares = ["foobar", "foobar"] - [[Providers.Docker.Constraints]] - Key = "foobar" - MustMatch = true - Value = "foobar" +[log] + level = "foobar" + filePath = "foobar" + format = "foobar" - [Providers.Docker.TLS] - CA = "foobar" - CAOptional = true - Cert = "foobar" - Key = "foobar" - InsecureSkipVerify = true - - [Providers.File] - Directory = "foobar" - Watch = true - Filename = "foobar" - DebugLogGeneratedTemplate = true - TraefikFile = "foobar" - - [Providers.Marathon] - Trace = true - Watch = true - Endpoint = "foobar" - DefaultRule = "foobar" - ExposedByDefault = true - DCOSToken = "foobar" - DialerTimeout = 42 - ResponseHeaderTimeout = 42 - TLSHandshakeTimeout = 42 - KeepAlive = 42 - ForceTaskHostname = true - RespectReadinessChecks = true - - [[Providers.Marathon.Constraints]] - Key = "foobar" - MustMatch = true - Value = "foobar" - - [[Providers.Marathon.Constraints]] - Key = "foobar" - MustMatch = true - Value = "foobar" - - [Providers.Marathon.TLS] - CA = "foobar" - CAOptional = true - Cert = "foobar" - Key = "foobar" - InsecureSkipVerify = true - [Providers.Marathon.Basic] - HTTPBasicAuthUser = "foobar" - HTTPBasicPassword = "foobar" - - [Providers.Kubernetes] - Endpoint = "foobar" - Token = "foobar" - CertAuthFilePath = "foobar" - DisablePassHostHeaders = true - Namespaces = ["foobar", "foobar"] - LabelSelector = "foobar" - IngressClass = "foobar" - [Providers.Kubernetes.IngressEndpoint] - IP = "foobar" - Hostname = "foobar" - PublishedService = "foobar" - - [Providers.KubernetesCRD] - Endpoint = "foobar" - Token = "foobar" - CertAuthFilePath = "foobar" - DisablePassHostHeaders = true - Namespaces = ["foobar", "foobar"] - LabelSelector = "foobar" - IngressClass = "foobar" - - [Providers.Rest] - EntryPoint = "foobar" - - [Providers.Rancher] - Watch = true - DefaultRule = "foobar" - ExposedByDefault = true - EnableServiceHealthFilter = true - RefreshSeconds = 42 - IntervalPoll = true - Prefix = "foobar" - - [[Providers.Rancher.Constraints]] - Key = "foobar" - MustMatch = true - Value = "foobar" - - [[Providers.Rancher.Constraints]] - Key = "foobar" - MustMatch = true - Value = "foobar" - -[API] - EntryPoint = "foobar" - Dashboard = true - Middlewares = ["foobar", "foobar"] - [API.Statistics] - RecentErrors = 42 - -[Metrics] - - [Metrics.Prometheus] - Buckets = [42.0, 42.0] - EntryPoint = "foobar" - Middlewares = ["foobar", "foobar"] - - [Metrics.Datadog] - Address = "foobar" - PushInterval = "10s" - - [Metrics.StatsD] - Address = "foobar" - PushInterval = "10s" - - [Metrics.InfluxDB] - Address = "foobar" - Protocol = "foobar" - PushInterval = "10s" - Database = "foobar" - RetentionPolicy = "foobar" - Username = "foobar" - Password = "foobar" - -[Ping] - EntryPoint = "foobar" - Middlewares = ["foobar", "foobar"] - -[Log] - Level = "foobar" - FilePath = "foobar" - Format = "foobar" - -[AccessLog] - FilePath = "foobar" - Format = "foobar" - BufferingSize = 42 - [AccessLog.Filters] - StatusCodes = ["foobar", "foobar"] - RetryAttempts = true - MinDuration = 42 - [AccessLog.Fields] - DefaultMode = "foobar" - [AccessLog.Fields.Names] +[accessLog] + filePath = "foobar" + format = "foobar" + bufferingSize = 42 + [accessLog.filters] + statusCodes = ["foobar", "foobar"] + retryAttempts = true + minDuration = 42 + [accessLog.fields] + defaultMode = "foobar" + [accessLog.fields.names] name0 = "foobar" name1 = "foobar" - [AccessLog.Fields.Headers] - DefaultMode = "foobar" - [AccessLog.Fields.Headers.Names] + [accessLog.fields.headers] + defaultMode = "foobar" + [accessLog.fields.headers.names] name0 = "foobar" name1 = "foobar" -[Tracing] - ServiceName = "foobar" - SpanNameLimit = 42 +[tracing] + serviceName = "foobar" + spanNameLimit = 42 + [tracing.jaeger] + samplingServerURL = "foobar" + samplingType = "foobar" + samplingParam = 42.0 + localAgentHostPort = "foobar" + gen128Bit = true + propagation = "foobar" + traceContextHeaderName = "foobar" + [tracing.zipkin] + httpEndpoint = "foobar" + sameSpan = true + id128Bit = true + debug = true + sampleRate = 42.0 + [tracing.dataDog] + localAgentHostPort = "foobar" + globalTag = "foobar" + debug = true + prioritySampling = true + traceIDHeaderName = "foobar" + parentIDHeaderName = "foobar" + samplingPriorityHeaderName = "foobar" + bagagePrefixHeaderName = "foobar" + [tracing.instana] + localAgentHost = "foobar" + localAgentPort = 42 + logLevel = "foobar" + [tracing.haystack] + localAgentHost = "foobar" + localAgentPort = 42 + globalTag = "foobar" + traceIDHeaderName = "foobar" + parentIDHeaderName = "foobar" + spanIDHeaderName = "foobar" - [Tracing.Jaeger] - SamplingServerURL = "foobar" - SamplingType = "foobar" - SamplingParam = 42.0 - LocalAgentHostPort = "foobar" - Gen128Bit = true - Propagation = "foobar" - TraceContextHeaderName = "foobar" +[hostResolver] + cnameFlattening = true + resolvConfig = "foobar" + resolvDepth = 42 - [Tracing.Zipkin] - HTTPEndpoint = "foobar" - SameSpan = true - ID128Bit = true - Debug = true - SampleRate = 42.0 +[acme] + email = "foobar" + acmeLogging = true + caServer = "foobar" + storage = "foobar" + entryPoint = "foobar" + keyType = "foobar" + onHostRule = true + [acme.dnsChallenge] + provider = "foobar" + delayBeforeCheck = 42 + resolvers = ["foobar", "foobar"] + disablePropagationCheck = true + [acme.httpChallenge] + entryPoint = "foobar" + [acme.tlsChallenge] - [Tracing.DataDog] - LocalAgentHostPort = "foobar" - GlobalTag = "foobar" - Debug = true - PrioritySampling = true - TraceIDHeaderName = "foobar" - ParentIDHeaderName = "foobar" - SamplingPriorityHeaderName = "foobar" - BagagePrefixHeaderName = "foobar" + [[acme.domains]] + main = "foobar" + sans = ["foobar", "foobar"] - [Tracing.Instana] - LocalAgentHost = "foobar" - LocalAgentPort = 42 - LogLevel = "foobar" + [[acme.domains]] + main = "foobar" + sans = ["foobar", "foobar"] - [Tracing.Haystack] - GlobalTag = "foobar" - LocalAgentHost = "foobar" - LocalAgentPort = 42 - ParentIDHeaderName = "foobar" - SpanIDHeaderName = "foobar" - TraceIDHeaderName = "foobar" +## Dynamic configuration -[HostResolver] - CnameFlattening = true - ResolvConfig = "foobar" - ResolvDepth = 42 - -[ACME] - Email = "foobar" - ACMELogging = true - CAServer = "foobar" - Storage = "foobar" - EntryPoint = "foobar" - KeyType = "foobar" - OnHostRule = true - - [ACME.DNSChallenge] - Provider = "foobar" - DelayBeforeCheck = 42 - Resolvers = ["foobar", "foobar"] - DisablePropagationCheck = true - - [ACME.HTTPChallenge] - EntryPoint = "foobar" - - [ACME.TLSChallenge] - - [[ACME.Domains]] - Main = "foobar" - SANs = ["foobar", "foobar"] - - [[ACME.Domains]] - Main = "foobar" - SANs = ["foobar", "foobar"] - -#### Dynamic configuration - -[HTTP] - - [HTTP.Routers] - - [HTTP.Routers.Router0] - EntryPoints = ["foobar", "foobar"] - Middlewares = ["foobar", "foobar"] - Service = "foobar" - Rule = "foobar" +[http] + [http.routers] + [http.routers.Router0] + entryPoints = ["foobar", "foobar"] + middlewares = ["foobar", "foobar"] + service = "foobar" + rule = "foobar" priority = 42 - [HTTP.Routers.Router0.tls] - - [HTTP.Middlewares] - - [HTTP.Middlewares.Middleware0.AddPrefix] - Prefix = "foobar" - - [HTTP.Middlewares.Middleware1.StripPrefix] - Prefixes = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware2.StripPrefixRegex] - Regex = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware3.ReplacePath] - Path = "foobar" - - [HTTP.Middlewares.Middleware4.ReplacePathRegex] - Regex = "foobar" - Replacement = "foobar" - - [HTTP.Middlewares.Middleware5.Chain] - Middlewares = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware6.IPWhiteList] - SourceRange = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware7.IPWhiteList.IPStrategy] - Depth = 42 - ExcludedIPs = ["foobar", "foobar"] - - [HTTP.Middlewares.Middleware8.Headers] - AccessControlAllowCredentials = true - AccessControlAllowHeaders = ["foobar", "foobar"] - AccessControlAllowMethods = ["foobar", "foobar"] - AccessControlAllowOrigin = "foobar" - AccessControlExposeHeaders = ["foobar", "foobar"] - AccessControlMaxAge = 42 - AddVaryHeader = true - AllowedHosts = ["foobar", "foobar"] - HostsProxyHeaders = ["foobar", "foobar"] - SSLRedirect = true - SSLTemporaryRedirect = true - SSLHost = "foobar" - SSLForceHost = true - STSSeconds = 42 - STSIncludeSubdomains = true - STSPreload = true - ForceSTSHeader = true - FrameDeny = true - CustomFrameOptionsValue = "foobar" - ContentTypeNosniff = true - BrowserXSSFilter = true - CustomBrowserXSSValue = "foobar" - ContentSecurityPolicy = "foobar" - PublicKey = "foobar" - ReferrerPolicy = "foobar" - IsDevelopment = true - [HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders] + [http.routers.Router0.tls] + [http.middlewares] + [http.middlewares.Middleware0] + [http.middlewares.Middleware0.addPrefix] + prefix = "foobar" + [http.middlewares.Middleware1] + [http.middlewares.Middleware1.stripPrefix] + prefixes = ["foobar", "foobar"] + [http.middlewares.Middleware10] + [http.middlewares.Middleware10.rateLimit] + extractorFunc = "foobar" + [http.middlewares.Middleware10.rateLimit.rateSet] + [http.middlewares.Middleware10.rateLimit.rateSet.Rate0] + period = 42000000000 + average = 42 + burst = 42 + [http.middlewares.Middleware10.rateLimit.rateSet.Rate1] + period = 42000000000 + average = 42 + burst = 42 + [http.middlewares.Middleware11] + [http.middlewares.Middleware11.redirectRegex] + regex = "foobar" + replacement = "foobar" + permanent = true + [http.middlewares.Middleware12] + [http.middlewares.Middleware12.redirectScheme] + scheme = "foobar" + port = "foobar" + permanent = true + [http.middlewares.Middleware13] + [http.middlewares.Middleware13.basicAuth] + users = ["foobar", "foobar"] + usersFile = "foobar" + realm = "foobar" + removeHeader = true + headerField = "foobar" + [http.middlewares.Middleware14] + [http.middlewares.Middleware14.digestAuth] + users = ["foobar", "foobar"] + usersFile = "foobar" + removeHeader = true + realm = "foobar" + headerField = "foobar" + [http.middlewares.Middleware15] + [http.middlewares.Middleware15.forwardAuth] + address = "foobar" + trustForwardHeader = true + authResponseHeaders = ["foobar", "foobar"] + [http.middlewares.Middleware15.forwardAuth.tls] + ca = "foobar" + caOptional = true + cert = "foobar" + key = "foobar" + insecureSkipVerify = true + [http.middlewares.Middleware16] + [http.middlewares.Middleware16.maxConn] + amount = 42 + extractorFunc = "foobar" + [http.middlewares.Middleware17] + [http.middlewares.Middleware17.buffering] + maxRequestBodyBytes = 42 + memRequestBodyBytes = 42 + maxResponseBodyBytes = 42 + memResponseBodyBytes = 42 + retryExpression = "foobar" + [http.middlewares.Middleware18] + [http.middlewares.Middleware18.circuitBreaker] + expression = "foobar" + [http.middlewares.Middleware19] + [http.middlewares.Middleware19.compress] + [http.middlewares.Middleware2] + [http.middlewares.Middleware2.stripPrefixRegex] + regex = ["foobar", "foobar"] + [http.middlewares.Middleware20] + [http.middlewares.Middleware20.passTLSClientCert] + pem = true + [http.middlewares.Middleware20.passTLSClientCert.info] + notAfter = true + notBefore = true + sans = true + [http.middlewares.Middleware20.passTLSClientCert.info.subject] + country = true + province = true + locality = true + organization = true + commonName = true + serialNumber = true + domainComponent = true + [http.middlewares.Middleware20.passTLSClientCert.info.issuer] + country = true + province = true + locality = true + organization = true + commonName = true + serialNumber = true + domainComponent = true + [http.middlewares.Middleware21] + [http.middlewares.Middleware21.retry] + regex = 0 + [http.middlewares.Middleware3] + [http.middlewares.Middleware3.replacePath] + path = "foobar" + [http.middlewares.Middleware4] + [http.middlewares.Middleware4.replacePathRegex] + regex = "foobar" + replacement = "foobar" + [http.middlewares.Middleware5] + [http.middlewares.Middleware5.chain] + middlewares = ["foobar", "foobar"] + [http.middlewares.Middleware6] + [http.middlewares.Middleware6.ipWhiteList] + sourceRange = ["foobar", "foobar"] + [http.middlewares.Middleware7] + [http.middlewares.Middleware7.ipWhiteList] + [http.middlewares.Middleware7.ipWhiteList.ipStrategy] + depth = 42 + excludedIPs = ["foobar", "foobar"] + [http.middlewares.Middleware8] + [http.middlewares.Middleware8.headers] + accessControlAllowCredentials = true + accessControlAllowHeaders = ["foobar", "foobar"] + accessControlAllowMethods = ["foobar", "foobar"] + accessControlAllowOrigin = "foobar" + accessControlExposeHeaders = ["foobar", "foobar"] + accessControlMaxAge = 42 + addVaryHeader = true + allowedHosts = ["foobar", "foobar"] + hostsProxyHeaders = ["foobar", "foobar"] + sslRedirect = true + sslTemporaryRedirect = true + sslHost = "foobar" + sslForceHost = true + stsSeconds = 42 + stsIncludeSubdomains = true + stsPreload = true + forceSTSHeader = true + frameDeny = true + customFrameOptionsValue = "foobar" + contentTypeNosniff = true + browserXssFilter = true + customBrowserXSSValue = "foobar" + contentSecurityPolicy = "foobar" + publicKey = "foobar" + referrerPolicy = "foobar" + isDevelopment = true + [http.middlewares.Middleware8.headers.customRequestHeaders] name0 = "foobar" name1 = "foobar" - [HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders] + [http.middlewares.Middleware8.headers.customResponseHeaders] name0 = "foobar" name1 = "foobar" - [HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders] + [http.middlewares.Middleware8.headers.sslProxyHeaders] name0 = "foobar" name1 = "foobar" + [http.middlewares.Middleware9] + [http.middlewares.Middleware9.errors] + status = ["foobar", "foobar"] + service = "foobar" + query = "foobar" + [http.services] + [http.services.Service0] + [http.services.Service0.loadBalancer] + passHostHeader = true + [http.services.Service0.loadBalancer.stickiness] + cookieName = "foobar" - [HTTP.Middlewares.Middleware9.Errors] - Status = ["foobar", "foobar"] - Service = "foobar" - Query = "foobar" + [[http.services.Service0.loadBalancer.servers]] + url = "foobar" - [HTTP.Middlewares.Middleware10.RateLimit] - ExtractorFunc = "foobar" - [HTTP.Middlewares.Middleware10.RateLimit.RateSet] - [HTTP.Middlewares.Middleware10.RateLimit.RateSet.Rate0] - Period = 42 - Average = 42 - Burst = 42 - [HTTP.Middlewares.Middleware10.RateLimit.RateSet.Rate1] - Period = 42 - Average = 42 - Burst = 42 - - [HTTP.Middlewares.Middleware11.RedirectRegex] - Regex = "foobar" - Replacement = "foobar" - Permanent = true - - [HTTP.Middlewares.Middleware12.RedirectScheme] - Scheme = "foobar" - Port = "foobar" - Permanent = true - - [HTTP.Middlewares.Middleware13.BasicAuth] - Users = ["foobar", "foobar"] - UsersFile = "foobar" - Realm = "foobar" - RemoveHeader = true - HeaderField = "foobar" - - [HTTP.Middlewares.Middleware14.DigestAuth] - Users = ["foobar", "foobar"] - UsersFile = "foobar" - RemoveHeader = true - Realm = "foobar" - HeaderField = "foobar" - - [HTTP.Middlewares.Middleware15.ForwardAuth] - Address = "foobar" - TrustForwardHeader = true - AuthResponseHeaders = ["foobar", "foobar"] - [HTTP.Middlewares.Middleware15.ForwardAuth.TLS] - CA = "foobar" - CAOptional = true - Cert = "foobar" - Key = "foobar" - InsecureSkipVerify = true - - [HTTP.Middlewares.Middleware16.MaxConn] - Amount = 42 - ExtractorFunc = "foobar" - - [HTTP.Middlewares.Middleware17.Buffering] - MaxRequestBodyBytes = 42 - MemRequestBodyBytes = 42 - MaxResponseBodyBytes = 42 - MemResponseBodyBytes = 42 - RetryExpression = "foobar" - - [HTTP.Middlewares.Middleware18.CircuitBreaker] - Expression = "foobar" - - [HTTP.Middlewares.Middleware19.Compress] - - [HTTP.Middlewares.Middleware20.PassTLSClientCert] - PEM = true - [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info] - NotAfter = true - NotBefore = true - Sans = true - [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info.Subject] - Country = true - Province = true - Locality = true - Organization = true - CommonName = true - SerialNumber = true - DomainComponent = true - [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info.Issuer] - Country = true - Province = true - Locality = true - Organization = true - CommonName = true - SerialNumber = true - DomainComponent = true - - [HTTP.Middlewares.Middleware21.Retry] - Attempts = 42 - - [HTTP.Services] - [HTTP.Services.Service0] - [HTTP.Services.Service0.LoadBalancer] - Method = "foobar" - PassHostHeader = true - - [[HTTP.Services.Service0.LoadBalancer.Servers]] - URL = "foobar" - - [HTTP.Services.Service0.LoadBalancer.Stickiness] - CookieName = "foobar" - - [[HTTP.Services.Service0.LoadBalancer.Servers]] - URL = "foobar" - - [HTTP.Services.Service0.LoadBalancer.HealthCheck] - Scheme = "foobar" - Path = "foobar" - Port = 42 - Interval = "foobar" - Timeout = "foobar" - Hostname = "foobar" - [HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers] + [[http.services.Service0.loadBalancer.servers]] + url = "foobar" + [http.services.Service0.loadBalancer.healthCheck] + scheme = "foobar" + path = "foobar" + port = 42 + interval = "foobar" + timeout = "foobar" + hostname = "foobar" + [http.services.Service0.loadBalancer.healthCheck.headers] name0 = "foobar" name1 = "foobar" - [HTTP.Services.Service0.LoadBalancer.ResponseForwarding] - FlushInterval = "foobar" + [http.services.Service0.loadBalancer.responseForwarding] + flushInterval = "foobar" -[TCP] - - [TCP.Routers] - - [TCP.Routers.TCPRouter0] - EntryPoints = ["foobar", "foobar"] - Service = "foobar" - Rule = "foobar" - [TCP.Routers.TCPRouter0.tls] +[tcp] + [tcp.routers] + [tcp.routers.TCPRouter0] + entryPoints = ["foobar", "foobar"] + service = "foobar" + rule = "foobar" + [tcp.routers.TCPRouter0.tls] passthrough = true + [tcp.services] + [tcp.services.TCPService0] + [tcp.services.TCPService0.loadBalancer] - [TCP.Services] + [[tcp.services.TCPService0.loadBalancer.servers]] + address = "foobar" - [TCP.Services.TCPService0] - [TCP.Services.TCPService0.LoadBalancer] - Method = "foobar" + [[tcp.services.TCPService0.loadBalancer.servers]] + address = "foobar" - [[TCP.Services.TCPService0.LoadBalancer.Servers]] - Address = "foobar" +[tls] - [[TCP.Services.TCPService0.LoadBalancer.Servers]] - Address = "foobar" + [[tls.Certificates]] + certFile = "foobar" + keyFile = "foobar" + stores = ["foobar", "foobar"] -[[TLS.Certificates]] - Stores = ["foobar", "foobar"] - CertFile = "foobar" - KeyFile = "foobar" - -[[TLS.Certificates]] - Stores = ["foobar", "foobar"] - CertFile = "foobar" - KeyFile = "foobar" - -[TLS.Options] - - [TLS.Options.TLS0] - MinVersion = "foobar" - CipherSuites = ["foobar", "foobar"] - SniStrict = true - [TLS.Options.TLS0.ClientCA] - Files = ["foobar", "foobar"] - Optional = true - [TLS.Options.TLS1] - MinVersion = "foobar" - CipherSuites = ["foobar", "foobar"] - SniStrict = true - [TLS.Options.TLS1.ClientCA] - Files = ["foobar", "foobar"] - Optional = true - -[TLS.Stores] - - [TLS.Stores.Store0] - [TLS.Stores.Store0.DefaultCertificate] - CertFile = "foobar" - KeyFile = "foobar" - [TLS.Stores.Store1] - [TLS.Stores.Store1.DefaultCertificate] - CertFile = "foobar" - KeyFile = "foobar" + [[tls.Certificates]] + certFile = "foobar" + keyFile = "foobar" + stores = ["foobar", "foobar"] + [tls.options] + [tls.options.TLS0] + minVersion = "foobar" + cipherSuites = ["foobar", "foobar"] + sniStrict = true + [tls.options.TLS0.clientCA] + files = ["foobar", "foobar"] + optional = true + [tls.options.TLS1] + minVersion = "foobar" + cipherSuites = ["foobar", "foobar"] + sniStrict = true + [tls.options.TLS1.clientCA] + files = ["foobar", "foobar"] + optional = true + [tls.stores] + [tls.stores.Store0] + [tls.stores.Store0.defaultCertificate] + certFile = "foobar" + keyFile = "foobar" + [tls.stores.Store1] + [tls.stores.Store1.defaultCertificate] + certFile = "foobar" + keyFile = "foobar" \ No newline at end of file diff --git a/pkg/config/file/fixtures/sample.yml b/pkg/config/file/fixtures/sample.yml index 23724c162..40c269d72 100644 --- a/pkg/config/file/fixtures/sample.yml +++ b/pkg/config/file/fixtures/sample.yml @@ -1,262 +1,244 @@ -Global: - Debug: true - CheckNewVersion: true - SendAnonymousUsage: true -ServersTransport: - InsecureSkipVerify: true - RootCAs: +global: + checkNewVersion: true + sendAnonymousUsage: true +serversTransport: + insecureSkipVerify: true + rootCAs: - foobar - foobar - MaxIdleConnsPerHost: 42 - ForwardingTimeouts: - DialTimeout: 42 - ResponseHeaderTimeout: 42 -EntryPoints: + maxIdleConnsPerHost: 42 + forwardingTimeouts: + dialTimeout: 42 + responseHeaderTimeout: 42 + idleConnTimeout: 42 +entryPoints: EntryPoint0: - Address: foobar - Transport: - LifeCycle: - RequestAcceptGraceTimeout: 42 - GraceTimeOut: 42 - RespondingTimeouts: - ReadTimeout: 42 - WriteTimeout: 42 - IdleTimeout: 42 - ProxyProtocol: - Insecure: true - TrustedIPs: + address: foobar + transport: + lifeCycle: + requestAcceptGraceTimeout: 42 + graceTimeOut: 42 + respondingTimeouts: + readTimeout: 42 + writeTimeout: 42 + idleTimeout: 42 + proxyProtocol: + insecure: true + trustedIPs: - foobar - foobar - ForwardedHeaders: - Insecure: true - TrustedIPs: + forwardedHeaders: + insecure: true + trustedIPs: - foobar - foobar -Providers: - ProvidersThrottleDuration: 42 - Docker: - Watch: true - Endpoint: foobar - DefaultRule: foobar - ExposedByDefault: true - UseBindPortIP: true - SwarmMode: true - Network: foobar - SwarmModeRefreshSeconds: 42 - Constraints: - - Key: foobar - MustMatch: true - Value: foobar - - Key: foobar - MustMatch: true - Value: foobar - TLS: - CA: foobar - CAOptional: true - Cert: foobar - Key: foobar - InsecureSkipVerify: true - File: - Directory: foobar - Watch: true - Filename: foobar - DebugLogGeneratedTemplate: true - TraefikFile: foobar - Marathon: - Trace: true - Watch: true - Endpoint: foobar - DefaultRule: foobar - ExposedByDefault: true - DCOSToken: foobar - DialerTimeout: 42 - ResponseHeaderTimeout: 42 - TLSHandshakeTimeout: 42 - KeepAlive: 42 - ForceTaskHostname: true - RespectReadinessChecks: true - Constraints: - - Key: foobar - MustMatch: true - Value: foobar - - Key: foobar - MustMatch: true - Value: foobar - TLS: - CA: foobar - CAOptional: true - Cert: foobar - Key: foobar - InsecureSkipVerify: true - Basic: - HTTPBasicAuthUser: foobar - HTTPBasicPassword: foobar - Kubernetes: - Endpoint: foobar - Token: foobar - CertAuthFilePath: foobar - DisablePassHostHeaders: true - Namespaces: +providers: + providersThrottleDuration: 42 + docker: + constraints: foobar + watch: true + endpoint: foobar + defaultRule: foobar + tls: + ca: foobar + caOptional: true + cert: foobar + key: foobar + insecureSkipVerify: true + exposedByDefault: true + useBindPortIP: true + swarmMode: true + network: foobar + swarmModeRefreshSeconds: 42 + file: + directory: foobar + watch: true + filename: foobar + debugLogGeneratedTemplate: true + traefikFile: foobar + marathon: + constraints: foobar + trace: true + watch: true + endpoint: foobar + defaultRule: foobar + exposedByDefault: true + dcosToken: foobar + tls: + ca: foobar + caOptional: true + cert: foobar + key: foobar + insecureSkipVerify: true + dialerTimeout: 42 + responseHeaderTimeout: 42 + tlsHandshakeTimeout: 42 + keepAlive: 42 + forceTaskHostname: true + basic: + httpBasicAuthUser: foobar + httpBasicPassword: foobar + respectReadinessChecks: true + kubernetes: + endpoint: foobar + token: foobar + certAuthFilePath: foobar + disablePassHostHeaders: true + namespaces: - foobar - foobar - LabelSelector: foobar - IngressClass: foobar - IngressEndpoint: - IP: foobar - Hostname: foobar - PublishedService: foobar - KubernetesCRD: - Endpoint: foobar - Token: foobar - CertAuthFilePath: foobar - DisablePassHostHeaders: true - Namespaces: + labelSelector: foobar + ingressClass: foobar + ingressEndpoint: + ip: foobar + hostname: foobar + publishedService: foobar + kubernetesCRD: + endpoint: foobar + token: foobar + certAuthFilePath: foobar + disablePassHostHeaders: true + namespaces: - foobar - foobar - LabelSelector: foobar - IngressClass: foobar - Rest: - EntryPoint: foobar - Rancher: - Watch: true - DefaultRule: foobar - ExposedByDefault: true - EnableServiceHealthFilter: true - RefreshSeconds: 42 - IntervalPoll: true - Prefix: foobar - Constraints: - - Key: foobar - MustMatch: true - Value: foobar - - Key: foobar - MustMatch: true - Value: foobar -API: - EntryPoint: foobar - Dashboard: true - Middlewares: + labelSelector: foobar + ingressClass: foobar + rest: + entryPoint: foobar + rancher: + constraints: foobar + watch: true + defaultRule: foobar + exposedByDefault: true + enableServiceHealthFilter: true + refreshSeconds: 42 + intervalPoll: true + prefix: foobar +api: + entryPoint: foobar + dashboard: true + statistics: + recentErrors: 42 + middlewares: - foobar - foobar - Statistics: - RecentErrors: 42 -Metrics: - Prometheus: - Buckets: +metrics: + prometheus: + buckets: - 42 - 42 - EntryPoint: foobar - Middlewares: + entryPoint: foobar + middlewares: - foobar - foobar - Datadog: - Address: foobar - PushInterval: 10s - StatsD: - Address: foobar - PushInterval: 10s - InfluxDB: - Address: foobar - Protocol: foobar - PushInterval: 10s - Database: foobar - RetentionPolicy: foobar - Username: foobar - Password: foobar -Ping: - EntryPoint: foobar - Middlewares: + dataDog: + address: foobar + pushInterval: 10s + statsD: + address: foobar + pushInterval: 10s + influxDB: + address: foobar + protocol: foobar + pushInterval: 10s + database: foobar + retentionPolicy: foobar + username: foobar + password: foobar +ping: + entryPoint: foobar + middlewares: - foobar - foobar -Log: - Level: foobar - FilePath: foobar - Format: foobar -AccessLog: - FilePath: foobar - Format: foobar - BufferingSize: 42 - Filters: - StatusCodes: +log: + level: foobar + filePath: foobar + format: foobar +accessLog: + filePath: foobar + format: foobar + filters: + statusCodes: - foobar - foobar - RetryAttempts: true - MinDuration: 42 - Fields: - DefaultMode: foobar - Names: + retryAttempts: true + minDuration: 42 + fields: + defaultMode: foobar + names: name0: foobar name1: foobar - Headers: - DefaultMode: foobar - Names: + headers: + defaultMode: foobar + names: name0: foobar name1: foobar -Tracing: - ServiceName: foobar - SpanNameLimit: 42 - Jaeger: - SamplingServerURL: foobar - SamplingType: foobar - SamplingParam: 42 - LocalAgentHostPort: foobar - Gen128Bit: true - Propagation: foobar - TraceContextHeaderName: foobar - Zipkin: - HTTPEndpoint: foobar - SameSpan: true - ID128Bit: true - Debug: true - SampleRate: 42 - DataDog: - LocalAgentHostPort: foobar - GlobalTag: foobar - Debug: true - PrioritySampling: true - TraceIDHeaderName: foobar - ParentIDHeaderName: foobar - SamplingPriorityHeaderName: foobar - BagagePrefixHeaderName: foobar - Instana: - LocalAgentHost: foobar - LocalAgentPort: 42 - LogLevel: foobar - Haystack: - GlobalTag: foobar - LocalAgentHost: foobar - LocalAgentPort: 42 - ParentIDHeaderName: foobar - TraceIDHeaderName: foobar - SpanIDHeaderName: foobar -HostResolver: - CnameFlattening: true - ResolvConfig: foobar - ResolvDepth: 42 -ACME: - Email: foobar - ACMELogging: true - CAServer: foobar - Storage: foobar - EntryPoint: foobar - KeyType: foobar - OnHostRule: true - DNSChallenge: - Provider: foobar - DelayBeforeCheck: 42 - Resolvers: + bufferingSize: 42 +tracing: + serviceName: foobar + spanNameLimit: 42 + jaeger: + samplingServerURL: foobar + samplingType: foobar + samplingParam: 42 + localAgentHostPort: foobar + gen128Bit: true + propagation: foobar + traceContextHeaderName: foobar + zipkin: + httpEndpoint: foobar + sameSpan: true + id128Bit: true + debug: true + sampleRate: 42 + dataDog: + localAgentHostPort: foobar + globalTag: foobar + debug: true + prioritySampling: true + traceIDHeaderName: foobar + parentIDHeaderName: foobar + samplingPriorityHeaderName: foobar + bagagePrefixHeaderName: foobar + instana: + localAgentHost: foobar + localAgentPort: 42 + logLevel: foobar + haystack: + localAgentHost: foobar + localAgentPort: 42 + globalTag: foobar + traceIDHeaderName: foobar + parentIDHeaderName: foobar + spanIDHeaderName: foobar +hostResolver: + cnameFlattening: true + resolvConfig: foobar + resolvDepth: 42 +acme: + email: foobar + acmeLogging: true + caServer: foobar + storage: foobar + entryPoint: foobar + keyType: foobar + onHostRule: true + dnsChallenge: + provider: foobar + delayBeforeCheck: 42 + resolvers: - foobar - foobar - DisablePropagationCheck: true - HTTPChallenge: - EntryPoint: foobar - TLSChallenge: {} - Domains: - - Main: foobar - SANs: + disablePropagationCheck: true + httpChallenge: + entryPoint: foobar + tlsChallenge: {} + domains: + - main: foobar + sans: - foobar - foobar - - Main: foobar - SANs: + - main: foobar + sans: - foobar - foobar diff --git a/pkg/config/middlewares.go b/pkg/config/middlewares.go index 05c36513a..8b8ee3599 100644 --- a/pkg/config/middlewares.go +++ b/pkg/config/middlewares.go @@ -1,6 +1,12 @@ package config import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" + "os" + "github.com/containous/traefik/pkg/ip" "github.com/containous/traefik/pkg/types" ) @@ -9,79 +15,79 @@ import ( // Middleware holds the Middleware configuration. type Middleware struct { - AddPrefix *AddPrefix `json:"addPrefix,omitempty" yaml:"addPrefix,omitempty"` - StripPrefix *StripPrefix `json:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty"` - StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty"` - ReplacePath *ReplacePath `json:"replacePath,omitempty" yaml:"replacePath,omitempty"` - ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty"` - Chain *Chain `json:"chain,omitempty" yaml:"chain,omitempty"` - IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty"` - Headers *Headers `json:"headers,omitempty" yaml:"headers,omitempty"` - Errors *ErrorPage `json:"errors,omitempty" yaml:"errors,omitempty"` - RateLimit *RateLimit `json:"rateLimit,omitempty" yaml:"rateLimit,omitempty"` - RedirectRegex *RedirectRegex `json:"redirectRegex,omitempty" yaml:"redirectRegex,omitempty"` - RedirectScheme *RedirectScheme `json:"redirectScheme,omitempty" yaml:"redirectScheme,omitempty"` - BasicAuth *BasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth,omitempty"` - DigestAuth *DigestAuth `json:"digestAuth,omitempty" yaml:"digestAuth,omitempty"` - ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty" yaml:"forwardAuth,omitempty"` - MaxConn *MaxConn `json:"maxConn,omitempty" yaml:"maxConn,omitempty"` - Buffering *Buffering `json:"buffering,omitempty" yaml:"buffering,omitempty"` - CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty" yaml:"circuitBreaker,omitempty"` - Compress *Compress `json:"compress,omitempty" label:"allowEmpty" yaml:"compress,omitempty" label:"allowEmpty"` - PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty"` - Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"` + AddPrefix *AddPrefix `json:"addPrefix,omitempty" toml:"addPrefix,omitempty" yaml:"addPrefix,omitempty"` + StripPrefix *StripPrefix `json:"stripPrefix,omitempty" toml:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty"` + StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty" toml:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty"` + ReplacePath *ReplacePath `json:"replacePath,omitempty" toml:"replacePath,omitempty" yaml:"replacePath,omitempty"` + ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" toml:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty"` + Chain *Chain `json:"chain,omitempty" toml:"chain,omitempty" yaml:"chain,omitempty"` + IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty"` + Headers *Headers `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty"` + Errors *ErrorPage `json:"errors,omitempty" toml:"errors,omitempty" yaml:"errors,omitempty"` + RateLimit *RateLimit `json:"rateLimit,omitempty" toml:"rateLimit,omitempty" yaml:"rateLimit,omitempty"` + RedirectRegex *RedirectRegex `json:"redirectRegex,omitempty" toml:"redirectRegex,omitempty" yaml:"redirectRegex,omitempty"` + RedirectScheme *RedirectScheme `json:"redirectScheme,omitempty" toml:"redirectScheme,omitempty" yaml:"redirectScheme,omitempty"` + BasicAuth *BasicAuth `json:"basicAuth,omitempty" toml:"basicAuth,omitempty" yaml:"basicAuth,omitempty"` + DigestAuth *DigestAuth `json:"digestAuth,omitempty" toml:"digestAuth,omitempty" yaml:"digestAuth,omitempty"` + ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty" toml:"forwardAuth,omitempty" yaml:"forwardAuth,omitempty"` + MaxConn *MaxConn `json:"maxConn,omitempty" toml:"maxConn,omitempty" yaml:"maxConn,omitempty"` + Buffering *Buffering `json:"buffering,omitempty" toml:"buffering,omitempty" yaml:"buffering,omitempty"` + CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty" toml:"circuitBreaker,omitempty" yaml:"circuitBreaker,omitempty"` + Compress *Compress `json:"compress,omitempty" toml:"compress,omitempty" yaml:"compress,omitempty" label:"allowEmpty"` + PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty" toml:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty"` + Retry *Retry `json:"retry,omitempty" toml:"retry,omitempty" yaml:"retry,omitempty"` } // +k8s:deepcopy-gen=true // AddPrefix holds the AddPrefix configuration. type AddPrefix struct { - Prefix string `json:"prefix,omitempty"` + Prefix string `json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty"` } // +k8s:deepcopy-gen=true // Auth holds the authentication configuration (BASIC, DIGEST, users). type Auth struct { - Basic *BasicAuth `json:"basic,omitempty" export:"true"` - Digest *DigestAuth `json:"digest,omitempty" export:"true"` - Forward *ForwardAuth `json:"forward,omitempty" export:"true"` + Basic *BasicAuth `json:"basic,omitempty" toml:"basic,omitempty" yaml:"basic,omitempty" export:"true"` + Digest *DigestAuth `json:"digest,omitempty" toml:"digest,omitempty" yaml:"digest,omitempty" export:"true"` + Forward *ForwardAuth `json:"forward,omitempty" toml:"forward,omitempty" yaml:"forward,omitempty" export:"true"` } // +k8s:deepcopy-gen=true // BasicAuth holds the HTTP basic authentication configuration. type BasicAuth struct { - Users Users `json:"users,omitempty"` - UsersFile string `json:"usersFile,omitempty"` - Realm string `json:"realm,omitempty"` - RemoveHeader bool `json:"removeHeader,omitempty"` - HeaderField string `json:"headerField,omitempty" export:"true"` + Users Users `json:"users,omitempty" toml:"users,omitempty" yaml:"users,omitempty"` + UsersFile string `json:"usersFile,omitempty" toml:"usersFile,omitempty" yaml:"usersFile,omitempty"` + Realm string `json:"realm,omitempty" toml:"realm,omitempty" yaml:"realm,omitempty"` + RemoveHeader bool `json:"removeHeader,omitempty" toml:"removeHeader,omitempty" yaml:"removeHeader,omitempty"` + HeaderField string `json:"headerField,omitempty" toml:"headerField,omitempty" yaml:"headerField,omitempty" export:"true"` } // +k8s:deepcopy-gen=true // Buffering holds the request/response buffering configuration. type Buffering struct { - MaxRequestBodyBytes int64 `json:"maxRequestBodyBytes,omitempty"` - MemRequestBodyBytes int64 `json:"memRequestBodyBytes,omitempty"` - MaxResponseBodyBytes int64 `json:"maxResponseBodyBytes,omitempty"` - MemResponseBodyBytes int64 `json:"memResponseBodyBytes,omitempty"` - RetryExpression string `json:"retryExpression,omitempty"` + MaxRequestBodyBytes int64 `json:"maxRequestBodyBytes,omitempty" toml:"maxRequestBodyBytes,omitempty" yaml:"maxRequestBodyBytes,omitempty"` + MemRequestBodyBytes int64 `json:"memRequestBodyBytes,omitempty" toml:"memRequestBodyBytes,omitempty" yaml:"memRequestBodyBytes,omitempty"` + MaxResponseBodyBytes int64 `json:"maxResponseBodyBytes,omitempty" toml:"maxResponseBodyBytes,omitempty" yaml:"maxResponseBodyBytes,omitempty"` + MemResponseBodyBytes int64 `json:"memResponseBodyBytes,omitempty" toml:"memResponseBodyBytes,omitempty" yaml:"memResponseBodyBytes,omitempty"` + RetryExpression string `json:"retryExpression,omitempty" toml:"retryExpression,omitempty" yaml:"retryExpression,omitempty"` } // +k8s:deepcopy-gen=true // Chain holds a chain of middlewares type Chain struct { - Middlewares []string `json:"middlewares"` + Middlewares []string `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty"` } // +k8s:deepcopy-gen=true // CircuitBreaker holds the circuit breaker configuration. type CircuitBreaker struct { - Expression string `json:"expression,omitempty"` + Expression string `json:"expression,omitempty" toml:"expression,omitempty" yaml:"expression,omitempty"` } // +k8s:deepcopy-gen=true @@ -93,74 +99,74 @@ type Compress struct{} // DigestAuth holds the Digest HTTP authentication configuration. type DigestAuth struct { - Users Users `json:"users,omitempty"` - UsersFile string `json:"usersFile,omitempty"` - RemoveHeader bool `json:"removeHeader,omitempty"` - Realm string `json:"realm,omitempty" mapstructure:","` - HeaderField string `json:"headerField,omitempty" export:"true"` + Users Users `json:"users,omitempty" toml:"users,omitempty" yaml:"users,omitempty"` + UsersFile string `json:"usersFile,omitempty" toml:"usersFile,omitempty" yaml:"usersFile,omitempty"` + RemoveHeader bool `json:"removeHeader,omitempty" toml:"removeHeader,omitempty" yaml:"removeHeader,omitempty"` + Realm string `json:"realm,omitempty" toml:"realm,omitempty" yaml:"realm,omitempty"` + HeaderField string `json:"headerField,omitempty" toml:"headerField,omitempty" yaml:"headerField,omitempty" export:"true"` } // +k8s:deepcopy-gen=true // ErrorPage holds the custom error page configuration. type ErrorPage struct { - Status []string `json:"status,omitempty"` - Service string `json:"service,omitempty"` - Query string `json:"query,omitempty"` + Status []string `json:"status,omitempty" toml:"status,omitempty" yaml:"status,omitempty"` + Service string `json:"service,omitempty" toml:"service,omitempty" yaml:"service,omitempty"` + Query string `json:"query,omitempty" toml:"query,omitempty" yaml:"query,omitempty"` } // +k8s:deepcopy-gen=true // ForwardAuth holds the http forward authentication configuration. type ForwardAuth struct { - Address string `description:"Authentication server address" json:"address,omitempty"` - TLS *ClientTLS `description:"Enable TLS support" json:"tls,omitempty" export:"true"` - TrustForwardHeader bool `description:"Trust X-Forwarded-* headers" json:"trustForwardHeader,omitempty" export:"true"` - AuthResponseHeaders []string `description:"Headers to be forwarded from auth response" json:"authResponseHeaders,omitempty"` + Address string `json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` + TLS *ClientTLS `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty"` + TrustForwardHeader bool `json:"trustForwardHeader,omitempty" toml:"trustForwardHeader,omitempty" yaml:"trustForwardHeader,omitempty" export:"true"` + AuthResponseHeaders []string `json:"authResponseHeaders,omitempty" toml:"authResponseHeaders,omitempty" yaml:"authResponseHeaders,omitempty"` } // +k8s:deepcopy-gen=true // Headers holds the custom header configuration. type Headers struct { - CustomRequestHeaders map[string]string `json:"customRequestHeaders,omitempty"` - CustomResponseHeaders map[string]string `json:"customResponseHeaders,omitempty"` + CustomRequestHeaders map[string]string `json:"customRequestHeaders,omitempty" toml:"customRequestHeaders,omitempty" yaml:"customRequestHeaders,omitempty"` + CustomResponseHeaders map[string]string `json:"customResponseHeaders,omitempty" toml:"customResponseHeaders,omitempty" yaml:"customResponseHeaders,omitempty"` // AccessControlAllowCredentials is only valid if true. false is ignored. - AccessControlAllowCredentials bool `json:"AccessControlAllowCredentials,omitempty"` + AccessControlAllowCredentials bool `json:"accessControlAllowCredentials,omitempty" toml:"accessControlAllowCredentials,omitempty" yaml:"accessControlAllowCredentials,omitempty"` // AccessControlAllowHeaders must be used in response to a preflight request with Access-Control-Request-Headers set. - AccessControlAllowHeaders []string `json:"AccessControlAllowHeaders,omitempty"` + AccessControlAllowHeaders []string `json:"accessControlAllowHeaders,omitempty" toml:"accessControlAllowHeaders,omitempty" yaml:"accessControlAllowHeaders,omitempty"` // AccessControlAllowMethods must be used in response to a preflight request with Access-Control-Request-Method set. - AccessControlAllowMethods []string `json:"AccessControlAllowMethods,omitempty"` + AccessControlAllowMethods []string `json:"accessControlAllowMethods,omitempty" toml:"accessControlAllowMethods,omitempty" yaml:"accessControlAllowMethods,omitempty"` // AccessControlAllowOrigin Can be "origin-list-or-null" or "*". From (https://www.w3.org/TR/cors/#access-control-allow-origin-response-header) - AccessControlAllowOrigin string `json:"AccessControlAllowOrigin,omitempty"` + AccessControlAllowOrigin string `json:"accessControlAllowOrigin,omitempty" toml:"accessControlAllowOrigin,omitempty" yaml:"accessControlAllowOrigin,omitempty"` // AccessControlExposeHeaders sets valid headers for the response. - AccessControlExposeHeaders []string `json:"AccessControlExposeHeaders,omitempty"` + AccessControlExposeHeaders []string `json:"accessControlExposeHeaders,omitempty" toml:"accessControlExposeHeaders,omitempty" yaml:"accessControlExposeHeaders,omitempty"` // AccessControlMaxAge sets the time that a preflight request may be cached. - AccessControlMaxAge int64 `json:"AccessControlMaxAge,omitempty"` + AccessControlMaxAge int64 `json:"accessControlMaxAge,omitempty" toml:"accessControlMaxAge,omitempty" yaml:"accessControlMaxAge,omitempty"` // AddVaryHeader controls if the Vary header is automatically added/updated when the AccessControlAllowOrigin is set. - AddVaryHeader bool `json:"AddVaryHeader,omitempty"` + AddVaryHeader bool `json:"addVaryHeader,omitempty" toml:"addVaryHeader,omitempty" yaml:"addVaryHeader,omitempty"` - AllowedHosts []string `json:"allowedHosts,omitempty"` - HostsProxyHeaders []string `json:"hostsProxyHeaders,omitempty"` - SSLRedirect bool `json:"sslRedirect,omitempty"` - SSLTemporaryRedirect bool `json:"sslTemporaryRedirect,omitempty"` - SSLHost string `json:"sslHost,omitempty"` - SSLProxyHeaders map[string]string `json:"sslProxyHeaders,omitempty"` - SSLForceHost bool `json:"sslForceHost,omitempty"` - STSSeconds int64 `json:"stsSeconds,omitempty"` - STSIncludeSubdomains bool `json:"stsIncludeSubdomains,omitempty"` - STSPreload bool `json:"stsPreload,omitempty"` - ForceSTSHeader bool `json:"forceSTSHeader,omitempty"` - FrameDeny bool `json:"frameDeny,omitempty"` - CustomFrameOptionsValue string `json:"customFrameOptionsValue,omitempty"` - ContentTypeNosniff bool `json:"contentTypeNosniff,omitempty"` - BrowserXSSFilter bool `json:"browserXssFilter,omitempty"` - CustomBrowserXSSValue string `json:"customBrowserXSSValue,omitempty"` - ContentSecurityPolicy string `json:"contentSecurityPolicy,omitempty"` - PublicKey string `json:"publicKey,omitempty"` - ReferrerPolicy string `json:"referrerPolicy,omitempty"` - IsDevelopment bool `json:"isDevelopment,omitempty"` + AllowedHosts []string `json:"allowedHosts,omitempty" toml:"allowedHosts,omitempty" yaml:"allowedHosts,omitempty"` + HostsProxyHeaders []string `json:"hostsProxyHeaders,omitempty" toml:"hostsProxyHeaders,omitempty" yaml:"hostsProxyHeaders,omitempty"` + SSLRedirect bool `json:"sslRedirect,omitempty" toml:"sslRedirect,omitempty" yaml:"sslRedirect,omitempty"` + SSLTemporaryRedirect bool `json:"sslTemporaryRedirect,omitempty" toml:"sslTemporaryRedirect,omitempty" yaml:"sslTemporaryRedirect,omitempty"` + SSLHost string `json:"sslHost,omitempty" toml:"sslHost,omitempty" yaml:"sslHost,omitempty"` + SSLProxyHeaders map[string]string `json:"sslProxyHeaders,omitempty" toml:"sslProxyHeaders,omitempty" yaml:"sslProxyHeaders,omitempty"` + SSLForceHost bool `json:"sslForceHost,omitempty" toml:"sslForceHost,omitempty" yaml:"sslForceHost,omitempty"` + STSSeconds int64 `json:"stsSeconds,omitempty" toml:"stsSeconds,omitempty" yaml:"stsSeconds,omitempty"` + STSIncludeSubdomains bool `json:"stsIncludeSubdomains,omitempty" toml:"stsIncludeSubdomains,omitempty" yaml:"stsIncludeSubdomains,omitempty"` + STSPreload bool `json:"stsPreload,omitempty" toml:"stsPreload,omitempty" yaml:"stsPreload,omitempty"` + ForceSTSHeader bool `json:"forceSTSHeader,omitempty" toml:"forceSTSHeader,omitempty" yaml:"forceSTSHeader,omitempty"` + FrameDeny bool `json:"frameDeny,omitempty" toml:"frameDeny,omitempty" yaml:"frameDeny,omitempty"` + CustomFrameOptionsValue string `json:"customFrameOptionsValue,omitempty" toml:"customFrameOptionsValue,omitempty" yaml:"customFrameOptionsValue,omitempty"` + ContentTypeNosniff bool `json:"contentTypeNosniff,omitempty" toml:"contentTypeNosniff,omitempty" yaml:"contentTypeNosniff,omitempty"` + BrowserXSSFilter bool `json:"browserXssFilter,omitempty" toml:"browserXssFilter,omitempty" yaml:"browserXssFilter,omitempty"` + CustomBrowserXSSValue string `json:"customBrowserXSSValue,omitempty" toml:"customBrowserXSSValue,omitempty" yaml:"customBrowserXSSValue,omitempty"` + ContentSecurityPolicy string `json:"contentSecurityPolicy,omitempty" toml:"contentSecurityPolicy,omitempty" yaml:"contentSecurityPolicy,omitempty"` + PublicKey string `json:"publicKey,omitempty" toml:"publicKey,omitempty" yaml:"publicKey,omitempty"` + ReferrerPolicy string `json:"referrerPolicy,omitempty" toml:"referrerPolicy,omitempty" yaml:"referrerPolicy,omitempty"` + IsDevelopment bool `json:"isDevelopment,omitempty" toml:"isDevelopment,omitempty" yaml:"isDevelopment,omitempty"` } // HasCustomHeadersDefined checks to see if any of the custom header elements have been set @@ -208,8 +214,8 @@ func (h *Headers) HasSecureHeadersDefined() bool { // IPStrategy holds the ip strategy configuration. type IPStrategy struct { - Depth int `json:"depth,omitempty" export:"true"` - ExcludedIPs []string `json:"excludedIPs,omitempty"` + Depth int `json:"depth,omitempty" toml:"depth,omitempty" yaml:"depth,omitempty" export:"true"` + ExcludedIPs []string `json:"excludedIPs,omitempty" toml:"excludedIPs,omitempty" yaml:"excludedIPs,omitempty"` } // Get an IP selection strategy @@ -244,16 +250,16 @@ func (s *IPStrategy) Get() (ip.Strategy, error) { // IPWhiteList holds the ip white list configuration. type IPWhiteList struct { - SourceRange []string `json:"sourceRange,omitempty"` - IPStrategy *IPStrategy `json:"ipStrategy,omitempty" label:"allowEmpty"` + SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"` + IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty"` } // +k8s:deepcopy-gen=true // MaxConn holds maximum connection configuration. type MaxConn struct { - Amount int64 `json:"amount,omitempty"` - ExtractorFunc string `json:"extractorFunc,omitempty"` + Amount int64 `json:"amount,omitempty" toml:"amount,omitempty" yaml:"amount,omitempty"` + ExtractorFunc string `json:"extractorFunc,omitempty" toml:"extractorFunc,omitempty" yaml:"extractorFunc,omitempty"` } // SetDefaults Default values for a MaxConn. @@ -265,26 +271,26 @@ func (m *MaxConn) SetDefaults() { // PassTLSClientCert holds the TLS client cert headers configuration. type PassTLSClientCert struct { - PEM bool `description:"Enable header with escaped client pem" json:"pem"` - Info *TLSClientCertificateInfo `description:"Enable header with configured client cert info" json:"info,omitempty"` + PEM bool `json:"pem,omitempty" toml:"pem,omitempty" yaml:"pem,omitempty"` + Info *TLSClientCertificateInfo `json:"info,omitempty" toml:"info,omitempty" yaml:"info,omitempty"` } // +k8s:deepcopy-gen=true // Rate holds the rate limiting configuration for a specific time period. type Rate struct { - Period types.Duration `json:"period,omitempty"` - Average int64 `json:"average,omitempty"` - Burst int64 `json:"burst,omitempty"` + Period types.Duration `json:"period,omitempty" toml:"period,omitempty" yaml:"period,omitempty"` + Average int64 `json:"average,omitempty" toml:"average,omitempty" yaml:"average,omitempty"` + Burst int64 `json:"burst,omitempty" toml:"burst,omitempty" yaml:"burst,omitempty"` } // +k8s:deepcopy-gen=true // RateLimit holds the rate limiting configuration for a given frontend. type RateLimit struct { - RateSet map[string]*Rate `json:"rateset,omitempty"` + RateSet map[string]*Rate `json:"rateSet,omitempty" toml:"rateSet,omitempty" yaml:"rateSet,omitempty"` // FIXME replace by ipStrategy see oxy and replace - ExtractorFunc string `json:"extractorFunc,omitempty"` + ExtractorFunc string `json:"extractorFunc,omitempty" toml:"extractorFunc,omitempty" yaml:"extractorFunc,omitempty"` } // SetDefaults Default values for a MaxConn. @@ -296,65 +302,65 @@ func (r *RateLimit) SetDefaults() { // RedirectRegex holds the redirection configuration. type RedirectRegex struct { - Regex string `json:"regex,omitempty"` - Replacement string `json:"replacement,omitempty"` - Permanent bool `json:"permanent,omitempty"` + Regex string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty"` + Replacement string `json:"replacement,omitempty" toml:"replacement,omitempty" yaml:"replacement,omitempty"` + Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty"` } // +k8s:deepcopy-gen=true // RedirectScheme holds the scheme redirection configuration. type RedirectScheme struct { - Scheme string `json:"scheme,omitempty"` - Port string `json:"port,omitempty"` - Permanent bool `json:"permanent,omitempty"` + Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty"` + Port string `json:"port,omitempty" toml:"port,omitempty" yaml:"port,omitempty"` + Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty"` } // +k8s:deepcopy-gen=true // ReplacePath holds the ReplacePath configuration. type ReplacePath struct { - Path string `json:"path,omitempty"` + Path string `json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty"` } // +k8s:deepcopy-gen=true // ReplacePathRegex holds the ReplacePathRegex configuration. type ReplacePathRegex struct { - Regex string `json:"regex,omitempty"` - Replacement string `json:"replacement,omitempty"` + Regex string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty"` + Replacement string `json:"replacement,omitempty" toml:"replacement,omitempty" yaml:"replacement,omitempty"` } // +k8s:deepcopy-gen=true // Retry holds the retry configuration. type Retry struct { - Attempts int `description:"Number of attempts" export:"true"` + Attempts int `json:"attempts,omitempty" toml:"attempts,omitempty" yaml:"attempts,omitempty" export:"true"` } // +k8s:deepcopy-gen=true // StripPrefix holds the StripPrefix configuration. type StripPrefix struct { - Prefixes []string `json:"prefixes,omitempty"` + Prefixes []string `json:"prefixes,omitempty" toml:"prefixes,omitempty" yaml:"prefixes,omitempty"` } // +k8s:deepcopy-gen=true // StripPrefixRegex holds the StripPrefixRegex configuration. type StripPrefixRegex struct { - Regex []string `json:"regex,omitempty"` + Regex []string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty"` } // +k8s:deepcopy-gen=true // TLSClientCertificateInfo holds the client TLS certificate info configuration. type TLSClientCertificateInfo struct { - NotAfter bool `description:"Add NotAfter info in header" json:"notAfter"` - NotBefore bool `description:"Add NotBefore info in header" json:"notBefore"` - Sans bool `description:"Add Sans info in header" json:"sans"` - Subject *TLSCLientCertificateDNInfo `description:"Add Subject info in header" json:"subject,omitempty"` - Issuer *TLSCLientCertificateDNInfo `description:"Add Issuer info in header" json:"issuer,omitempty"` + NotAfter bool `json:"notAfter,omitempty" toml:"notAfter,omitempty" yaml:"notAfter,omitempty"` + NotBefore bool `json:"notBefore,omitempty" toml:"notBefore,omitempty" yaml:"notBefore,omitempty"` + Sans bool `json:"sans,omitempty" toml:"sans,omitempty" yaml:"sans,omitempty"` + Subject *TLSCLientCertificateDNInfo `json:"subject,omitempty" toml:"subject,omitempty" yaml:"subject,omitempty"` + Issuer *TLSCLientCertificateDNInfo `json:"issuer,omitempty" toml:"issuer,omitempty" yaml:"issuer,omitempty"` } // +k8s:deepcopy-gen=true @@ -362,13 +368,13 @@ type TLSClientCertificateInfo struct { // TLSCLientCertificateDNInfo holds the client TLS certificate distinguished name info configuration // cf https://tools.ietf.org/html/rfc3739 type TLSCLientCertificateDNInfo struct { - Country bool `description:"Add Country info in header" json:"country"` - Province bool `description:"Add Province info in header" json:"province"` - Locality bool `description:"Add Locality info in header" json:"locality"` - Organization bool `description:"Add Organization info in header" json:"organization"` - CommonName bool `description:"Add CommonName info in header" json:"commonName"` - SerialNumber bool `description:"Add SerialNumber info in header" json:"serialNumber"` - DomainComponent bool `description:"Add Domain Component info in header" json:"domainComponent"` + Country bool `json:"country,omitempty" toml:"country,omitempty" yaml:"country,omitempty"` + Province bool `json:"province,omitempty" toml:"province,omitempty" yaml:"province,omitempty"` + Locality bool `json:"locality,omitempty" toml:"locality,omitempty" yaml:"locality,omitempty"` + Organization bool `json:"organization,omitempty" toml:"organization,omitempty" yaml:"organization,omitempty"` + CommonName bool `json:"commonName,omitempty" toml:"commonName,omitempty" yaml:"commonName,omitempty"` + SerialNumber bool `json:"serialNumber,omitempty" toml:"serialNumber,omitempty" yaml:"serialNumber,omitempty"` + DomainComponent bool `json:"domainComponent,omitempty" toml:"domainComponent,omitempty" yaml:"domainComponent,omitempty"` } // +k8s:deepcopy-gen=true @@ -381,9 +387,78 @@ type Users []string // ClientTLS holds the TLS specific configurations as client // CA, Cert and Key can be either path or file contents. type ClientTLS struct { - CA string `description:"TLS CA" json:"ca,omitempty"` - CAOptional bool `description:"TLS CA.Optional" json:"caOptional,omitempty"` - Cert string `description:"TLS cert" json:"cert,omitempty"` - Key string `description:"TLS key" json:"key,omitempty"` - InsecureSkipVerify bool `description:"TLS insecure skip verify" json:"insecureSkipVerify,omitempty"` + CA string `json:"ca,omitempty" toml:"ca,omitempty" yaml:"ca,omitempty"` + CAOptional bool `json:"caOptional,omitempty" toml:"caOptional,omitempty" yaml:"caOptional,omitempty"` + Cert string `json:"cert,omitempty" toml:"cert,omitempty" yaml:"cert,omitempty"` + Key string `json:"key,omitempty" toml:"key,omitempty" yaml:"key,omitempty"` + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty"` +} + +// CreateTLSConfig creates a TLS config from ClientTLS structures. +func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) { + if clientTLS == nil { + return nil, nil + } + + var err error + caPool := x509.NewCertPool() + clientAuth := tls.NoClientCert + if clientTLS.CA != "" { + var ca []byte + if _, errCA := os.Stat(clientTLS.CA); errCA == nil { + ca, err = ioutil.ReadFile(clientTLS.CA) + if err != nil { + return nil, fmt.Errorf("failed to read CA. %s", err) + } + } else { + ca = []byte(clientTLS.CA) + } + + if !caPool.AppendCertsFromPEM(ca) { + return nil, fmt.Errorf("failed to parse CA") + } + + if clientTLS.CAOptional { + clientAuth = tls.VerifyClientCertIfGiven + } else { + clientAuth = tls.RequireAndVerifyClientCert + } + } + + cert := tls.Certificate{} + _, errKeyIsFile := os.Stat(clientTLS.Key) + + if !clientTLS.InsecureSkipVerify && (len(clientTLS.Cert) == 0 || len(clientTLS.Key) == 0) { + return nil, fmt.Errorf("TLS Certificate or Key file must be set when TLS configuration is created") + } + + if len(clientTLS.Cert) > 0 && len(clientTLS.Key) > 0 { + if _, errCertIsFile := os.Stat(clientTLS.Cert); errCertIsFile == nil { + if errKeyIsFile == nil { + cert, err = tls.LoadX509KeyPair(clientTLS.Cert, clientTLS.Key) + if err != nil { + return nil, fmt.Errorf("failed to load TLS keypair: %v", err) + } + } else { + return nil, fmt.Errorf("tls cert is a file, but tls key is not") + } + } else { + if errKeyIsFile != nil { + cert, err = tls.X509KeyPair([]byte(clientTLS.Cert), []byte(clientTLS.Key)) + if err != nil { + return nil, fmt.Errorf("failed to load TLS keypair: %v", err) + + } + } else { + return nil, fmt.Errorf("TLS key is a file, but tls cert is not") + } + } + } + + return &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: caPool, + InsecureSkipVerify: clientTLS.InsecureSkipVerify, + ClientAuth: clientAuth, + }, nil } diff --git a/pkg/config/static/entrypoints.go b/pkg/config/static/entrypoints.go index 3cfaac2dd..544bb8386 100644 --- a/pkg/config/static/entrypoints.go +++ b/pkg/config/static/entrypoints.go @@ -2,10 +2,10 @@ package static // EntryPoint holds the entry point configuration. type EntryPoint struct { - Address string `description:"Entry point address."` - Transport *EntryPointsTransport `description:"Configures communication between clients and Traefik."` - ProxyProtocol *ProxyProtocol `description:"Proxy-Protocol configuration." label:"allowEmpty"` - ForwardedHeaders *ForwardedHeaders `description:"Trust client forwarding headers."` + Address string `description:"Entry point address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` + Transport *EntryPointsTransport `description:"Configures communication between clients and Traefik." json:"transport,omitempty" toml:"transport,omitempty" yaml:"transport,omitempty"` + ProxyProtocol *ProxyProtocol `description:"Proxy-Protocol configuration." json:"proxyProtocol,omitempty" toml:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty" label:"allowEmpty"` + ForwardedHeaders *ForwardedHeaders `description:"Trust client forwarding headers." json:"forwardedHeaders,omitempty" toml:"forwardedHeaders,omitempty" yaml:"forwardedHeaders,omitempty"` } // SetDefaults sets the default values. @@ -17,14 +17,14 @@ func (e *EntryPoint) SetDefaults() { // ForwardedHeaders Trust client forwarding headers. type ForwardedHeaders struct { - Insecure bool `description:"Trust all forwarded headers." export:"true"` - TrustedIPs []string `description:"Trust only forwarded headers from selected IPs."` + Insecure bool `description:"Trust all forwarded headers." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true"` + TrustedIPs []string `description:"Trust only forwarded headers from selected IPs." json:"trustedIPs,omitempty" toml:"trustedIPs,omitempty" yaml:"trustedIPs,omitempty"` } // ProxyProtocol contains Proxy-Protocol configuration. type ProxyProtocol struct { - Insecure bool `description:"Trust all." export:"true"` - TrustedIPs []string `description:"Trust only selected IPs."` + Insecure bool `description:"Trust all." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true"` + TrustedIPs []string `description:"Trust only selected IPs." json:"trustedIPs,omitempty" toml:"trustedIPs,omitempty" yaml:"trustedIPs,omitempty"` } // EntryPoints holds the HTTP entry point list. @@ -32,8 +32,8 @@ type EntryPoints map[string]*EntryPoint // EntryPointsTransport configures communication between clients and Traefik. type EntryPointsTransport struct { - LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle." export:"true"` - RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance." export:"true"` + LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle." json:"lifeCycle,omitempty" toml:"lifeCycle,omitempty" yaml:"lifeCycle,omitempty" export:"true" export:"true"` + RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance." json:"respondingTimeouts,omitempty" toml:"respondingTimeouts,omitempty" yaml:"respondingTimeouts,omitempty" export:"true" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index d149ef37b..d34931506 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -43,48 +43,47 @@ const ( // Configuration is the static configuration type Configuration struct { - Global *Global `description:"Global configuration options" export:"true"` + Global *Global `description:"Global configuration options" json:"global,omitempty" toml:"global,omitempty" yaml:"global,omitempty" export:"true"` - ServersTransport *ServersTransport `description:"Servers default transport." export:"true"` - EntryPoints EntryPoints `description:"Entry points definition." export:"true"` - Providers *Providers `description:"Providers configuration." export:"true"` + ServersTransport *ServersTransport `description:"Servers default transport." json:"serversTransport,omitempty" toml:"serversTransport,omitempty" yaml:"serversTransport,omitempty" export:"true"` + EntryPoints EntryPoints `description:"Entry points definition." json:"entryPoints,omitempty" toml:"entryPoints,omitempty" yaml:"entryPoints,omitempty" export:"true"` + Providers *Providers `description:"Providers configuration." json:"providers,omitempty" toml:"providers,omitempty" yaml:"providers,omitempty" export:"true"` - API *API `description:"Enable api/dashboard." export:"true" label:"allowEmpty"` - Metrics *types.Metrics `description:"Enable a metrics exporter." export:"true"` - Ping *ping.Handler `description:"Enable ping." export:"true" label:"allowEmpty"` - // Rest *rest.Provider `description:"Enable Rest backend with default settings" export:"true"` + API *API `description:"Enable api/dashboard." json:"api,omitempty" toml:"api,omitempty" yaml:"api,omitempty" label:"allowEmpty" export:"true"` + Metrics *types.Metrics `description:"Enable a metrics exporter." json:"metrics,omitempty" toml:"metrics,omitempty" yaml:"metrics,omitempty" export:"true"` + Ping *ping.Handler `description:"Enable ping." json:"ping,omitempty" toml:"ping,omitempty" yaml:"ping,omitempty" label:"allowEmpty" export:"true"` - Log *types.TraefikLog `description:"Traefik log settings." export:"true" label:"allowEmpty"` - AccessLog *types.AccessLog `description:"Access log settings." export:"true" label:"allowEmpty"` - Tracing *Tracing `description:"OpenTracing configuration." export:"true" label:"allowEmpty"` + Log *types.TraefikLog `description:"Traefik log settings." json:"log,omitempty" toml:"log,omitempty" yaml:"log,omitempty" label:"allowEmpty" export:"true"` + AccessLog *types.AccessLog `description:"Access log settings." json:"accessLog,omitempty" toml:"accessLog,omitempty" yaml:"accessLog,omitempty" label:"allowEmpty" export:"true"` + Tracing *Tracing `description:"OpenTracing configuration." json:"tracing,omitempty" toml:"tracing,omitempty" yaml:"tracing,omitempty" label:"allowEmpty" export:"true"` - HostResolver *types.HostResolverConfig `description:"Enable CNAME Flattening." export:"true" label:"allowEmpty"` + HostResolver *types.HostResolverConfig `description:"Enable CNAME Flattening." json:"hostResolver,omitempty" toml:"hostResolver,omitempty" yaml:"hostResolver,omitempty" label:"allowEmpty" export:"true"` - ACME *acmeprovider.Configuration `description:"Enable ACME (Let's Encrypt): automatic SSL." export:"true"` + ACME *acmeprovider.Configuration `description:"Enable ACME (Let's Encrypt): automatic SSL." json:"acme,omitempty" toml:"acme,omitempty" yaml:"acme,omitempty" export:"true"` } // Global holds the global configuration. type Global struct { - CheckNewVersion bool `description:"Periodically check if a new version has been released." export:"true"` - SendAnonymousUsage *bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default." export:"true"` + CheckNewVersion bool `description:"Periodically check if a new version has been released." json:"checkNewVersion,omitempty" toml:"checkNewVersion,omitempty" yaml:"checkNewVersion,omitempty" label:"allowEmpty" export:"true"` + SendAnonymousUsage *bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default." json:"sendAnonymousUsage,omitempty" toml:"sendAnonymousUsage,omitempty" yaml:"sendAnonymousUsage,omitempty" label:"allowEmpty" export:"true"` } // ServersTransport options to configure communication between Traefik and the servers type ServersTransport struct { - InsecureSkipVerify bool `description:"Disable SSL certificate verification." export:"true"` - RootCAs []tls.FileOrContent `description:"Add cert file for self-signed certificate."` - MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" export:"true"` - ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers." export:"true"` + InsecureSkipVerify bool `description:"Disable SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"` + RootCAs []tls.FileOrContent `description:"Add cert file for self-signed certificate." json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"` + MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" json:"maxIdleConnsPerHost,omitempty" toml:"maxIdleConnsPerHost,omitempty" yaml:"maxIdleConnsPerHost,omitempty" export:"true"` + ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"` } // API holds the API configuration type API struct { - EntryPoint string `description:"The entry point that the API handler will be bound to." export:"true"` - Dashboard bool `description:"Activate dashboard." export:"true"` - Debug bool `description:"Enable additional endpoints for debugging and profiling." export:"true"` - Statistics *types.Statistics `description:"Enable more detailed statistics." export:"true" label:"allowEmpty"` - Middlewares []string `description:"Middleware list." export:"true"` - DashboardAssets *assetfs.AssetFS `json:"-" label:"-"` + EntryPoint string `description:"The entry point that the API handler will be bound to." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"` + Dashboard bool `description:"Activate dashboard." json:"dashboard,omitempty" toml:"dashboard,omitempty" yaml:"dashboard,omitempty" export:"true"` + Debug bool `description:"Enable additional endpoints for debugging and profiling." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"` + Statistics *types.Statistics `description:"Enable more detailed statistics." json:"statistics,omitempty" toml:"statistics,omitempty" yaml:"statistics,omitempty" export:"true" label:"allowEmpty"` + Middlewares []string `description:"Middleware list." json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"` + DashboardAssets *assetfs.AssetFS `json:"-" toml:"-" yaml:"-" label:"-"` } // SetDefaults sets the default values. @@ -95,9 +94,9 @@ func (a *API) SetDefaults() { // RespondingTimeouts contains timeout configurations for incoming requests to the Traefik instance. type RespondingTimeouts struct { - ReadTimeout types.Duration `description:"ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set." export:"true"` - WriteTimeout types.Duration `description:"WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set." export:"true"` - IdleTimeout types.Duration `description:"IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout is set." export:"true"` + ReadTimeout types.Duration `description:"ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set." json:"readTimeout,omitempty" toml:"readTimeout,omitempty" yaml:"readTimeout,omitempty" export:"true"` + WriteTimeout types.Duration `description:"WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set." json:"writeTimeout,omitempty" toml:"writeTimeout,omitempty" yaml:"writeTimeout,omitempty" export:"true"` + IdleTimeout types.Duration `description:"IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout is set." json:"idleTimeout,omitempty" toml:"idleTimeout,omitempty" yaml:"idleTimeout,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -107,9 +106,9 @@ func (a *RespondingTimeouts) SetDefaults() { // ForwardingTimeouts contains timeout configurations for forwarding requests to the backend servers. type ForwardingTimeouts struct { - DialTimeout types.Duration `description:"The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." export:"true"` - ResponseHeaderTimeout types.Duration `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists." export:"true"` - IdleConnTimeout types.Duration `description:"The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself" export:"true"` + DialTimeout types.Duration `description:"The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." json:"dialTimeout,omitempty" toml:"dialTimeout,omitempty" yaml:"dialTimeout,omitempty" export:"true"` + ResponseHeaderTimeout types.Duration `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"` + IdleConnTimeout types.Duration `description:"The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself" json:"idleConnTimeout,omitempty" toml:"idleConnTimeout,omitempty" yaml:"idleConnTimeout,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -120,8 +119,8 @@ func (f *ForwardingTimeouts) SetDefaults() { // LifeCycle contains configurations relevant to the lifecycle (such as the shutdown phase) of Traefik. type LifeCycle struct { - RequestAcceptGraceTimeout types.Duration `description:"Duration to keep accepting requests before Traefik initiates the graceful shutdown procedure."` - GraceTimeOut types.Duration `description:"Duration to give active requests a chance to finish before Traefik stops."` + RequestAcceptGraceTimeout types.Duration `description:"Duration to keep accepting requests before Traefik initiates the graceful shutdown procedure." json:"requestAcceptGraceTimeout,omitempty" toml:"requestAcceptGraceTimeout,omitempty" yaml:"requestAcceptGraceTimeout,omitempty" export:"true"` + GraceTimeOut types.Duration `description:"Duration to give active requests a chance to finish before Traefik stops." json:"graceTimeOut,omitempty" toml:"graceTimeOut,omitempty" yaml:"graceTimeOut,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -131,13 +130,13 @@ func (a *LifeCycle) SetDefaults() { // Tracing holds the tracing configuration. type Tracing struct { - ServiceName string `description:"Set the name for this service." export:"true"` - SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)." export:"true"` - Jaeger *jaeger.Config `description:"Settings for jaeger." label:"allowEmpty"` - Zipkin *zipkin.Config `description:"Settings for zipkin." label:"allowEmpty"` - DataDog *datadog.Config `description:"Settings for DataDog." label:"allowEmpty"` - Instana *instana.Config `description:"Settings for Instana." label:"allowEmpty"` - Haystack *haystack.Config `description:"Settings for Haystack." label:"allowEmpty"` + ServiceName string `description:"Set the name for this service." json:"serviceName,omitempty" toml:"serviceName,omitempty" yaml:"serviceName,omitempty" export:"true"` + SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)." json:"spanNameLimit,omitempty" toml:"spanNameLimit,omitempty" yaml:"spanNameLimit,omitempty" export:"true"` + Jaeger *jaeger.Config `description:"Settings for Jaeger." json:"jaeger,omitempty" toml:"jaeger,omitempty" yaml:"jaeger,omitempty" export:"true" label:"allowEmpty"` + Zipkin *zipkin.Config `description:"Settings for Zipkin." json:"zipkin,omitempty" toml:"zipkin,omitempty" yaml:"zipkin,omitempty" export:"true" label:"allowEmpty"` + DataDog *datadog.Config `description:"Settings for DataDog." json:"dataDog,omitempty" toml:"dataDog,omitempty" yaml:"dataDog,omitempty" export:"true" label:"allowEmpty"` + Instana *instana.Config `description:"Settings for Instana." json:"instana,omitempty" toml:"instana,omitempty" yaml:"instana,omitempty" export:"true" label:"allowEmpty"` + Haystack *haystack.Config `description:"Settings for Haystack." json:"haystack,omitempty" toml:"haystack,omitempty" yaml:"haystack,omitempty" export:"true" label:"allowEmpty"` } // SetDefaults sets the default values. @@ -148,14 +147,14 @@ func (t *Tracing) SetDefaults() { // Providers contains providers configuration type Providers struct { - ProvidersThrottleDuration types.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time." export:"true"` - Docker *docker.Provider `description:"Enable Docker backend with default settings." export:"true" label:"allowEmpty"` - File *file.Provider `description:"Enable File backend with default settings." export:"true" label:"allowEmpty"` - Marathon *marathon.Provider `description:"Enable Marathon backend with default settings." export:"true" label:"allowEmpty"` - Kubernetes *ingress.Provider `description:"Enable Kubernetes backend with default settings." export:"true" label:"allowEmpty"` - KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." export:"true" label:"allowEmpty"` - Rest *rest.Provider `description:"Enable Rest backend with default settings." export:"true" label:"allowEmpty"` - Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." export:"true" label:"allowEmpty"` + ProvidersThrottleDuration types.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time." json:"providersThrottleDuration,omitempty" toml:"providersThrottleDuration,omitempty" yaml:"providersThrottleDuration,omitempty" export:"true"` + Docker *docker.Provider `description:"Enable Docker backend with default settings." json:"docker,omitempty" toml:"docker,omitempty" yaml:"docker,omitempty" export:"true" label:"allowEmpty"` + File *file.Provider `description:"Enable File backend with default settings." json:"file,omitempty" toml:"file,omitempty" yaml:"file,omitempty" export:"true" label:"allowEmpty"` + Marathon *marathon.Provider `description:"Enable Marathon backend with default settings." json:"marathon,omitempty" toml:"marathon,omitempty" yaml:"marathon,omitempty" export:"true" label:"allowEmpty"` + Kubernetes *ingress.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetes,omitempty" toml:"kubernetes,omitempty" yaml:"kubernetes,omitempty" export:"true" label:"allowEmpty"` + KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesCRD,omitempty" toml:"kubernetesCRD,omitempty" yaml:"kubernetesCRD,omitempty" export:"true" label:"allowEmpty"` + Rest *rest.Provider `description:"Enable Rest backend with default settings." json:"rest,omitempty" toml:"rest,omitempty" yaml:"rest,omitempty" export:"true" label:"allowEmpty"` + Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." json:"rancher,omitempty" toml:"rancher,omitempty" yaml:"rancher,omitempty" export:"true" label:"allowEmpty"` } // SetEffectiveConfiguration adds missing configuration parameters derived from existing ones. diff --git a/pkg/metrics/datadog.go b/pkg/metrics/datadog.go index e2118cead..5e3567059 100644 --- a/pkg/metrics/datadog.go +++ b/pkg/metrics/datadog.go @@ -35,7 +35,7 @@ const ( ) // RegisterDatadog registers the metrics pusher if this didn't happen yet and creates a datadog Registry instance. -func RegisterDatadog(ctx context.Context, config *types.Datadog) Registry { +func RegisterDatadog(ctx context.Context, config *types.DataDog) Registry { if datadogTicker == nil { datadogTicker = initDatadogClient(ctx, config) } @@ -59,7 +59,7 @@ func RegisterDatadog(ctx context.Context, config *types.Datadog) Registry { return registry } -func initDatadogClient(ctx context.Context, config *types.Datadog) *time.Ticker { +func initDatadogClient(ctx context.Context, config *types.DataDog) *time.Ticker { address := config.Address if len(address) == 0 { address = "localhost:8125" diff --git a/pkg/metrics/datadog_test.go b/pkg/metrics/datadog_test.go index e45976c13..c8618c01b 100644 --- a/pkg/metrics/datadog_test.go +++ b/pkg/metrics/datadog_test.go @@ -16,7 +16,7 @@ func TestDatadog(t *testing.T) { // This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond udp.Timeout = 5 * time.Second - datadogRegistry := RegisterDatadog(context.Background(), &types.Datadog{Address: ":18125", PushInterval: types.Duration(time.Second)}) + datadogRegistry := RegisterDatadog(context.Background(), &types.DataDog{Address: ":18125", PushInterval: types.Duration(time.Second)}) defer StopDatadog() if !datadogRegistry.IsEnabled() { diff --git a/pkg/ping/ping.go b/pkg/ping/ping.go index 0daf65499..50e7b4708 100644 --- a/pkg/ping/ping.go +++ b/pkg/ping/ping.go @@ -10,8 +10,8 @@ import ( // Handler expose ping routes. type Handler struct { - EntryPoint string `description:"Ping entryPoint." export:"true"` - Middlewares []string `description:"Middleware list." export:"true"` + EntryPoint string `description:"Ping entryPoint." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"` + Middlewares []string `description:"Middleware list." json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"` terminating bool } diff --git a/pkg/provider/acme/provider.go b/pkg/provider/acme/provider.go index 39e2ba072..75b6ff03b 100644 --- a/pkg/provider/acme/provider.go +++ b/pkg/provider/acme/provider.go @@ -38,17 +38,17 @@ var ( // Configuration holds ACME configuration provided by users type Configuration struct { - Email string `description:"Email address used for registration."` - ACMELogging bool `description:"Enable debug logging of ACME actions."` - CAServer string `description:"CA server to use."` - Storage string `description:"Storage to use."` - EntryPoint string `description:"EntryPoint to use."` - KeyType string `description:"KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'."` - OnHostRule bool `description:"Enable certificate generation on router Host rules."` - DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge." label:"allowEmpty"` - HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge." label:"allowEmpty"` - TLSChallenge *TLSChallenge `description:"Activate TLS-ALPN-01 Challenge." label:"allowEmpty"` - Domains []types.Domain `description:"The list of domains for which certificates are generated on startup. Wildcard domains only accepted with DNSChallenge."` + Email string `description:"Email address used for registration." json:"email,omitempty" toml:"email,omitempty" yaml:"email,omitempty"` + ACMELogging bool `description:"Enable debug logging of ACME actions." json:"acmeLogging,omitempty" toml:"acmeLogging,omitempty" yaml:"acmeLogging,omitempty"` + CAServer string `description:"CA server to use." json:"caServer,omitempty" toml:"caServer,omitempty" yaml:"caServer,omitempty"` + Storage string `description:"Storage to use." json:"storage,omitempty" toml:"storage,omitempty" yaml:"storage,omitempty"` + EntryPoint string `description:"EntryPoint to use." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"` + KeyType string `description:"KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'." json:"keyType,omitempty" toml:"keyType,omitempty" yaml:"keyType,omitempty"` + OnHostRule bool `description:"Enable certificate generation on router Host rules." json:"onHostRule,omitempty" toml:"onHostRule,omitempty" yaml:"onHostRule,omitempty"` + DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge." json:"dnsChallenge,omitempty" toml:"dnsChallenge,omitempty" yaml:"dnsChallenge,omitempty" label:"allowEmpty"` + HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge." json:"httpChallenge,omitempty" toml:"httpChallenge,omitempty" yaml:"httpChallenge,omitempty" label:"allowEmpty"` + TLSChallenge *TLSChallenge `description:"Activate TLS-ALPN-01 Challenge." json:"tlsChallenge,omitempty" toml:"tlsChallenge,omitempty" yaml:"tlsChallenge,omitempty" label:"allowEmpty"` + Domains []types.Domain `description:"The list of domains for which certificates are generated on startup. Wildcard domains only accepted with DNSChallenge." json:"domains,omitempty" toml:"domains,omitempty" yaml:"domains,omitempty"` } // SetDefaults sets the default values. @@ -60,22 +60,22 @@ func (a *Configuration) SetDefaults() { // Certificate is a struct which contains all data needed from an ACME certificate type Certificate struct { - Domain types.Domain - Certificate []byte - Key []byte + Domain types.Domain `json:"domain,omitempty" toml:"domain,omitempty" yaml:"domain,omitempty"` + Certificate []byte `json:"certificate,omitempty" toml:"certificate,omitempty" yaml:"certificate,omitempty"` + Key []byte `json:"key,omitempty" toml:"key,omitempty" yaml:"key,omitempty"` } // DNSChallenge contains DNS challenge Configuration type DNSChallenge struct { - Provider string `description:"Use a DNS-01 based challenge provider rather than HTTPS."` - DelayBeforeCheck types.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."` - Resolvers []string `description:"Use following DNS servers to resolve the FQDN authority."` - DisablePropagationCheck bool `description:"Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready. [not recommended]"` + Provider string `description:"Use a DNS-01 based challenge provider rather than HTTPS." json:"provider,omitempty" toml:"provider,omitempty" yaml:"provider,omitempty"` + DelayBeforeCheck types.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers." json:"delayBeforeCheck,omitempty" toml:"delayBeforeCheck,omitempty" yaml:"delayBeforeCheck,omitempty"` + Resolvers []string `description:"Use following DNS servers to resolve the FQDN authority." json:"resolvers,omitempty" toml:"resolvers,omitempty" yaml:"resolvers,omitempty"` + DisablePropagationCheck bool `description:"Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready. [not recommended]" json:"disablePropagationCheck,omitempty" toml:"disablePropagationCheck,omitempty" yaml:"disablePropagationCheck,omitempty"` } // HTTPChallenge contains HTTP challenge Configuration type HTTPChallenge struct { - EntryPoint string `description:"HTTP challenge EntryPoint"` + EntryPoint string `description:"HTTP challenge EntryPoint" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"` } // TLSChallenge contains TLS challenge Configuration @@ -84,7 +84,7 @@ type TLSChallenge struct{} // Provider holds configurations of the provider. type Provider struct { *Configuration - Store Store + Store Store `json:"store,omitempty" toml:"store,omitempty" yaml:"store,omitempty"` certificates []*Certificate account *Account client *lego.Client diff --git a/pkg/provider/docker/docker.go b/pkg/provider/docker/docker.go index 3e4507647..7eaa48818 100644 --- a/pkg/provider/docker/docker.go +++ b/pkg/provider/docker/docker.go @@ -45,16 +45,16 @@ var _ provider.Provider = (*Provider)(nil) // Provider holds configurations of the provider. type Provider struct { - Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." export:"true"` - Watch bool `description:"Watch provider." export:"true"` - Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint."` - DefaultRule string `description:"Default rule."` - TLS *types.ClientTLS `description:"Enable Docker TLS support." export:"true"` - ExposedByDefault bool `description:"Expose containers by default." export:"true"` - UseBindPortIP bool `description:"Use the ip address from the bound port, rather than from the inner network." export:"true"` - SwarmMode bool `description:"Use Docker on Swarm Mode." export:"true"` - Network string `description:"Default Docker network used." export:"true"` - SwarmModeRefreshSeconds types.Duration `description:"Polling interval for swarm mode." export:"true"` + Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` + Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` + Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"` + DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` + TLS *types.ClientTLS `description:"Enable Docker TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` + ExposedByDefault bool `description:"Expose containers by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` + UseBindPortIP bool `description:"Use the ip address from the bound port, rather than from the inner network." json:"useBindPortIP,omitempty" toml:"useBindPortIP,omitempty" yaml:"useBindPortIP,omitempty" export:"true"` + SwarmMode bool `description:"Use Docker on Swarm Mode." json:"swarmMode,omitempty" toml:"swarmMode,omitempty" yaml:"swarmMode,omitempty" export:"true"` + Network string `description:"Default Docker network used." json:"network,omitempty" toml:"network,omitempty" yaml:"network,omitempty" export:"true"` + SwarmModeRefreshSeconds types.Duration `description:"Polling interval for swarm mode." json:"swarmModeRefreshSeconds,omitempty" toml:"swarmModeRefreshSeconds,omitempty" yaml:"swarmModeRefreshSeconds,omitempty" export:"true"` defaultRuleTpl *template.Template } diff --git a/pkg/provider/file/file.go b/pkg/provider/file/file.go index cceb93fbb..2d64b0375 100644 --- a/pkg/provider/file/file.go +++ b/pkg/provider/file/file.go @@ -28,11 +28,11 @@ var _ provider.Provider = (*Provider)(nil) // Provider holds configurations of the provider. type Provider struct { - Directory string `description:"Load configuration from one or more .toml files in a directory." export:"true"` - Watch bool `description:"Watch provider." export:"true"` - Filename string `description:"Override default configuration template. For advanced users :)" export:"true"` - DebugLogGeneratedTemplate bool `description:"Enable debug logging of generated configuration template." export:"true"` - TraefikFile string `description:"-"` + Directory string `description:"Load configuration from one or more .toml files in a directory." json:"directory,omitempty" toml:"directory,omitempty" yaml:"directory,omitempty" export:"true"` + Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` + Filename string `description:"Override default configuration template. For advanced users :)" json:"filename,omitempty" toml:"filename,omitempty" yaml:"filename,omitempty" export:"true"` + DebugLogGeneratedTemplate bool `description:"Enable debug logging of generated configuration template." json:"debugLogGeneratedTemplate,omitempty" toml:"debugLogGeneratedTemplate,omitempty" yaml:"debugLogGeneratedTemplate,omitempty" export:"true"` + TraefikFile string `description:"-" json:"traefikFile,omitempty" toml:"traefikFile,omitempty" yaml:"traefikFile,omitempty"` } // SetDefaults sets the default values. diff --git a/pkg/provider/file/fixtures/toml/dir01_file01.toml b/pkg/provider/file/fixtures/toml/dir01_file01.toml index 64f84722a..a695df25f 100644 --- a/pkg/provider/file/fixtures/toml/dir01_file01.toml +++ b/pkg/provider/file/fixtures/toml/dir01_file01.toml @@ -1,7 +1,7 @@ [http.routers] -[http.routers."router1"] - service = "application-1" + [http.routers."router1"] + service = "application-1" -[http.routers."router2"] - service = "application-2" + [http.routers."router2"] + service = "application-2" diff --git a/pkg/provider/file/fixtures/toml/dir01_file02.toml b/pkg/provider/file/fixtures/toml/dir01_file02.toml index 6eb6d31d5..3fed5e860 100644 --- a/pkg/provider/file/fixtures/toml/dir01_file02.toml +++ b/pkg/provider/file/fixtures/toml/dir01_file02.toml @@ -1,13 +1,13 @@ [http.services] -[http.services.application-1.loadbalancer] - [[http.services.application-1.loadbalancer.servers]] - url = "http://172.17.0.1:80" +[http.services.application-1.loadBalancer] + [[http.services.application-1.loadBalancer.servers]] + url = "http://172.17.0.1:80" -[http.services.application-2.loadbalancer] - [[http.services.application-2.loadbalancer.servers]] - url = "http://172.17.0.2:80" +[http.services.application-2.loadBalancer] + [[http.services.application-2.loadBalancer.servers]] + url = "http://172.17.0.2:80" -[http.services.application-3.loadbalancer] - [[http.services.application-3.loadbalancer.servers]] - url = "http://172.17.0.3:80" +[http.services.application-3.loadBalancer] + [[http.services.application-3.loadBalancer.servers]] + url = "http://172.17.0.3:80" diff --git a/pkg/provider/file/fixtures/toml/dir01_file03.toml b/pkg/provider/file/fixtures/toml/dir01_file03.toml index 7d5a35e0d..6cfb2635c 100644 --- a/pkg/provider/file/fixtures/toml/dir01_file03.toml +++ b/pkg/provider/file/fixtures/toml/dir01_file03.toml @@ -1,17 +1,17 @@ -[TLS] +[tls] -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest1.com.cert" + keyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest2.com.cert" + keyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest3.com.cert" + keyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest4.com.cert" + keyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_file_01.toml b/pkg/provider/file/fixtures/toml/simple_file_01.toml index 287597951..bb3df5d87 100644 --- a/pkg/provider/file/fixtures/toml/simple_file_01.toml +++ b/pkg/provider/file/fixtures/toml/simple_file_01.toml @@ -1,57 +1,58 @@ [http.routers] -[http.routers."router1"] - service = "application-1" - -[http.routers."router2"] - service = "application-2" - -[http.routers."router3"] - service = "application-3" + [http.routers."router1"] + service = "application-1" + + [http.routers."router2"] + service = "application-2" + + [http.routers."router3"] + service = "application-3" + [http.services] -[http.services.application-1.loadbalancer] - [[http.services.application-1.loadbalancer.servers]] - url = "http://172.17.0.1:80" + [http.services.application-1.loadBalancer] + [[http.services.application-1.loadBalancer.servers]] + url = "http://172.17.0.1:80" -[http.services.application-2.loadbalancer] - [[http.services.application-2.loadbalancer.servers]] - url = "http://172.17.0.2:80" + [http.services.application-2.loadBalancer] + [[http.services.application-2.loadBalancer.servers]] + url = "http://172.17.0.2:80" -[http.services.application-3.loadbalancer] - [[http.services.application-3.loadbalancer.servers]] - url = "http://172.17.0.3:80" + [http.services.application-3.loadBalancer] + [[http.services.application-3.loadBalancer.servers]] + url = "http://172.17.0.3:80" -[http.services.application-4.loadbalancer] - [[http.services.application-4.loadbalancer.servers]] - url = "http://172.17.0.4:80" + [http.services.application-4.loadBalancer] + [[http.services.application-4.loadBalancer.servers]] + url = "http://172.17.0.4:80" -[http.services.application-5.loadbalancer] - [[http.services.application-5.loadbalancer.servers]] - url = "http://172.17.0.5:80" + [http.services.application-5.loadBalancer] + [[http.services.application-5.loadBalancer.servers]] + url = "http://172.17.0.5:80" -[http.services.application-6.loadbalancer] - [[http.services.application-6.loadbalancer.servers]] - url = "http://172.17.0.6:80" + [http.services.application-6.loadBalancer] + [[http.services.application-6.loadBalancer.servers]] + url = "http://172.17.0.6:80" -[TLS] +[tls] -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" + [[tls.certificates]] + certFile = "integration/fixtures/https/snitest1.com.cert" + keyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" + [[tls.certificates]] + certFile = "integration/fixtures/https/snitest2.com.cert" + keyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" + [[tls.certificates]] + certFile = "integration/fixtures/https/snitest3.com.cert" + keyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" + [[tls.certificates]] + certFile = "integration/fixtures/https/snitest4.com.cert" + keyFile = "integration/fixtures/https/snitest4.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest5.com.cert" - KeyFile = "integration/fixtures/https/snitest5.com.key" + [[tls.certificates]] + certFile = "integration/fixtures/https/snitest5.com.cert" + keyFile = "integration/fixtures/https/snitest5.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_file_02.toml b/pkg/provider/file/fixtures/toml/simple_file_02.toml index 2b4feb4a4..947d3d64d 100644 --- a/pkg/provider/file/fixtures/toml/simple_file_02.toml +++ b/pkg/provider/file/fixtures/toml/simple_file_02.toml @@ -1,64 +1,65 @@ [http.routers] -[http.routers."router1"] - service = "application-1" + [http.routers."router1"] + service = "application-1" -[http.routers."router2"] - service = "application-2" + [http.routers."router2"] + service = "application-2" -[http.routers."router3"] - service = "application-3" + [http.routers."router3"] + service = "application-3" + + [http.routers."router4"] + service = "application-4" -[http.routers."router4"] - service = "application-4" [http.services] -[http.services.application-1.loadbalancer] - [[http.services.application-1.loadbalancer.servers]] - url = "http://172.17.0.1:80" + [http.services.application-1.loadBalancer] + [[http.services.application-1.loadBalancer.servers]] + url = "http://172.17.0.1:80" -[http.services.application-2.loadbalancer] - [[http.services.application-2.loadbalancer.servers]] - url = "http://172.17.0.2:80" + [http.services.application-2.loadBalancer] + [[http.services.application-2.loadBalancer.servers]] + url = "http://172.17.0.2:80" -[http.services.application-3.loadbalancer] - [[http.services.application-3.loadbalancer.servers]] - url = "http://172.17.0.3:80" + [http.services.application-3.loadBalancer] + [[http.services.application-3.loadBalancer.servers]] + url = "http://172.17.0.3:80" -[http.services.application-4.loadbalancer] - [[http.services.application-4.loadbalancer.servers]] - url = "http://172.17.0.4:80" + [http.services.application-4.loadBalancer] + [[http.services.application-4.loadBalancer.servers]] + url = "http://172.17.0.4:80" -[http.services.application-5.loadbalancer] - [[http.services.application-5.loadbalancer.servers]] - url = "http://172.17.0.5:80" + [http.services.application-5.loadBalancer] + [[http.services.application-5.loadBalancer.servers]] + url = "http://172.17.0.5:80" -[http.services.application-6.loadbalancer] - [[http.services.application-6.loadbalancer.servers]] - url = "http://172.17.0.6:80" + [http.services.application-6.loadBalancer] + [[http.services.application-6.loadBalancer.servers]] + url = "http://172.17.0.6:80" -[http.services.application-7.loadbalancer] - [[http.services.application-7.loadbalancer.servers]] - url = "http://172.17.0.7:80" + [http.services.application-7.loadBalancer] + [[http.services.application-7.loadBalancer.servers]] + url = "http://172.17.0.7:80" -[http.services.application-8.loadbalancer] - [[http.services.application-8.loadbalancer.servers]] - url = "http://172.17.0.8:80" + [http.services.application-8.loadBalancer] + [[http.services.application-8.loadBalancer.servers]] + url = "http://172.17.0.8:80" -[TLS] +[tls] -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest1.com.cert" + keyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest2.com.cert" + keyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest3.com.cert" + keyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest4.com.cert" + keyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml index dcc1c678d..023ca4109 100644 --- a/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_02.toml @@ -1,40 +1,44 @@ [providers.file] +## dynamic configuration ## + [http.routers] -[http.routers."router1"] - service = "application-1" + [http.routers."router1"] + service = "application-1" + + [http.routers."router2"] + service = "application-2" + -[http.routers."router2"] - service = "application-2" [http.services] -[http.services.application-1.loadbalancer] - [[http.services.application-1.loadbalancer.servers]] - url = "http://172.17.0.1:80" + [http.services.application-1.loadBalancer] + [[http.services.application-1.loadBalancer.servers]] + url = "http://172.17.0.1:80" -[http.services.application-2.loadbalancer] - [[http.services.application-2.loadbalancer.servers]] - url = "http://172.17.0.2:80" + [http.services.application-2.loadBalancer] + [[http.services.application-2.loadBalancer.servers]] + url = "http://172.17.0.2:80" -[http.services.application-3.loadbalancer] - [[http.services.application-3.loadbalancer.servers]] - url = "http://172.17.0.3:80" + [http.services.application-3.loadBalancer] + [[http.services.application-3.loadBalancer.servers]] + url = "http://172.17.0.3:80" -[TLS] +[tls] -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest1.com.cert" + keyFile = "integration/fixtures/https/snitest1.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest2.com.cert" + keyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest3.com.cert" + keyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest4.com.cert" + keyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml b/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml index c07e8601c..c99dc5610 100644 --- a/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml +++ b/pkg/provider/file/fixtures/toml/simple_traefik_file_with_templating.toml @@ -2,41 +2,44 @@ temp="{{ getTag \"test\" }}" [providers.file] +## dynamic configuration ## + [http.routers] - + [http.routers."router1"] - service = "application-1" + service = "application-1" [http.routers."router2"] - service = "application-2" + service = "application-2" + [http.services] -[http.services.application-1.loadbalancer] - [[http.services.application-1.loadbalancer.servers]] - url = "http://172.17.0.1:80" + [http.services.application-1.loadBalancer] + [[http.services.application-1.loadBalancer.servers]] + url = "http://172.17.0.1:80" + + [http.services.application-2.loadBalancer] + [[http.services.application-2.loadBalancer.servers]] + url = "http://172.17.0.2:80" + + [http.services.application-3.loadBalancer] + [[http.services.application-3.loadBalancer.servers]] + url = "http://172.17.0.3:80" -[http.services.application-2.loadbalancer] - [[http.services.application-2.loadbalancer.servers]] - url = "http://172.17.0.2:80" +[tls] -[http.services.application-3.loadbalancer] - [[http.services.application-3.loadbalancer.servers]] - url = "http://172.17.0.3:80" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest1.com.cert" + keyFile = "integration/fixtures/https/snitest1.com.key" -[TLS] +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest2.com.cert" + keyFile = "integration/fixtures/https/snitest2.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest1.com.cert" - KeyFile = "integration/fixtures/https/snitest1.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest3.com.cert" + keyFile = "integration/fixtures/https/snitest3.com.key" -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest2.com.cert" - KeyFile = "integration/fixtures/https/snitest2.com.key" - -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest3.com.cert" - KeyFile = "integration/fixtures/https/snitest3.com.key" - -[[TLS.Certificates]] - CertFile = "integration/fixtures/https/snitest4.com.cert" - KeyFile = "integration/fixtures/https/snitest4.com.key" +[[tls.certificates]] + certFile = "integration/fixtures/https/snitest4.com.cert" + keyFile = "integration/fixtures/https/snitest4.com.key" diff --git a/pkg/provider/file/fixtures/yaml/dir01_file02.yml b/pkg/provider/file/fixtures/yaml/dir01_file02.yml index 65f706ff0..39fff3e75 100644 --- a/pkg/provider/file/fixtures/yaml/dir01_file02.yml +++ b/pkg/provider/file/fixtures/yaml/dir01_file02.yml @@ -1,14 +1,14 @@ http: services: application-1: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.1:80' application-2: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.2:80' application-3: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.3:80' diff --git a/pkg/provider/file/fixtures/yaml/dir01_file03.yml b/pkg/provider/file/fixtures/yaml/dir01_file03.yml index 3bd36db08..bcf46ba67 100644 --- a/pkg/provider/file/fixtures/yaml/dir01_file03.yml +++ b/pkg/provider/file/fixtures/yaml/dir01_file03.yml @@ -1,10 +1,10 @@ tls: certificates: - - certfile: integration/fixtures/https/snitest1.com.cert - keyfile: integration/fixtures/https/snitest1.com.key - - certfile: integration/fixtures/https/snitest2.com.cert - keyfile: integration/fixtures/https/snitest2.com.key - - certfile: integration/fixtures/https/snitest3.com.cert - keyfile: integration/fixtures/https/snitest3.com.key - - certfile: integration/fixtures/https/snitest4.com.cert - keyfile: integration/fixtures/https/snitest4.com.key + - certFile: integration/fixtures/https/snitest1.com.cert + keyFile: integration/fixtures/https/snitest1.com.key + - certFile: integration/fixtures/https/snitest2.com.cert + keyFile: integration/fixtures/https/snitest2.com.key + - certFile: integration/fixtures/https/snitest3.com.cert + keyFile: integration/fixtures/https/snitest3.com.key + - certFile: integration/fixtures/https/snitest4.com.cert + keyFile: integration/fixtures/https/snitest4.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_file_01.yml b/pkg/provider/file/fixtures/yaml/simple_file_01.yml index e1cd1cb5b..286565ff6 100644 --- a/pkg/provider/file/fixtures/yaml/simple_file_01.yml +++ b/pkg/provider/file/fixtures/yaml/simple_file_01.yml @@ -8,39 +8,39 @@ http: service: application-3 services: application-1: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.1:80' application-2: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.2:80' application-3: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.3:80' application-4: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.4:80' application-5: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.5:80' application-6: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.6:80' tls: certificates: - - certfile: integration/fixtures/https/snitest1.com.cert - keyfile: integration/fixtures/https/snitest1.com.key - - certfile: integration/fixtures/https/snitest2.com.cert - keyfile: integration/fixtures/https/snitest2.com.key - - certfile: integration/fixtures/https/snitest3.com.cert - keyfile: integration/fixtures/https/snitest3.com.key - - certfile: integration/fixtures/https/snitest4.com.cert - keyfile: integration/fixtures/https/snitest4.com.key - - certfile: integration/fixtures/https/snitest5.com.cert - keyfile: integration/fixtures/https/snitest5.com.key + - certFile: integration/fixtures/https/snitest1.com.cert + keyFile: integration/fixtures/https/snitest1.com.key + - certFile: integration/fixtures/https/snitest2.com.cert + keyFile: integration/fixtures/https/snitest2.com.key + - certFile: integration/fixtures/https/snitest3.com.cert + keyFile: integration/fixtures/https/snitest3.com.key + - certFile: integration/fixtures/https/snitest4.com.cert + keyFile: integration/fixtures/https/snitest4.com.key + - certFile: integration/fixtures/https/snitest5.com.cert + keyFile: integration/fixtures/https/snitest5.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_file_02.yml b/pkg/provider/file/fixtures/yaml/simple_file_02.yml index 6066f9a57..db147efd4 100644 --- a/pkg/provider/file/fixtures/yaml/simple_file_02.yml +++ b/pkg/provider/file/fixtures/yaml/simple_file_02.yml @@ -10,45 +10,44 @@ http: service: application-4 services: application-1: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.1:80' application-2: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.2:80' application-3: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.3:80' application-4: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.4:80' application-5: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.5:80' application-6: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.6:80' application-7: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.7:80' application-8: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.8:80' - tls: certificates: - - certfile: integration/fixtures/https/snitest1.com.cert - keyfile: integration/fixtures/https/snitest1.com.key - - certfile: integration/fixtures/https/snitest2.com.cert - keyfile: integration/fixtures/https/snitest2.com.key - - certfile: integration/fixtures/https/snitest3.com.cert - keyfile: integration/fixtures/https/snitest3.com.key - - certfile: integration/fixtures/https/snitest4.com.cert - keyfile: integration/fixtures/https/snitest4.com.key \ No newline at end of file + - certFile: integration/fixtures/https/snitest1.com.cert + keyFile: integration/fixtures/https/snitest1.com.key + - certFile: integration/fixtures/https/snitest2.com.cert + keyFile: integration/fixtures/https/snitest2.com.key + - certFile: integration/fixtures/https/snitest3.com.cert + keyFile: integration/fixtures/https/snitest3.com.key + - certFile: integration/fixtures/https/snitest4.com.cert + keyFile: integration/fixtures/https/snitest4.com.key diff --git a/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml b/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml index 4d6f87160..1d9979eb9 100644 --- a/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml +++ b/pkg/provider/file/fixtures/yaml/simple_traefik_file_02.yml @@ -8,25 +8,25 @@ http: service: application-2 services: application-1: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.1:80' application-2: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.2:80' application-3: - loadbalancer: + loadBalancer: servers: - url: 'http://172.17.0.3:80' tls: certificates: - - certfile: integration/fixtures/https/snitest1.com.cert - keyfile: integration/fixtures/https/snitest1.com.key - - certfile: integration/fixtures/https/snitest2.com.cert - keyfile: integration/fixtures/https/snitest2.com.key - - certfile: integration/fixtures/https/snitest3.com.cert - keyfile: integration/fixtures/https/snitest3.com.key - - certfile: integration/fixtures/https/snitest4.com.cert - keyfile: integration/fixtures/https/snitest4.com.key \ No newline at end of file + - certFile: integration/fixtures/https/snitest1.com.cert + keyFile: integration/fixtures/https/snitest1.com.key + - certFile: integration/fixtures/https/snitest2.com.cert + keyFile: integration/fixtures/https/snitest2.com.key + - certFile: integration/fixtures/https/snitest3.com.cert + keyFile: integration/fixtures/https/snitest3.com.key + - certFile: integration/fixtures/https/snitest4.com.cert + keyFile: integration/fixtures/https/snitest4.com.key diff --git a/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml b/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml index 8c2d94c03..36cf2e202 100644 --- a/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml +++ b/pkg/provider/file/fixtures/yaml/template_in_directory_file02.yml @@ -2,7 +2,7 @@ http: services: {{ range $i, $e := until 20 }} application-{{ $e }}: - loadbalancer: + loadBalancer: servers: - url: 'http://127.0.0.1' {{ end }} diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index 07c3e7610..8a4c277e1 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -31,13 +31,13 @@ const ( // Provider holds configurations of the provider. type Provider struct { - Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)."` - Token string `description:"Kubernetes bearer token (not needed for in-cluster client)."` - CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)."` - DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers." export:"true"` - Namespaces []string `description:"Kubernetes namespaces." export:"true"` - LabelSelector string `description:"Kubernetes label selector to use." export:"true"` - IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." export:"true"` + Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Token string `description:"Kubernetes bearer token (not needed for in-cluster client)." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty"` + CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)." json:"certAuthFilePath,omitempty" toml:"certAuthFilePath,omitempty" yaml:"certAuthFilePath,omitempty"` + DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers." json:"disablePassHostHeaders,omitempty" toml:"disablePassHostHeaders,omitempty" yaml:"disablePassHostHeaders,omitempty" export:"true"` + Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"` + LabelSelector string `description:"Kubernetes label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"` + IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"` lastConfiguration safe.Safe } diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index 7f4b24c08..16bfc30d1 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -32,22 +32,22 @@ const ( // Provider holds configurations of the provider. type Provider struct { - Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)."` - Token string `description:"Kubernetes bearer token (not needed for in-cluster client)."` - CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)."` - DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers." export:"true"` - Namespaces []string `description:"Kubernetes namespaces." export:"true"` - LabelSelector string `description:"Kubernetes Ingress label selector to use." export:"true"` - IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." export:"true"` - IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint."` + Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Token string `description:"Kubernetes bearer token (not needed for in-cluster client)." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty"` + CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)." json:"certAuthFilePath,omitempty" toml:"certAuthFilePath,omitempty" yaml:"certAuthFilePath,omitempty"` + DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers." json:"disablePassHostHeaders,omitempty" toml:"disablePassHostHeaders,omitempty" yaml:"disablePassHostHeaders,omitempty" export:"true"` + Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"` + LabelSelector string `description:"Kubernetes Ingress label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"` + IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"` + IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint." json:"ingressEndpoint,omitempty" toml:"ingressEndpoint,omitempty" yaml:"ingressEndpoint,omitempty"` lastConfiguration safe.Safe } // EndpointIngress holds the endpoint information for the Kubernetes provider type EndpointIngress struct { - IP string `description:"IP used for Kubernetes Ingress endpoints."` - Hostname string `description:"Hostname used for Kubernetes Ingress endpoints."` - PublishedService string `description:"Published Kubernetes Service to copy status from."` + IP string `description:"IP used for Kubernetes Ingress endpoints." json:"ip,omitempty" toml:"ip,omitempty" yaml:"ip,omitempty"` + Hostname string `description:"Hostname used for Kubernetes Ingress endpoints." json:"hostname,omitempty" toml:"hostname,omitempty" yaml:"hostname,omitempty"` + PublishedService string `description:"Published Kubernetes Service to copy status from." json:"publishedService,omitempty" toml:"publishedService,omitempty" yaml:"publishedService,omitempty"` } func (p *Provider) newK8sClient(ctx context.Context, ingressLabelSelector string) (*clientWrapper, error) { diff --git a/pkg/provider/marathon/marathon.go b/pkg/provider/marathon/marathon.go index 5fb64ccd7..b08d7f425 100644 --- a/pkg/provider/marathon/marathon.go +++ b/pkg/provider/marathon/marathon.go @@ -45,21 +45,21 @@ var _ provider.Provider = (*Provider)(nil) // Provider holds configuration of the provider. type Provider struct { - Constraints string `description:"Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application." export:"true"` - Trace bool `description:"Display additional provider logs." export:"true"` - Watch bool `description:"Watch provider." export:"true"` - Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon." export:"true"` - DefaultRule string `description:"Default rule."` - ExposedByDefault bool `description:"Expose Marathon apps by default." export:"true"` - DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header." export:"true"` - TLS *types.ClientTLS `description:"Enable TLS support." export:"true"` - DialerTimeout types.Duration `description:"Set a dialer timeout for Marathon." export:"true"` - ResponseHeaderTimeout types.Duration `description:"Set a response header timeout for Marathon." export:"true"` - TLSHandshakeTimeout types.Duration `description:"Set a TLS handshake timeout for Marathon." export:"true"` - KeepAlive types.Duration `description:"Set a TCP Keep Alive time." export:"true"` - ForceTaskHostname bool `description:"Force to use the task's hostname." export:"true"` - Basic *Basic `description:"Enable basic authentication." export:"true"` - RespectReadinessChecks bool `description:"Filter out tasks with non-successful readiness checks during deployments." export:"true"` + Constraints string `description:"Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` + Trace bool `description:"Display additional provider logs." json:"trace,omitempty" toml:"trace,omitempty" yaml:"trace,omitempty" export:"true"` + Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` + Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty" export:"true"` + DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` + ExposedByDefault bool `description:"Expose Marathon apps by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` + DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header." json:"dcosToken,omitempty" toml:"dcosToken,omitempty" yaml:"dcosToken,omitempty" export:"true"` + TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` + DialerTimeout types.Duration `description:"Set a dialer timeout for Marathon." json:"dialerTimeout,omitempty" toml:"dialerTimeout,omitempty" yaml:"dialerTimeout,omitempty" export:"true"` + ResponseHeaderTimeout types.Duration `description:"Set a response header timeout for Marathon." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"` + TLSHandshakeTimeout types.Duration `description:"Set a TLS handshake timeout for Marathon." json:"tlsHandshakeTimeout,omitempty" toml:"tlsHandshakeTimeout,omitempty" yaml:"tlsHandshakeTimeout,omitempty" export:"true"` + KeepAlive types.Duration `description:"Set a TCP Keep Alive time." json:"keepAlive,omitempty" toml:"keepAlive,omitempty" yaml:"keepAlive,omitempty" export:"true"` + ForceTaskHostname bool `description:"Force to use the task's hostname." json:"forceTaskHostname,omitempty" toml:"forceTaskHostname,omitempty" yaml:"forceTaskHostname,omitempty" export:"true"` + Basic *Basic `description:"Enable basic authentication." json:"basic,omitempty" toml:"basic,omitempty" yaml:"basic,omitempty" export:"true"` + RespectReadinessChecks bool `description:"Filter out tasks with non-successful readiness checks during deployments." json:"respectReadinessChecks,omitempty" toml:"respectReadinessChecks,omitempty" yaml:"respectReadinessChecks,omitempty" export:"true"` readyChecker *readinessChecker marathonClient marathon.Marathon defaultRuleTpl *template.Template @@ -79,8 +79,8 @@ func (p *Provider) SetDefaults() { // Basic holds basic authentication specific configurations type Basic struct { - HTTPBasicAuthUser string `description:"Basic authentication User."` - HTTPBasicPassword string `description:"Basic authentication Password."` + HTTPBasicAuthUser string `description:"Basic authentication User." json:"httpBasicAuthUser,omitempty" toml:"httpBasicAuthUser,omitempty" yaml:"httpBasicAuthUser,omitempty"` + HTTPBasicPassword string `description:"Basic authentication Password." json:"httpBasicPassword,omitempty" toml:"httpBasicPassword,omitempty" yaml:"httpBasicPassword,omitempty"` } // Init the provider diff --git a/pkg/provider/rancher/config_test.go b/pkg/provider/rancher/config_test.go index 0adff55f1..3cdf36f6e 100644 --- a/pkg/provider/rancher/config_test.go +++ b/pkg/provider/rancher/config_test.go @@ -496,7 +496,6 @@ func Test_buildConfiguration(t *testing.T) { }, }, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{ Routers: map[string]*config.TCPRouter{ "foo": { diff --git a/pkg/provider/rancher/rancher.go b/pkg/provider/rancher/rancher.go index 76a3f9028..9d12ac6bc 100644 --- a/pkg/provider/rancher/rancher.go +++ b/pkg/provider/rancher/rancher.go @@ -40,14 +40,14 @@ var _ provider.Provider = (*Provider)(nil) // Provider holds configurations of the provider. type Provider struct { - Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." export:"true"` - Watch bool `description:"Watch provider." export:"true"` - DefaultRule string `description:"Default rule."` - ExposedByDefault bool `description:"Expose containers by default." export:"true"` - EnableServiceHealthFilter bool `description:"Filter services with unhealthy states and inactive states." export:"true"` - RefreshSeconds int `description:"Defines the polling interval in seconds." export:"true"` - IntervalPoll bool `description:"Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate)."` - Prefix string `description:"Prefix used for accessing the Rancher metadata service."` + Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` + Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` + DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` + ExposedByDefault bool `description:"Expose containers by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` + EnableServiceHealthFilter bool `description:"Filter services with unhealthy states and inactive states." json:"enableServiceHealthFilter,omitempty" toml:"enableServiceHealthFilter,omitempty" yaml:"enableServiceHealthFilter,omitempty" export:"true"` + RefreshSeconds int `description:"Defines the polling interval in seconds." json:"refreshSeconds,omitempty" toml:"refreshSeconds,omitempty" yaml:"refreshSeconds,omitempty" export:"true"` + IntervalPoll bool `description:"Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate)." json:"intervalPoll,omitempty" toml:"intervalPoll,omitempty" yaml:"intervalPoll,omitempty"` + Prefix string `description:"Prefix used for accessing the Rancher metadata service." json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty"` defaultRuleTpl *template.Template } diff --git a/pkg/provider/rest/rest.go b/pkg/provider/rest/rest.go index 02aa10c5f..b7cc8e065 100644 --- a/pkg/provider/rest/rest.go +++ b/pkg/provider/rest/rest.go @@ -19,7 +19,7 @@ var _ provider.Provider = (*Provider)(nil) // Provider is a provider.Provider implementation that provides a Rest API. type Provider struct { configurationChan chan<- config.Message - EntryPoint string `description:"EntryPoint." export:"true"` + EntryPoint string `description:"EntryPoint." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/server/server.go b/pkg/server/server.go index 093ee6e21..c84f1c84a 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -306,11 +306,11 @@ func registerMetricClients(metricsConfig *types.Metrics) metrics.Registry { } } - if metricsConfig.Datadog != nil { + if metricsConfig.DataDog != nil { ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "datadog")) - registries = append(registries, metrics.RegisterDatadog(ctx, metricsConfig.Datadog)) + registries = append(registries, metrics.RegisterDatadog(ctx, metricsConfig.DataDog)) log.FromContext(ctx).Debugf("Configured DataDog metrics: pushing to %s once every %s", - metricsConfig.Datadog.Address, metricsConfig.Datadog.PushInterval) + metricsConfig.DataDog.Address, metricsConfig.DataDog.PushInterval) } if metricsConfig.StatsD != nil { diff --git a/pkg/tls/certificate.go b/pkg/tls/certificate.go index 08d0d80a6..4b59fee49 100644 --- a/pkg/tls/certificate.go +++ b/pkg/tls/certificate.go @@ -57,8 +57,8 @@ var ( // Certificate holds a SSL cert/key pair // Certs and Key could be either a file path, or the file content itself type Certificate struct { - CertFile FileOrContent - KeyFile FileOrContent + CertFile FileOrContent `json:"certFile,omitempty" toml:"certFile,omitempty" yaml:"certFile,omitempty"` + KeyFile FileOrContent `json:"keyFile,omitempty" toml:"keyFile,omitempty" yaml:"keyFile,omitempty"` } // Certificates defines traefik certificates type diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index e509e4b10..8b855fcba 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -5,25 +5,25 @@ const certificateHeader = "-----BEGIN CERTIFICATE-----\n" // ClientCA defines traefik CA files for a entryPoint // and it indicates if they are mandatory or have just to be analyzed if provided. type ClientCA struct { - Files []FileOrContent - Optional bool + Files []FileOrContent `json:"files,omitempty" toml:"files,omitempty" yaml:"files,omitempty"` + Optional bool `json:"optional,omitempty" toml:"optional,omitempty" yaml:"optional,omitempty"` } // Options configures TLS for an entry point type Options struct { - MinVersion string `export:"true"` - CipherSuites []string - ClientCA ClientCA - SniStrict bool `export:"true"` + MinVersion string `json:"minVersion,omitempty" toml:"minVersion,omitempty" yaml:"minVersion,omitempty" export:"true"` + CipherSuites []string `json:"cipherSuites,omitempty" toml:"cipherSuites,omitempty" yaml:"cipherSuites,omitempty"` + ClientCA ClientCA `json:"clientCA,omitempty" toml:"clientCA,omitempty" yaml:"clientCA,omitempty"` + SniStrict bool `json:"sniStrict,omitempty" toml:"sniStrict,omitempty" yaml:"sniStrict,omitempty" export:"true"` } // Store holds the options for a given Store type Store struct { - DefaultCertificate *Certificate + DefaultCertificate *Certificate `json:"defaultCertificate,omitempty" toml:"defaultCertificate,omitempty" yaml:"defaultCertificate,omitempty"` } // CertAndStores allows mapping a TLS certificate to a list of entry points. type CertAndStores struct { Certificate `yaml:",inline"` - Stores []string + Stores []string `json:"stores,omitempty" toml:"stores,omitempty" yaml:"stores,omitempty"` } diff --git a/pkg/tracing/datadog/datadog.go b/pkg/tracing/datadog/datadog.go index 70af78cdd..466df2ca9 100644 --- a/pkg/tracing/datadog/datadog.go +++ b/pkg/tracing/datadog/datadog.go @@ -15,14 +15,14 @@ const Name = "datadog" // Config provides configuration settings for a datadog tracer type Config struct { - LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used." export:"false"` - GlobalTag string `description:"Key:Value tag to be set on all the spans." export:"true"` - Debug bool `description:"Enable DataDog debug." export:"true"` - PrioritySampling bool `description:"Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled."` - TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." export:"true"` - ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." export:"true"` - SamplingPriorityHeaderName string `description:"Specifies the header name that will be used to store the sampling priority." export:"true"` - BagagePrefixHeaderName string `description:"Specifies the header name prefix that will be used to store baggage items in a map." export:"true"` + LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used." json:"localAgentHostPort,omitempty" toml:"localAgentHostPort,omitempty" yaml:"localAgentHostPort,omitempty"` + GlobalTag string `description:"Key:Value tag to be set on all the spans." json:"globalTag,omitempty" toml:"globalTag,omitempty" yaml:"globalTag,omitempty" export:"true"` + Debug bool `description:"Enable DataDog debug." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"` + PrioritySampling bool `description:"Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled." json:"prioritySampling,omitempty" toml:"prioritySampling,omitempty" yaml:"prioritySampling,omitempty"` + TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." json:"traceIDHeaderName,omitempty" toml:"traceIDHeaderName,omitempty" yaml:"traceIDHeaderName,omitempty" export:"true"` + ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." json:"parentIDHeaderName,omitempty" toml:"parentIDHeaderName,omitempty" yaml:"parentIDHeaderName,omitempty" export:"true"` + SamplingPriorityHeaderName string `description:"Specifies the header name that will be used to store the sampling priority." json:"samplingPriorityHeaderName,omitempty" toml:"samplingPriorityHeaderName,omitempty" yaml:"samplingPriorityHeaderName,omitempty" export:"true"` + BagagePrefixHeaderName string `description:"Specifies the header name prefix that will be used to store baggage items in a map." json:"bagagePrefixHeaderName,omitempty" toml:"bagagePrefixHeaderName,omitempty" yaml:"bagagePrefixHeaderName,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/tracing/haystack/haystack.go b/pkg/tracing/haystack/haystack.go index 58a65be02..19038fff9 100644 --- a/pkg/tracing/haystack/haystack.go +++ b/pkg/tracing/haystack/haystack.go @@ -15,13 +15,13 @@ const Name = "haystack" // Config provides configuration settings for a haystack tracer type Config struct { - LocalAgentHost string `description:"Set haystack-agent's host that the reporter will used." export:"false"` - LocalAgentPort int `description:"Set haystack-agent's port that the reporter will used." export:"false"` - GlobalTag string `description:"Key:Value tag to be set on all the spans." export:"true"` - TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." export:"true"` - ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." export:"true"` - SpanIDHeaderName string `description:"Specifies the header name that will be used to store the span ID." export:"true"` - BaggagePrefixHeaderName string `description:"Specifies the header name prefix that will be used to store baggage items in a map." export:"true"` + LocalAgentHost string `description:"Set haystack-agent's host that the reporter will used." json:"localAgentHost,omitempty" toml:"localAgentHost,omitempty" yaml:"localAgentHost,omitempty"` + LocalAgentPort int `description:"Set haystack-agent's port that the reporter will used." json:"localAgentPort,omitempty" toml:"localAgentPort,omitempty" yaml:"localAgentPort,omitempty"` + GlobalTag string `description:"Key:Value tag to be set on all the spans." json:"globalTag,omitempty" toml:"globalTag,omitempty" yaml:"globalTag,omitempty" export:"true"` + TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." json:"traceIDHeaderName,omitempty" toml:"traceIDHeaderName,omitempty" yaml:"traceIDHeaderName,omitempty" export:"true"` + ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." json:"parentIDHeaderName,omitempty" toml:"parentIDHeaderName,omitempty" yaml:"parentIDHeaderName,omitempty" export:"true"` + SpanIDHeaderName string `description:"Specifies the header name that will be used to store the span ID." json:"spanIDHeaderName,omitempty" toml:"spanIDHeaderName,omitempty" yaml:"spanIDHeaderName,omitempty" export:"true"` + BaggagePrefixHeaderName string `description:"Specifies the header name prefix that will be used to store baggage items in a map." json:"baggagePrefixHeaderName,omitempty" toml:"baggagePrefixHeaderName,omitempty" yaml:"baggagePrefixHeaderName,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/tracing/instana/instana.go b/pkg/tracing/instana/instana.go index da66ea916..34df22f16 100644 --- a/pkg/tracing/instana/instana.go +++ b/pkg/tracing/instana/instana.go @@ -13,9 +13,9 @@ const Name = "instana" // Config provides configuration settings for a instana tracer type Config struct { - LocalAgentHost string `description:"Set instana-agent's host that the reporter will used." export:"false"` - LocalAgentPort int `description:"Set instana-agent's port that the reporter will used." export:"false"` - LogLevel string `description:"Set instana-agent's log level. ('error','warn','info','debug')" export:"false"` + LocalAgentHost string `description:"Set instana-agent's host that the reporter will used." json:"localAgentHost,omitempty" toml:"localAgentHost,omitempty" yaml:"localAgentHost,omitempty"` + LocalAgentPort int `description:"Set instana-agent's port that the reporter will used." json:"localAgentPort,omitempty" toml:"localAgentPort,omitempty" yaml:"localAgentPort,omitempty"` + LogLevel string `description:"Set instana-agent's log level. ('error','warn','info','debug')" json:"logLevel,omitempty" toml:"logLevel,omitempty" yaml:"logLevel,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/tracing/jaeger/jaeger.go b/pkg/tracing/jaeger/jaeger.go index 1aaf61ba5..458c7444a 100644 --- a/pkg/tracing/jaeger/jaeger.go +++ b/pkg/tracing/jaeger/jaeger.go @@ -18,13 +18,13 @@ const Name = "jaeger" // Config provides configuration settings for a jaeger tracer type Config struct { - SamplingServerURL string `description:"Set the sampling server url." export:"false"` - SamplingType string `description:"Set the sampling type." export:"true"` - SamplingParam float64 `description:"Set the sampling parameter." export:"true"` - LocalAgentHostPort string `description:"Set jaeger-agent's host:port that the reporter will used." export:"false"` - Gen128Bit bool `description:"Generate 128 bit span IDs." export:"true"` - Propagation string `description:"Which propgation format to use (jaeger/b3)." export:"true"` - TraceContextHeaderName string `description:"Set the header to use for the trace-id." export:"true"` + SamplingServerURL string `description:"Set the sampling server url." json:"samplingServerURL,omitempty" toml:"samplingServerURL,omitempty" yaml:"samplingServerURL,omitempty"` + SamplingType string `description:"Set the sampling type." json:"samplingType,omitempty" toml:"samplingType,omitempty" yaml:"samplingType,omitempty" export:"true"` + SamplingParam float64 `description:"Set the sampling parameter." json:"samplingParam,omitempty" toml:"samplingParam,omitempty" yaml:"samplingParam,omitempty" export:"true"` + LocalAgentHostPort string `description:"Set jaeger-agent's host:port that the reporter will used." json:"localAgentHostPort,omitempty" toml:"localAgentHostPort,omitempty" yaml:"localAgentHostPort,omitempty"` + Gen128Bit bool `description:"Generate 128 bit span IDs." json:"gen128Bit,omitempty" toml:"gen128Bit,omitempty" yaml:"gen128Bit,omitempty" export:"true"` + Propagation string `description:"Which propgation format to use (jaeger/b3)." json:"propagation,omitempty" toml:"propagation,omitempty" yaml:"propagation,omitempty" export:"true"` + TraceContextHeaderName string `description:"Set the header to use for the trace-id." json:"traceContextHeaderName,omitempty" toml:"traceContextHeaderName,omitempty" yaml:"traceContextHeaderName,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/tracing/zipkin/zipkin.go b/pkg/tracing/zipkin/zipkin.go index e2bc34c0f..3d246be9f 100644 --- a/pkg/tracing/zipkin/zipkin.go +++ b/pkg/tracing/zipkin/zipkin.go @@ -14,11 +14,11 @@ const Name = "zipkin" // Config provides configuration settings for a zipkin tracer. type Config struct { - HTTPEndpoint string `description:"HTTP Endpoint to report traces to." export:"false"` - SameSpan bool `description:"Use Zipkin SameSpan RPC style traces." export:"true"` - ID128Bit bool `description:"Use Zipkin 128 bit root span IDs." export:"true"` - Debug bool `description:"Enable Zipkin debug." export:"true"` - SampleRate float64 `description:"The rate between 0.0 and 1.0 of requests to trace." export:"true"` + HTTPEndpoint string `description:"HTTP Endpoint to report traces to." json:"httpEndpoint,omitempty" toml:"httpEndpoint,omitempty" yaml:"httpEndpoint,omitempty"` + SameSpan bool `description:"Use Zipkin SameSpan RPC style traces." json:"sameSpan,omitempty" toml:"sameSpan,omitempty" yaml:"sameSpan,omitempty" export:"true"` + ID128Bit bool `description:"Use Zipkin 128 bit root span IDs." json:"id128Bit,omitempty" toml:"id128Bit,omitempty" yaml:"id128Bit,omitempty" export:"true"` + Debug bool `description:"Enable Zipkin debug." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"` + SampleRate float64 `description:"The rate between 0.0 and 1.0 of requests to trace." json:"sampleRate,omitempty" toml:"sampleRate,omitempty" yaml:"sampleRate,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/types/domains.go b/pkg/types/domains.go index 70b3a3904..0ebda7f59 100644 --- a/pkg/types/domains.go +++ b/pkg/types/domains.go @@ -7,8 +7,8 @@ import ( // Domain holds a domain name with SANs. type Domain struct { - Main string `description:"Default subject name."` - SANs []string `description:"Subject alternative names."` + Main string `description:"Default subject name." json:"main,omitempty" toml:"main,omitempty" yaml:"main,omitempty"` + SANs []string `description:"Subject alternative names." json:"sans,omitempty" toml:"sans,omitempty" yaml:"sans,omitempty"` } // ToStrArray convert a domain into an array of strings. diff --git a/pkg/types/host_resolver.go b/pkg/types/host_resolver.go index 0e5ad3b18..081fb7b34 100644 --- a/pkg/types/host_resolver.go +++ b/pkg/types/host_resolver.go @@ -2,9 +2,9 @@ package types // HostResolverConfig contain configuration for CNAME Flattening. type HostResolverConfig struct { - CnameFlattening bool `description:"A flag to enable/disable CNAME flattening" export:"true"` - ResolvConfig string `description:"resolv.conf used for DNS resolving" export:"true"` - ResolvDepth int `description:"The maximal depth of DNS recursive resolving" export:"true"` + CnameFlattening bool `description:"A flag to enable/disable CNAME flattening" json:"cnameFlattening,omitempty" toml:"cnameFlattening,omitempty" yaml:"cnameFlattening,omitempty" export:"true"` + ResolvConfig string `description:"resolv.conf used for DNS resolving" json:"resolvConfig,omitempty" toml:"resolvConfig,omitempty" yaml:"resolvConfig,omitempty" export:"true"` + ResolvDepth int `description:"The maximal depth of DNS recursive resolving" json:"resolvDepth,omitempty" toml:"resolvDepth,omitempty" yaml:"resolvDepth,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/types/logs.go b/pkg/types/logs.go index 716decf01..7c9f82906 100644 --- a/pkg/types/logs.go +++ b/pkg/types/logs.go @@ -19,9 +19,9 @@ const ( // TraefikLog holds the configuration settings for the traefik logger. type TraefikLog struct { - Level string `description:"Log level set to traefik logs." export:"true"` - FilePath string `json:"file,omitempty" description:"Traefik log file path. Stdout is used when omitted or empty."` - Format string `json:"format,omitempty" description:"Traefik log format: json | common"` + Level string `description:"Log level set to traefik logs." json:"level,omitempty" toml:"level,omitempty" yaml:"level,omitempty" export:"true"` + FilePath string `description:"Traefik log file path. Stdout is used when omitted or empty." json:"filePath,omitempty" toml:"filePath,omitempty" yaml:"filePath,omitempty"` + Format string `description:"Traefik log format: json | common" json:"format,omitempty" toml:"format,omitempty" yaml:"format,omitempty"` } // SetDefaults sets the default values. @@ -32,11 +32,11 @@ func (l *TraefikLog) SetDefaults() { // AccessLog holds the configuration settings for the access logger (middlewares/accesslog). type AccessLog struct { - FilePath string `json:"file,omitempty" description:"Access log file path. Stdout is used when omitted or empty." export:"true"` - Format string `json:"format,omitempty" description:"Access log format: json | common" export:"true"` - Filters *AccessLogFilters `json:"filters,omitempty" description:"Access log filters, used to keep only specific access logs." export:"true"` - Fields *AccessLogFields `json:"fields,omitempty" description:"AccessLogFields." export:"true"` - BufferingSize int64 `json:"bufferingSize,omitempty" description:"Number of access log lines to process in a buffered way." export:"true"` + FilePath string `description:"Access log file path. Stdout is used when omitted or empty." json:"filePath,omitempty" toml:"filePath,omitempty" yaml:"filePath,omitempty" export:"true"` + Format string `description:"Access log format: json | common" json:"format,omitempty" toml:"format,omitempty" yaml:"format,omitempty" export:"true"` + Filters *AccessLogFilters `description:"Access log filters, used to keep only specific access logs." json:"filters,omitempty" toml:"filters,omitempty" yaml:"filters,omitempty" export:"true"` + Fields *AccessLogFields `description:"AccessLogFields." json:"fields,omitempty" toml:"fields,omitempty" yaml:"fields,omitempty" export:"true"` + BufferingSize int64 `description:"Number of access log lines to process in a buffered way." json:"bufferingSize,omitempty" toml:"bufferingSize,omitempty" yaml:"bufferingSize,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -50,22 +50,22 @@ func (l *AccessLog) SetDefaults() { // AccessLogFilters holds filters configuration type AccessLogFilters struct { - StatusCodes []string `json:"statusCodes,omitempty" description:"Keep access logs with status codes in the specified range." export:"true"` - RetryAttempts bool `json:"retryAttempts,omitempty" description:"Keep access logs when at least one retry happened." export:"true"` - MinDuration Duration `json:"duration,omitempty" description:"Keep access logs when request took longer than the specified duration." export:"true"` + StatusCodes []string `description:"Keep access logs with status codes in the specified range." json:"statusCodes,omitempty" toml:"statusCodes,omitempty" yaml:"statusCodes,omitempty" export:"true"` + RetryAttempts bool `description:"Keep access logs when at least one retry happened." json:"retryAttempts,omitempty" toml:"retryAttempts,omitempty" yaml:"retryAttempts,omitempty" export:"true"` + MinDuration Duration `description:"Keep access logs when request took longer than the specified duration." json:"minDuration,omitempty" toml:"minDuration,omitempty" yaml:"minDuration,omitempty" export:"true"` } // FieldHeaders holds configuration for access log headers type FieldHeaders struct { - DefaultMode string `json:"defaultMode,omitempty" description:"Default mode for fields: keep | drop | redact" export:"true"` - Names map[string]string `json:"names,omitempty" description:"Override mode for headers" export:"true"` + DefaultMode string `description:"Default mode for fields: keep | drop | redact" json:"defaultMode,omitempty" toml:"defaultMode,omitempty" yaml:"defaultMode,omitempty" export:"true"` + Names map[string]string `description:"Override mode for headers" json:"names,omitempty" toml:"names,omitempty" yaml:"names,omitempty" export:"true"` } // AccessLogFields holds configuration for access log fields type AccessLogFields struct { - DefaultMode string `json:"defaultMode,omitempty" description:"Default mode for fields: keep | drop" export:"true"` - Names map[string]string `json:"names,omitempty" description:"Override mode for fields" export:"true"` - Headers *FieldHeaders `json:"headers,omitempty" description:"Headers to keep, drop or redact" export:"true"` + DefaultMode string `description:"Default mode for fields: keep | drop" json:"defaultMode,omitempty" toml:"defaultMode,omitempty" yaml:"defaultMode,omitempty" export:"true"` + Names map[string]string `json:"names,omitempty" description:"Override mode for fields" json:"names,omitempty" toml:"names,omitempty" yaml:"names,omitempty" export:"true"` + Headers *FieldHeaders `description:"Headers to keep, drop or redact" json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/types/metrics.go b/pkg/types/metrics.go index 9a1a763b2..2d148ce93 100644 --- a/pkg/types/metrics.go +++ b/pkg/types/metrics.go @@ -6,17 +6,17 @@ import ( // Metrics provides options to expose and send Traefik metrics to different third party monitoring systems type Metrics struct { - Prometheus *Prometheus `description:"Prometheus metrics exporter type." export:"true" label:"allowEmpty"` - Datadog *Datadog `description:"DataDog metrics exporter type." export:"true" label:"allowEmpty"` - StatsD *Statsd `description:"StatsD metrics exporter type." export:"true" label:"allowEmpty"` - InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." label:"allowEmpty"` + Prometheus *Prometheus `description:"Prometheus metrics exporter type." json:"prometheus,omitempty" toml:"prometheus,omitempty" yaml:"prometheus,omitempty" export:"true" label:"allowEmpty"` + DataDog *DataDog `description:"DataDog metrics exporter type." json:"dataDog,omitempty" toml:"dataDog,omitempty" yaml:"dataDog,omitempty" export:"true" label:"allowEmpty"` + StatsD *Statsd `description:"StatsD metrics exporter type." json:"statsD,omitempty" toml:"statsD,omitempty" yaml:"statsD,omitempty" export:"true" label:"allowEmpty"` + InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." json:"influxDB,omitempty" toml:"influxDB,omitempty" yaml:"influxDB,omitempty" label:"allowEmpty"` } // Prometheus can contain specific configuration used by the Prometheus Metrics exporter type Prometheus struct { - Buckets []float64 `description:"Buckets for latency metrics." export:"true"` - EntryPoint string `description:"EntryPoint." export:"true"` - Middlewares []string `description:"Middlewares." export:"true"` + Buckets []float64 `description:"Buckets for latency metrics." json:"buckets,omitempty" toml:"buckets,omitempty" yaml:"buckets,omitempty" export:"true"` + EntryPoint string `description:"EntryPoint." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"` + Middlewares []string `description:"Middlewares." json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -25,22 +25,22 @@ func (p *Prometheus) SetDefaults() { p.EntryPoint = "traefik" } -// Datadog contains address and metrics pushing interval configuration -type Datadog struct { - Address string `description:"DataDog's address."` - PushInterval Duration `description:"DataDog push interval." export:"true"` +// DataDog contains address and metrics pushing interval configuration +type DataDog struct { + Address string `description:"DataDog's address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` + PushInterval Duration `description:"DataDog push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"` } // SetDefaults sets the default values. -func (d *Datadog) SetDefaults() { +func (d *DataDog) SetDefaults() { d.Address = "localhost:8125" d.PushInterval = Duration(10 * time.Second) } // Statsd contains address and metrics pushing interval configuration type Statsd struct { - Address string `description:"StatsD address."` - PushInterval Duration `description:"StatsD push interval." export:"true"` + Address string `description:"StatsD address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` + PushInterval Duration `description:"StatsD push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -51,13 +51,13 @@ func (s *Statsd) SetDefaults() { // InfluxDB contains address, login and metrics pushing interval configuration type InfluxDB struct { - Address string `description:"InfluxDB address."` - Protocol string `description:"InfluxDB address protocol (udp or http)."` - PushInterval Duration `description:"InfluxDB push interval." export:"true"` - Database string `description:"InfluxDB database used when protocol is http." export:"true"` - RetentionPolicy string `description:"InfluxDB retention policy used when protocol is http." export:"true"` - Username string `description:"InfluxDB username (only with http)." export:"true"` - Password string `description:"InfluxDB password (only with http)." export:"true"` + Address string `description:"InfluxDB address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` + Protocol string `description:"InfluxDB address protocol (udp or http)." json:"protocol,omitempty" toml:"protocol,omitempty" yaml:"protocol,omitempty"` + PushInterval Duration `description:"InfluxDB push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"` + Database string `description:"InfluxDB database used when protocol is http." json:"database,omitempty" toml:"database,omitempty" yaml:"database,omitempty" export:"true"` + RetentionPolicy string `description:"InfluxDB retention policy used when protocol is http." json:"retentionPolicy,omitempty" toml:"retentionPolicy,omitempty" yaml:"retentionPolicy,omitempty" export:"true"` + Username string `description:"InfluxDB username (only with http)." json:"username,omitempty" toml:"username,omitempty" yaml:"username,omitempty" export:"true"` + Password string `description:"InfluxDB password (only with http)." json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -69,7 +69,7 @@ func (i *InfluxDB) SetDefaults() { // Statistics provides options for monitoring request and response stats type Statistics struct { - RecentErrors int `description:"Number of recent errors logged." export:"true"` + RecentErrors int `description:"Number of recent errors logged." json:"recentErrors,omitempty" toml:"recentErrors,omitempty" yaml:"recentErrors,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/types/tls.go b/pkg/types/tls.go index 4f1c66ff7..492225003 100644 --- a/pkg/types/tls.go +++ b/pkg/types/tls.go @@ -14,11 +14,11 @@ import ( // ClientTLS holds TLS specific configurations as client // CA, Cert and Key can be either path or file contents type ClientTLS struct { - CA string `description:"TLS CA" json:"ca,omitempty"` - CAOptional bool `description:"TLS CA.Optional" json:"caOptional,omitempty"` - Cert string `description:"TLS cert" json:"cert,omitempty"` - Key string `description:"TLS key" json:"key,omitempty"` - InsecureSkipVerify bool `description:"TLS insecure skip verify" json:"insecureSkipVerify,omitempty"` + CA string `description:"TLS CA" json:"ca,omitempty" toml:"ca,omitempty" yaml:"ca,omitempty"` + CAOptional bool `description:"TLS CA.Optional" json:"caOptional,omitempty" toml:"caOptional,omitempty" yaml:"caOptional,omitempty"` + Cert string `description:"TLS cert" json:"cert,omitempty" toml:"cert,omitempty" yaml:"cert,omitempty"` + Key string `description:"TLS key" json:"key,omitempty" toml:"key,omitempty" yaml:"key,omitempty"` + InsecureSkipVerify bool `description:"TLS insecure skip verify" json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty"` } // CreateTLSConfig creates a TLS config from ClientTLS structures diff --git a/traefik.sample.toml b/traefik.sample.toml index 1bff7753d..57c90e9ac 100644 --- a/traefik.sample.toml +++ b/traefik.sample.toml @@ -21,8 +21,8 @@ # Optional # Default: [entryPoints] - [entryPoints.web] - address = ":80" + [entryPoints.web] + address = ":80" ################################################################ # Traefik logs configuration From 4360ca14c1cf7ff6951babe61e4f89c435df3911 Mon Sep 17 00:00:00 2001 From: Julien Salleyron Date: Mon, 1 Jul 2019 15:08:04 +0200 Subject: [PATCH 09/11] Use h2c from x/net to handle h2c requests Co-authored-by: Mathieu Lonjaret --- Gopkg.lock | 8 +- pkg/server/server_entrypoint_tcp.go | 24 +- vendor/golang.org/x/net/bpf/constants.go | 24 +- vendor/golang.org/x/net/bpf/instructions.go | 194 +- vendor/golang.org/x/net/bpf/vm.go | 10 + .../golang.org/x/net/bpf/vm_instructions.go | 38 +- .../x/net/context/ctxhttp/ctxhttp.go | 5 +- .../x/net/context/ctxhttp/ctxhttp_pre17.go | 147 - .../x/net/http2/client_conn_pool.go | 28 +- .../x/net/http2/configure_transport.go | 80 - vendor/golang.org/x/net/http2/flow.go | 10 +- vendor/golang.org/x/net/http2/frame.go | 67 +- vendor/golang.org/x/net/http2/go111.go | 29 + vendor/golang.org/x/net/http2/go16.go | 16 - vendor/golang.org/x/net/http2/go17.go | 106 - vendor/golang.org/x/net/http2/go17_not18.go | 36 - vendor/golang.org/x/net/http2/go18.go | 56 - vendor/golang.org/x/net/http2/go19.go | 16 - .../golang.org/x/net/http2}/h2c/h2c.go | 119 +- vendor/golang.org/x/net/http2/headermap.go | 20 +- vendor/golang.org/x/net/http2/hpack/hpack.go | 10 +- .../golang.org/x/net/http2/hpack/huffman.go | 20 +- vendor/golang.org/x/net/http2/http2.go | 17 +- vendor/golang.org/x/net/http2/not_go111.go | 20 + vendor/golang.org/x/net/http2/not_go16.go | 21 - vendor/golang.org/x/net/http2/not_go17.go | 87 - vendor/golang.org/x/net/http2/not_go18.go | 29 - vendor/golang.org/x/net/http2/not_go19.go | 16 - vendor/golang.org/x/net/http2/server.go | 126 +- vendor/golang.org/x/net/http2/transport.go | 414 +- vendor/golang.org/x/net/http2/write.go | 4 +- .../x/net/idna/{idna.go => idna10.0.0.go} | 8 +- vendor/golang.org/x/net/idna/idna9.0.0.go | 682 + .../x/net/idna/{tables.go => tables10.0.0.go} | 6 +- vendor/golang.org/x/net/idna/tables11.0.0.go | 4653 ++++ vendor/golang.org/x/net/idna/tables9.0.0.go | 4486 ++++ .../x/net/internal/socket/cmsghdr.go | 2 +- .../x/net/internal/socket/cmsghdr_bsd.go | 2 +- .../internal/socket/cmsghdr_linux_64bit.go | 2 +- .../x/net/internal/socket/cmsghdr_stub.go | 2 +- .../x/net/internal/socket/defs_aix.go | 39 + .../x/net/internal/socket/defs_darwin.go | 8 - .../x/net/internal/socket/defs_dragonfly.go | 8 - .../x/net/internal/socket/defs_freebsd.go | 8 - .../x/net/internal/socket/defs_linux.go | 8 - .../x/net/internal/socket/defs_netbsd.go | 8 - .../x/net/internal/socket/defs_openbsd.go | 8 - .../x/net/internal/socket/defs_solaris.go | 8 - .../golang.org/x/net/internal/socket/empty.s | 7 + .../x/net/internal/socket/error_unix.go | 2 +- .../x/net/internal/socket/iovec_64bit.go | 4 +- .../x/net/internal/socket/iovec_stub.go | 2 +- .../x/net/internal/socket/mmsghdr_stub.go | 2 +- .../x/net/internal/socket/mmsghdr_unix.go | 2 +- .../x/net/internal/socket/msghdr_bsd.go | 2 +- .../x/net/internal/socket/msghdr_bsdvar.go | 2 +- .../net/internal/socket/msghdr_linux_64bit.go | 2 +- .../x/net/internal/socket/msghdr_stub.go | 2 +- .../x/net/internal/socket/rawconn.go | 2 - .../x/net/internal/socket/rawconn_mmsg.go | 1 - .../x/net/internal/socket/rawconn_msg.go | 3 +- .../x/net/internal/socket/rawconn_nommsg.go | 7 +- .../x/net/internal/socket/rawconn_nomsg.go | 9 +- .../x/net/internal/socket/rawconn_stub.go | 25 - .../x/net/internal/socket/reflect.go | 62 - .../x/net/internal/socket/socket.go | 3 + .../golang.org/x/net/internal/socket/sys.go | 2 +- .../x/net/internal/socket/sys_bsd.go | 8 +- .../x/net/internal/socket/sys_bsdvar.go | 13 +- .../x/net/internal/socket/sys_const_unix.go | 17 + .../net/internal/socket/sys_go1_11_darwin.go | 33 + .../x/net/internal/socket/sys_linkname.go | 42 + .../net/internal/socket/sys_linux_riscv64.go | 12 + .../x/net/internal/socket/sys_posix.go | 45 +- .../x/net/internal/socket/sys_solaris.go | 5 +- .../x/net/internal/socket/sys_stub.go | 17 +- .../x/net/internal/socket/sys_unix.go | 2 +- .../x/net/internal/socket/sys_windows.go | 19 +- .../x/net/internal/socket/zsys_aix_ppc64.go | 61 + .../x/net/internal/socket/zsys_darwin_386.go | 10 +- .../net/internal/socket/zsys_darwin_amd64.go | 10 +- .../x/net/internal/socket/zsys_darwin_arm.go | 10 +- .../net/internal/socket/zsys_darwin_arm64.go | 10 +- .../internal/socket/zsys_dragonfly_amd64.go | 10 +- .../x/net/internal/socket/zsys_freebsd_386.go | 10 +- .../net/internal/socket/zsys_freebsd_amd64.go | 10 +- .../x/net/internal/socket/zsys_freebsd_arm.go | 10 +- .../net/internal/socket/zsys_freebsd_arm64.go | 53 + .../x/net/internal/socket/zsys_linux_386.go | 10 +- .../x/net/internal/socket/zsys_linux_amd64.go | 10 +- .../x/net/internal/socket/zsys_linux_arm.go | 10 +- .../x/net/internal/socket/zsys_linux_arm64.go | 10 +- .../x/net/internal/socket/zsys_linux_mips.go | 10 +- .../net/internal/socket/zsys_linux_mips64.go | 10 +- .../internal/socket/zsys_linux_mips64le.go | 10 +- .../net/internal/socket/zsys_linux_mipsle.go | 10 +- .../x/net/internal/socket/zsys_linux_ppc64.go | 10 +- .../net/internal/socket/zsys_linux_ppc64le.go | 10 +- .../net/internal/socket/zsys_linux_riscv64.go | 59 + .../x/net/internal/socket/zsys_linux_s390x.go | 10 +- .../x/net/internal/socket/zsys_netbsd_386.go | 10 +- .../net/internal/socket/zsys_netbsd_amd64.go | 10 +- .../x/net/internal/socket/zsys_netbsd_arm.go | 10 +- .../net/internal/socket/zsys_netbsd_arm64.go | 60 + .../x/net/internal/socket/zsys_openbsd_386.go | 10 +- .../net/internal/socket/zsys_openbsd_amd64.go | 10 +- .../x/net/internal/socket/zsys_openbsd_arm.go | 10 +- .../net/internal/socket/zsys_openbsd_arm64.go | 53 + .../net/internal/socket/zsys_solaris_amd64.go | 10 +- .../golang.org/x/net/internal/socks/socks.go | 1 + vendor/golang.org/x/net/ipv4/batch.go | 17 +- vendor/golang.org/x/net/ipv4/control_bsd.go | 2 +- vendor/golang.org/x/net/ipv4/control_stub.go | 4 +- vendor/golang.org/x/net/ipv4/control_unix.go | 2 +- .../golang.org/x/net/ipv4/control_windows.go | 8 +- vendor/golang.org/x/net/ipv4/defs_aix.go | 39 + vendor/golang.org/x/net/ipv4/dgramopt.go | 61 +- vendor/golang.org/x/net/ipv4/doc.go | 6 +- vendor/golang.org/x/net/ipv4/endpoint.go | 23 +- vendor/golang.org/x/net/ipv4/genericopt.go | 18 +- vendor/golang.org/x/net/ipv4/header.go | 24 +- vendor/golang.org/x/net/ipv4/helper.go | 25 +- vendor/golang.org/x/net/ipv4/packet.go | 58 +- vendor/golang.org/x/net/ipv4/packet_go1_8.go | 56 - vendor/golang.org/x/net/ipv4/packet_go1_9.go | 67 - vendor/golang.org/x/net/ipv4/payload_cmsg.go | 60 +- .../x/net/ipv4/payload_cmsg_go1_8.go | 59 - .../x/net/ipv4/payload_cmsg_go1_9.go | 67 - .../golang.org/x/net/ipv4/payload_nocmsg.go | 11 +- vendor/golang.org/x/net/ipv4/sockopt_posix.go | 6 +- vendor/golang.org/x/net/ipv4/sockopt_stub.go | 16 +- vendor/golang.org/x/net/ipv4/sys_aix.go | 38 + vendor/golang.org/x/net/ipv4/sys_asmreq.go | 2 +- .../golang.org/x/net/ipv4/sys_asmreq_stub.go | 8 +- .../golang.org/x/net/ipv4/sys_asmreqn_stub.go | 4 +- vendor/golang.org/x/net/ipv4/sys_bpf_stub.go | 2 +- vendor/golang.org/x/net/ipv4/sys_darwin.go | 52 +- vendor/golang.org/x/net/ipv4/sys_freebsd.go | 2 +- vendor/golang.org/x/net/ipv4/sys_ssmreq.go | 6 +- .../golang.org/x/net/ipv4/sys_ssmreq_stub.go | 4 +- vendor/golang.org/x/net/ipv4/sys_stub.go | 2 +- .../golang.org/x/net/ipv4/zsys_aix_ppc64.go | 33 + vendor/golang.org/x/net/ipv4/zsys_darwin.go | 2 +- .../golang.org/x/net/ipv4/zsys_dragonfly.go | 2 +- .../golang.org/x/net/ipv4/zsys_freebsd_386.go | 2 +- .../x/net/ipv4/zsys_freebsd_amd64.go | 2 +- .../golang.org/x/net/ipv4/zsys_freebsd_arm.go | 2 +- .../golang.org/x/net/ipv4/zsys_linux_386.go | 2 +- .../golang.org/x/net/ipv4/zsys_linux_amd64.go | 2 +- .../golang.org/x/net/ipv4/zsys_linux_arm.go | 2 +- .../golang.org/x/net/ipv4/zsys_linux_arm64.go | 2 +- .../golang.org/x/net/ipv4/zsys_linux_mips.go | 2 +- .../x/net/ipv4/zsys_linux_mips64.go | 2 +- .../x/net/ipv4/zsys_linux_mips64le.go | 2 +- .../x/net/ipv4/zsys_linux_mipsle.go | 2 +- .../golang.org/x/net/ipv4/zsys_linux_ppc.go | 2 +- .../golang.org/x/net/ipv4/zsys_linux_ppc64.go | 2 +- .../x/net/ipv4/zsys_linux_ppc64le.go | 2 +- .../x/net/ipv4/zsys_linux_riscv64.go | 151 + .../golang.org/x/net/ipv4/zsys_linux_s390x.go | 2 +- vendor/golang.org/x/net/ipv4/zsys_netbsd.go | 2 +- vendor/golang.org/x/net/ipv4/zsys_openbsd.go | 2 +- vendor/golang.org/x/net/ipv4/zsys_solaris.go | 2 +- vendor/golang.org/x/net/ipv6/batch.go | 7 +- .../x/net/ipv6/control_rfc3542_unix.go | 2 +- vendor/golang.org/x/net/ipv6/control_stub.go | 4 +- vendor/golang.org/x/net/ipv6/control_unix.go | 2 +- .../golang.org/x/net/ipv6/control_windows.go | 8 +- vendor/golang.org/x/net/ipv6/defs_aix.go | 82 + vendor/golang.org/x/net/ipv6/dgramopt.go | 69 +- vendor/golang.org/x/net/ipv6/doc.go | 4 +- vendor/golang.org/x/net/ipv6/endpoint.go | 15 +- vendor/golang.org/x/net/ipv6/genericopt.go | 18 +- vendor/golang.org/x/net/ipv6/helper.go | 4 +- vendor/golang.org/x/net/ipv6/icmp_bsd.go | 2 +- vendor/golang.org/x/net/ipv6/icmp_stub.go | 2 +- vendor/golang.org/x/net/ipv6/payload_cmsg.go | 47 +- .../x/net/ipv6/payload_cmsg_go1_8.go | 55 - .../x/net/ipv6/payload_cmsg_go1_9.go | 57 - .../golang.org/x/net/ipv6/payload_nocmsg.go | 11 +- vendor/golang.org/x/net/ipv6/sockopt_posix.go | 12 +- vendor/golang.org/x/net/ipv6/sockopt_stub.go | 18 +- vendor/golang.org/x/net/ipv6/sys_aix.go | 77 + vendor/golang.org/x/net/ipv6/sys_asmreq.go | 2 +- .../golang.org/x/net/ipv6/sys_asmreq_stub.go | 4 +- vendor/golang.org/x/net/ipv6/sys_bpf_stub.go | 2 +- vendor/golang.org/x/net/ipv6/sys_darwin.go | 74 +- vendor/golang.org/x/net/ipv6/sys_freebsd.go | 2 +- vendor/golang.org/x/net/ipv6/sys_ssmreq.go | 8 +- .../golang.org/x/net/ipv6/sys_ssmreq_stub.go | 6 +- vendor/golang.org/x/net/ipv6/sys_stub.go | 2 +- .../golang.org/x/net/ipv6/zsys_aix_ppc64.go | 103 + vendor/golang.org/x/net/ipv6/zsys_darwin.go | 2 +- .../golang.org/x/net/ipv6/zsys_dragonfly.go | 2 +- .../golang.org/x/net/ipv6/zsys_freebsd_386.go | 2 +- .../x/net/ipv6/zsys_freebsd_amd64.go | 2 +- .../golang.org/x/net/ipv6/zsys_freebsd_arm.go | 2 +- .../golang.org/x/net/ipv6/zsys_linux_386.go | 2 +- .../golang.org/x/net/ipv6/zsys_linux_amd64.go | 2 +- .../golang.org/x/net/ipv6/zsys_linux_arm.go | 2 +- .../golang.org/x/net/ipv6/zsys_linux_arm64.go | 2 +- .../golang.org/x/net/ipv6/zsys_linux_mips.go | 2 +- .../x/net/ipv6/zsys_linux_mips64.go | 2 +- .../x/net/ipv6/zsys_linux_mips64le.go | 2 +- .../x/net/ipv6/zsys_linux_mipsle.go | 2 +- .../golang.org/x/net/ipv6/zsys_linux_ppc.go | 2 +- .../golang.org/x/net/ipv6/zsys_linux_ppc64.go | 2 +- .../x/net/ipv6/zsys_linux_ppc64le.go | 2 +- .../x/net/ipv6/zsys_linux_riscv64.go | 173 + .../golang.org/x/net/ipv6/zsys_linux_s390x.go | 2 +- vendor/golang.org/x/net/ipv6/zsys_netbsd.go | 2 +- vendor/golang.org/x/net/ipv6/zsys_openbsd.go | 2 +- vendor/golang.org/x/net/ipv6/zsys_solaris.go | 2 +- vendor/golang.org/x/net/proxy/dial.go | 54 + vendor/golang.org/x/net/proxy/direct.go | 15 +- vendor/golang.org/x/net/proxy/per_host.go | 15 + vendor/golang.org/x/net/proxy/proxy.go | 33 +- vendor/golang.org/x/net/proxy/socks5.go | 10 +- vendor/golang.org/x/net/publicsuffix/gen.go | 8 +- vendor/golang.org/x/net/publicsuffix/list.go | 64 +- vendor/golang.org/x/net/publicsuffix/table.go | 19389 ++++++++-------- vendor/golang.org/x/net/trace/trace.go | 31 +- vendor/golang.org/x/net/trace/trace_go16.go | 21 - vendor/golang.org/x/net/trace/trace_go17.go | 21 - 224 files changed, 22414 insertions(+), 11768 deletions(-) delete mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go delete mode 100644 vendor/golang.org/x/net/http2/configure_transport.go create mode 100644 vendor/golang.org/x/net/http2/go111.go delete mode 100644 vendor/golang.org/x/net/http2/go16.go delete mode 100644 vendor/golang.org/x/net/http2/go17.go delete mode 100644 vendor/golang.org/x/net/http2/go17_not18.go delete mode 100644 vendor/golang.org/x/net/http2/go18.go delete mode 100644 vendor/golang.org/x/net/http2/go19.go rename {pkg => vendor/golang.org/x/net/http2}/h2c/h2c.go (77%) create mode 100644 vendor/golang.org/x/net/http2/not_go111.go delete mode 100644 vendor/golang.org/x/net/http2/not_go16.go delete mode 100644 vendor/golang.org/x/net/http2/not_go17.go delete mode 100644 vendor/golang.org/x/net/http2/not_go18.go delete mode 100644 vendor/golang.org/x/net/http2/not_go19.go rename vendor/golang.org/x/net/idna/{idna.go => idna10.0.0.go} (99%) create mode 100644 vendor/golang.org/x/net/idna/idna9.0.0.go rename vendor/golang.org/x/net/idna/{tables.go => tables10.0.0.go} (99%) create mode 100644 vendor/golang.org/x/net/idna/tables11.0.0.go create mode 100644 vendor/golang.org/x/net/idna/tables9.0.0.go create mode 100644 vendor/golang.org/x/net/internal/socket/defs_aix.go create mode 100644 vendor/golang.org/x/net/internal/socket/empty.s delete mode 100644 vendor/golang.org/x/net/internal/socket/rawconn_stub.go delete mode 100644 vendor/golang.org/x/net/internal/socket/reflect.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_const_unix.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linkname.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go create mode 100644 vendor/golang.org/x/net/ipv4/defs_aix.go delete mode 100644 vendor/golang.org/x/net/ipv4/packet_go1_8.go delete mode 100644 vendor/golang.org/x/net/ipv4/packet_go1_9.go delete mode 100644 vendor/golang.org/x/net/ipv4/payload_cmsg_go1_8.go delete mode 100644 vendor/golang.org/x/net/ipv4/payload_cmsg_go1_9.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_aix.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go create mode 100644 vendor/golang.org/x/net/ipv6/defs_aix.go delete mode 100644 vendor/golang.org/x/net/ipv6/payload_cmsg_go1_8.go delete mode 100644 vendor/golang.org/x/net/ipv6/payload_cmsg_go1_9.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_aix.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go create mode 100644 vendor/golang.org/x/net/proxy/dial.go delete mode 100644 vendor/golang.org/x/net/trace/trace_go16.go delete mode 100644 vendor/golang.org/x/net/trace/trace_go17.go diff --git a/Gopkg.lock b/Gopkg.lock index ef3da06b3..b2da47f6a 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1677,7 +1677,7 @@ [[projects]] branch = "master" - digest = "1:62afa19ba5d4c75369a1d6446688e33ef3c04a40aeedd819cf044a509747b563" + digest = "1:4d0fb9f19b2af3461e900a526395330403b39d839f126b66312215f153892ccc" name = "golang.org/x/net" packages = [ "bpf", @@ -1685,6 +1685,7 @@ "context/ctxhttp", "http/httpguts", "http2", + "http2/h2c", "http2/hpack", "idna", "internal/iana", @@ -1699,7 +1700,7 @@ "websocket", ] pruneopts = "NUT" - revision = "e514e69ffb8bc3c76a71ae40de0118d794855992" + revision = "da137c7871d730100384dbcf36e6f8fa493aef5b" [[projects]] branch = "master" @@ -2301,9 +2302,8 @@ "github.com/vulcand/oxy/roundrobin", "github.com/vulcand/oxy/utils", "github.com/vulcand/predicate", - "golang.org/x/net/http/httpguts", "golang.org/x/net/http2", - "golang.org/x/net/http2/hpack", + "golang.org/x/net/http2/h2c", "golang.org/x/net/websocket", "google.golang.org/grpc", "google.golang.org/grpc/credentials", diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go index b2ee10eba..98a56800e 100644 --- a/pkg/server/server_entrypoint_tcp.go +++ b/pkg/server/server_entrypoint_tcp.go @@ -10,13 +10,14 @@ import ( "github.com/armon/go-proxyproto" "github.com/containous/traefik/pkg/config/static" - "github.com/containous/traefik/pkg/h2c" "github.com/containous/traefik/pkg/ip" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/middlewares" "github.com/containous/traefik/pkg/middlewares/forwardedheaders" "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/tcp" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" ) type httpForwarder struct { @@ -336,7 +337,10 @@ type httpServer struct { func createHTTPServer(ln net.Listener, configuration *static.EntryPoint, withH2c bool) (*httpServer, error) { httpSwitcher := middlewares.NewHandlerSwitcher(buildDefaultHTTPRouter()) - handler, err := forwardedheaders.NewXForwarded( + + var handler http.Handler + var err error + handler, err = forwardedheaders.NewXForwarded( configuration.ForwardedHeaders.Insecure, configuration.ForwardedHeaders.TrustedIPs, httpSwitcher) @@ -344,18 +348,12 @@ func createHTTPServer(ln net.Listener, configuration *static.EntryPoint, withH2c return nil, err } - var serverHTTP stoppableServer - if withH2c { - serverHTTP = &h2c.Server{ - Server: &http.Server{ - Handler: handler, - }, - } - } else { - serverHTTP = &http.Server{ - Handler: handler, - } + handler = h2c.NewHandler(handler, &http2.Server{}) + } + + serverHTTP := &http.Server{ + Handler: handler, } listener := newHTTPForwarder(ln) diff --git a/vendor/golang.org/x/net/bpf/constants.go b/vendor/golang.org/x/net/bpf/constants.go index b89ca3523..12f3ee835 100644 --- a/vendor/golang.org/x/net/bpf/constants.go +++ b/vendor/golang.org/x/net/bpf/constants.go @@ -38,6 +38,7 @@ const ( type JumpTest uint16 // Supported operators for conditional jumps. +// K can be RegX for JumpIfX const ( // K == A JumpEqual JumpTest = iota @@ -134,12 +135,9 @@ const ( opMaskLoadDest = 0x01 opMaskLoadWidth = 0x18 opMaskLoadMode = 0xe0 - // opClsALU - opMaskOperandSrc = 0x08 - opMaskOperator = 0xf0 - // opClsJump - opMaskJumpConst = 0x0f - opMaskJumpCond = 0xf0 + // opClsALU & opClsJump + opMaskOperand = 0x08 + opMaskOperator = 0xf0 ) const ( @@ -192,15 +190,21 @@ const ( opLoadWidth1 ) -// Operator defined by ALUOp* +// Operand for ALU and Jump instructions +type opOperand uint16 +// Supported operand sources. const ( - opALUSrcConstant uint16 = iota << 3 - opALUSrcX + opOperandConstant opOperand = iota << 3 + opOperandX ) +// An jumpOp is a conditional jump condition. +type jumpOp uint16 + +// Supported jump conditions. const ( - opJumpAlways = iota << 4 + opJumpAlways jumpOp = iota << 4 opJumpEqual opJumpGT opJumpGE diff --git a/vendor/golang.org/x/net/bpf/instructions.go b/vendor/golang.org/x/net/bpf/instructions.go index f9dc0e8ee..3cffcaa01 100644 --- a/vendor/golang.org/x/net/bpf/instructions.go +++ b/vendor/golang.org/x/net/bpf/instructions.go @@ -89,10 +89,14 @@ func (ri RawInstruction) Disassemble() Instruction { case opClsALU: switch op := ALUOp(ri.Op & opMaskOperator); op { case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor: - if ri.Op&opMaskOperandSrc != 0 { + switch operand := opOperand(ri.Op & opMaskOperand); operand { + case opOperandX: return ALUOpX{Op: op} + case opOperandConstant: + return ALUOpConstant{Op: op, Val: ri.K} + default: + return ri } - return ALUOpConstant{Op: op, Val: ri.K} case aluOpNeg: return NegateA{} default: @@ -100,63 +104,18 @@ func (ri RawInstruction) Disassemble() Instruction { } case opClsJump: - if ri.Op&opMaskJumpConst != opClsJump { - return ri - } - switch ri.Op & opMaskJumpCond { + switch op := jumpOp(ri.Op & opMaskOperator); op { case opJumpAlways: return Jump{Skip: ri.K} - case opJumpEqual: - if ri.Jt == 0 { - return JumpIf{ - Cond: JumpNotEqual, - Val: ri.K, - SkipTrue: ri.Jf, - SkipFalse: 0, - } - } - return JumpIf{ - Cond: JumpEqual, - Val: ri.K, - SkipTrue: ri.Jt, - SkipFalse: ri.Jf, - } - case opJumpGT: - if ri.Jt == 0 { - return JumpIf{ - Cond: JumpLessOrEqual, - Val: ri.K, - SkipTrue: ri.Jf, - SkipFalse: 0, - } - } - return JumpIf{ - Cond: JumpGreaterThan, - Val: ri.K, - SkipTrue: ri.Jt, - SkipFalse: ri.Jf, - } - case opJumpGE: - if ri.Jt == 0 { - return JumpIf{ - Cond: JumpLessThan, - Val: ri.K, - SkipTrue: ri.Jf, - SkipFalse: 0, - } - } - return JumpIf{ - Cond: JumpGreaterOrEqual, - Val: ri.K, - SkipTrue: ri.Jt, - SkipFalse: ri.Jf, - } - case opJumpSet: - return JumpIf{ - Cond: JumpBitsSet, - Val: ri.K, - SkipTrue: ri.Jt, - SkipFalse: ri.Jf, + case opJumpEqual, opJumpGT, opJumpGE, opJumpSet: + cond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf) + switch operand := opOperand(ri.Op & opMaskOperand); operand { + case opOperandX: + return JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse} + case opOperandConstant: + return JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse} + default: + return ri } default: return ri @@ -187,6 +146,41 @@ func (ri RawInstruction) Disassemble() Instruction { } } +func jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) { + var test JumpTest + + // Decode "fake" jump conditions that don't appear in machine code + // Ensures the Assemble -> Disassemble stage recreates the same instructions + // See https://github.com/golang/go/issues/18470 + if skipTrue == 0 { + switch op { + case opJumpEqual: + test = JumpNotEqual + case opJumpGT: + test = JumpLessOrEqual + case opJumpGE: + test = JumpLessThan + case opJumpSet: + test = JumpBitsNotSet + } + + return test, skipFalse, 0 + } + + switch op { + case opJumpEqual: + test = JumpEqual + case opJumpGT: + test = JumpGreaterThan + case opJumpGE: + test = JumpGreaterOrEqual + case opJumpSet: + test = JumpBitsSet + } + + return test, skipTrue, skipFalse +} + // LoadConstant loads Val into register Dst. type LoadConstant struct { Dst Register @@ -413,7 +407,7 @@ type ALUOpConstant struct { // Assemble implements the Instruction Assemble method. func (a ALUOpConstant) Assemble() (RawInstruction, error) { return RawInstruction{ - Op: opClsALU | opALUSrcConstant | uint16(a.Op), + Op: opClsALU | uint16(opOperandConstant) | uint16(a.Op), K: a.Val, }, nil } @@ -454,7 +448,7 @@ type ALUOpX struct { // Assemble implements the Instruction Assemble method. func (a ALUOpX) Assemble() (RawInstruction, error) { return RawInstruction{ - Op: opClsALU | opALUSrcX | uint16(a.Op), + Op: opClsALU | uint16(opOperandX) | uint16(a.Op), }, nil } @@ -509,7 +503,7 @@ type Jump struct { // Assemble implements the Instruction Assemble method. func (a Jump) Assemble() (RawInstruction, error) { return RawInstruction{ - Op: opClsJump | opJumpAlways, + Op: opClsJump | uint16(opJumpAlways), K: a.Skip, }, nil } @@ -530,11 +524,39 @@ type JumpIf struct { // Assemble implements the Instruction Assemble method. func (a JumpIf) Assemble() (RawInstruction, error) { + return jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse) +} + +// String returns the instruction in assembler notation. +func (a JumpIf) String() string { + return jumpToString(a.Cond, fmt.Sprintf("#%d", a.Val), a.SkipTrue, a.SkipFalse) +} + +// JumpIfX skips the following Skip instructions in the program if A +// X is true. +type JumpIfX struct { + Cond JumpTest + SkipTrue uint8 + SkipFalse uint8 +} + +// Assemble implements the Instruction Assemble method. +func (a JumpIfX) Assemble() (RawInstruction, error) { + return jumpToRaw(a.Cond, opOperandX, 0, a.SkipTrue, a.SkipFalse) +} + +// String returns the instruction in assembler notation. +func (a JumpIfX) String() string { + return jumpToString(a.Cond, "x", a.SkipTrue, a.SkipFalse) +} + +// jumpToRaw assembles a jump instruction into a RawInstruction +func jumpToRaw(test JumpTest, operand opOperand, k uint32, skipTrue, skipFalse uint8) (RawInstruction, error) { var ( - cond uint16 + cond jumpOp flip bool ) - switch a.Cond { + switch test { case JumpEqual: cond = opJumpEqual case JumpNotEqual: @@ -552,63 +574,63 @@ func (a JumpIf) Assemble() (RawInstruction, error) { case JumpBitsNotSet: cond, flip = opJumpSet, true default: - return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", a.Cond) + return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", test) } - jt, jf := a.SkipTrue, a.SkipFalse + jt, jf := skipTrue, skipFalse if flip { jt, jf = jf, jt } return RawInstruction{ - Op: opClsJump | cond, + Op: opClsJump | uint16(cond) | uint16(operand), Jt: jt, Jf: jf, - K: a.Val, + K: k, }, nil } -// String returns the instruction in assembler notation. -func (a JumpIf) String() string { - switch a.Cond { +// jumpToString converts a jump instruction to assembler notation +func jumpToString(cond JumpTest, operand string, skipTrue, skipFalse uint8) string { + switch cond { // K == A case JumpEqual: - return conditionalJump(a, "jeq", "jneq") + return conditionalJump(operand, skipTrue, skipFalse, "jeq", "jneq") // K != A case JumpNotEqual: - return fmt.Sprintf("jneq #%d,%d", a.Val, a.SkipTrue) + return fmt.Sprintf("jneq %s,%d", operand, skipTrue) // K > A case JumpGreaterThan: - return conditionalJump(a, "jgt", "jle") + return conditionalJump(operand, skipTrue, skipFalse, "jgt", "jle") // K < A case JumpLessThan: - return fmt.Sprintf("jlt #%d,%d", a.Val, a.SkipTrue) + return fmt.Sprintf("jlt %s,%d", operand, skipTrue) // K >= A case JumpGreaterOrEqual: - return conditionalJump(a, "jge", "jlt") + return conditionalJump(operand, skipTrue, skipFalse, "jge", "jlt") // K <= A case JumpLessOrEqual: - return fmt.Sprintf("jle #%d,%d", a.Val, a.SkipTrue) + return fmt.Sprintf("jle %s,%d", operand, skipTrue) // K & A != 0 case JumpBitsSet: - if a.SkipFalse > 0 { - return fmt.Sprintf("jset #%d,%d,%d", a.Val, a.SkipTrue, a.SkipFalse) + if skipFalse > 0 { + return fmt.Sprintf("jset %s,%d,%d", operand, skipTrue, skipFalse) } - return fmt.Sprintf("jset #%d,%d", a.Val, a.SkipTrue) + return fmt.Sprintf("jset %s,%d", operand, skipTrue) // K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips case JumpBitsNotSet: - return JumpIf{Cond: JumpBitsSet, SkipTrue: a.SkipFalse, SkipFalse: a.SkipTrue, Val: a.Val}.String() + return jumpToString(JumpBitsSet, operand, skipFalse, skipTrue) default: - return fmt.Sprintf("unknown instruction: %#v", a) + return fmt.Sprintf("unknown JumpTest %#v", cond) } } -func conditionalJump(inst JumpIf, positiveJump, negativeJump string) string { - if inst.SkipTrue > 0 { - if inst.SkipFalse > 0 { - return fmt.Sprintf("%s #%d,%d,%d", positiveJump, inst.Val, inst.SkipTrue, inst.SkipFalse) +func conditionalJump(operand string, skipTrue, skipFalse uint8, positiveJump, negativeJump string) string { + if skipTrue > 0 { + if skipFalse > 0 { + return fmt.Sprintf("%s %s,%d,%d", positiveJump, operand, skipTrue, skipFalse) } - return fmt.Sprintf("%s #%d,%d", positiveJump, inst.Val, inst.SkipTrue) + return fmt.Sprintf("%s %s,%d", positiveJump, operand, skipTrue) } - return fmt.Sprintf("%s #%d,%d", negativeJump, inst.Val, inst.SkipFalse) + return fmt.Sprintf("%s %s,%d", negativeJump, operand, skipFalse) } // RetA exits the BPF program, returning the value of register A. diff --git a/vendor/golang.org/x/net/bpf/vm.go b/vendor/golang.org/x/net/bpf/vm.go index 4c656f1e1..73f57f1f7 100644 --- a/vendor/golang.org/x/net/bpf/vm.go +++ b/vendor/golang.org/x/net/bpf/vm.go @@ -35,6 +35,13 @@ func NewVM(filter []Instruction) (*VM, error) { if check <= int(ins.SkipFalse) { return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse) } + case JumpIfX: + if check <= int(ins.SkipTrue) { + return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue) + } + if check <= int(ins.SkipFalse) { + return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse) + } // Check for division or modulus by zero case ALUOpConstant: if ins.Val != 0 { @@ -109,6 +116,9 @@ func (v *VM) Run(in []byte) (int, error) { case JumpIf: jump := jumpIf(ins, regA) i += jump + case JumpIfX: + jump := jumpIfX(ins, regA, regX) + i += jump case LoadAbsolute: regA, ok = loadAbsolute(ins, in) case LoadConstant: diff --git a/vendor/golang.org/x/net/bpf/vm_instructions.go b/vendor/golang.org/x/net/bpf/vm_instructions.go index 516f9462b..cf8947c33 100644 --- a/vendor/golang.org/x/net/bpf/vm_instructions.go +++ b/vendor/golang.org/x/net/bpf/vm_instructions.go @@ -55,34 +55,41 @@ func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 { } } -func jumpIf(ins JumpIf, value uint32) int { - var ok bool - inV := uint32(ins.Val) +func jumpIf(ins JumpIf, regA uint32) int { + return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, ins.Val) +} - switch ins.Cond { +func jumpIfX(ins JumpIfX, regA uint32, regX uint32) int { + return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, regX) +} + +func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value uint32) int { + var ok bool + + switch cond { case JumpEqual: - ok = value == inV + ok = regA == value case JumpNotEqual: - ok = value != inV + ok = regA != value case JumpGreaterThan: - ok = value > inV + ok = regA > value case JumpLessThan: - ok = value < inV + ok = regA < value case JumpGreaterOrEqual: - ok = value >= inV + ok = regA >= value case JumpLessOrEqual: - ok = value <= inV + ok = regA <= value case JumpBitsSet: - ok = (value & inV) != 0 + ok = (regA & value) != 0 case JumpBitsNotSet: - ok = (value & inV) == 0 + ok = (regA & value) == 0 } if ok { - return int(ins.SkipTrue) + return int(skipTrue) } - return int(ins.SkipFalse) + return int(skipFalse) } func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) { @@ -122,7 +129,8 @@ func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) { func loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) { offset := int(ins.Off) - if !inBounds(len(in), offset, 0) { + // Size of LoadMemShift is always 1 byte + if !inBounds(len(in), offset, 1) { return 0, false } diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go index 606cf1f97..37dc0cfdb 100644 --- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go +++ b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go @@ -2,18 +2,15 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.7 - // Package ctxhttp provides helper functions for performing context-aware HTTP requests. package ctxhttp // import "golang.org/x/net/context/ctxhttp" import ( + "context" "io" "net/http" "net/url" "strings" - - "golang.org/x/net/context" ) // Do sends an HTTP request with the provided http.Client and returns diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go deleted file mode 100644 index 926870cc2..000000000 --- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.7 - -package ctxhttp // import "golang.org/x/net/context/ctxhttp" - -import ( - "io" - "net/http" - "net/url" - "strings" - - "golang.org/x/net/context" -) - -func nop() {} - -var ( - testHookContextDoneBeforeHeaders = nop - testHookDoReturned = nop - testHookDidBodyClose = nop -) - -// Do sends an HTTP request with the provided http.Client and returns an HTTP response. -// If the client is nil, http.DefaultClient is used. -// If the context is canceled or times out, ctx.Err() will be returned. -func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { - if client == nil { - client = http.DefaultClient - } - - // TODO(djd): Respect any existing value of req.Cancel. - cancel := make(chan struct{}) - req.Cancel = cancel - - type responseAndError struct { - resp *http.Response - err error - } - result := make(chan responseAndError, 1) - - // Make local copies of test hooks closed over by goroutines below. - // Prevents data races in tests. - testHookDoReturned := testHookDoReturned - testHookDidBodyClose := testHookDidBodyClose - - go func() { - resp, err := client.Do(req) - testHookDoReturned() - result <- responseAndError{resp, err} - }() - - var resp *http.Response - - select { - case <-ctx.Done(): - testHookContextDoneBeforeHeaders() - close(cancel) - // Clean up after the goroutine calling client.Do: - go func() { - if r := <-result; r.resp != nil { - testHookDidBodyClose() - r.resp.Body.Close() - } - }() - return nil, ctx.Err() - case r := <-result: - var err error - resp, err = r.resp, r.err - if err != nil { - return resp, err - } - } - - c := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - close(cancel) - case <-c: - // The response's Body is closed. - } - }() - resp.Body = ¬ifyingReader{resp.Body, c} - - return resp, nil -} - -// Get issues a GET request via the Do function. -func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - return Do(ctx, client, req) -} - -// Head issues a HEAD request via the Do function. -func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { - req, err := http.NewRequest("HEAD", url, nil) - if err != nil { - return nil, err - } - return Do(ctx, client, req) -} - -// Post issues a POST request via the Do function. -func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { - req, err := http.NewRequest("POST", url, body) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", bodyType) - return Do(ctx, client, req) -} - -// PostForm issues a POST request via the Do function. -func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { - return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) -} - -// notifyingReader is an io.ReadCloser that closes the notify channel after -// Close is called or a Read fails on the underlying ReadCloser. -type notifyingReader struct { - io.ReadCloser - notify chan<- struct{} -} - -func (r *notifyingReader) Read(p []byte) (int, error) { - n, err := r.ReadCloser.Read(p) - if err != nil && r.notify != nil { - close(r.notify) - r.notify = nil - } - return n, err -} - -func (r *notifyingReader) Close() error { - err := r.ReadCloser.Close() - if r.notify != nil { - close(r.notify) - r.notify = nil - } - return err -} diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go index bdf5652b0..f4d9b5ece 100644 --- a/vendor/golang.org/x/net/http2/client_conn_pool.go +++ b/vendor/golang.org/x/net/http2/client_conn_pool.go @@ -52,9 +52,31 @@ const ( noDialOnMiss = false ) +// shouldTraceGetConn reports whether getClientConn should call any +// ClientTrace.GetConn hook associated with the http.Request. +// +// This complexity is needed to avoid double calls of the GetConn hook +// during the back-and-forth between net/http and x/net/http2 (when the +// net/http.Transport is upgraded to also speak http2), as well as support +// the case where x/net/http2 is being used directly. +func (p *clientConnPool) shouldTraceGetConn(st clientConnIdleState) bool { + // If our Transport wasn't made via ConfigureTransport, always + // trace the GetConn hook if provided, because that means the + // http2 package is being used directly and it's the one + // dialing, as opposed to net/http. + if _, ok := p.t.ConnPool.(noDialClientConnPool); !ok { + return true + } + // Otherwise, only use the GetConn hook if this connection has + // been used previously for other requests. For fresh + // connections, the net/http package does the dialing. + return !st.freshConn +} + func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) { if isConnectionCloseRequest(req) && dialOnMiss { // It gets its own connection. + traceGetConn(req, addr) const singleUse = true cc, err := p.t.dialClientConn(addr, singleUse) if err != nil { @@ -64,7 +86,10 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis } p.mu.Lock() for _, cc := range p.conns[addr] { - if cc.CanTakeNewRequest() { + if st := cc.idleState(); st.canTakeNewRequest { + if p.shouldTraceGetConn(st) { + traceGetConn(req, addr) + } p.mu.Unlock() return cc, nil } @@ -73,6 +98,7 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis p.mu.Unlock() return nil, ErrNoCachedConn } + traceGetConn(req, addr) call := p.getStartDialLocked(addr) p.mu.Unlock() <-call.done diff --git a/vendor/golang.org/x/net/http2/configure_transport.go b/vendor/golang.org/x/net/http2/configure_transport.go deleted file mode 100644 index 088d6e2bd..000000000 --- a/vendor/golang.org/x/net/http2/configure_transport.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.6 - -package http2 - -import ( - "crypto/tls" - "fmt" - "net/http" -) - -func configureTransport(t1 *http.Transport) (*Transport, error) { - connPool := new(clientConnPool) - t2 := &Transport{ - ConnPool: noDialClientConnPool{connPool}, - t1: t1, - } - connPool.t = t2 - if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil { - return nil, err - } - if t1.TLSClientConfig == nil { - t1.TLSClientConfig = new(tls.Config) - } - if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") { - t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...) - } - if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") { - t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1") - } - upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper { - addr := authorityAddr("https", authority) - if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil { - go c.Close() - return erringRoundTripper{err} - } else if !used { - // Turns out we don't need this c. - // For example, two goroutines made requests to the same host - // at the same time, both kicking off TCP dials. (since protocol - // was unknown) - go c.Close() - } - return t2 - } - if m := t1.TLSNextProto; len(m) == 0 { - t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{ - "h2": upgradeFn, - } - } else { - m["h2"] = upgradeFn - } - return t2, nil -} - -// registerHTTPSProtocol calls Transport.RegisterProtocol but -// converting panics into errors. -func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) { - defer func() { - if e := recover(); e != nil { - err = fmt.Errorf("%v", e) - } - }() - t.RegisterProtocol("https", rt) - return nil -} - -// noDialH2RoundTripper is a RoundTripper which only tries to complete the request -// if there's already has a cached connection to the host. -type noDialH2RoundTripper struct{ t *Transport } - -func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - res, err := rt.t.RoundTrip(req) - if isNoCachedConnError(err) { - return nil, http.ErrSkipAltProtocol - } - return res, err -} diff --git a/vendor/golang.org/x/net/http2/flow.go b/vendor/golang.org/x/net/http2/flow.go index 957de2542..cea601fcd 100644 --- a/vendor/golang.org/x/net/http2/flow.go +++ b/vendor/golang.org/x/net/http2/flow.go @@ -41,10 +41,10 @@ func (f *flow) take(n int32) { // add adds n bytes (positive or negative) to the flow control window. // It returns false if the sum would exceed 2^31-1. func (f *flow) add(n int32) bool { - remain := (1<<31 - 1) - f.n - if n > remain { - return false + sum := f.n + n + if (sum > n) == (f.n > 0) { + f.n = sum + return true } - f.n += n - return true + return false } diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index e32500779..514c126c5 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -643,7 +643,7 @@ func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { return f.WriteDataPadded(streamID, endStream, data, nil) } -// WriteData writes a DATA frame with optional padding. +// WriteDataPadded writes a DATA frame with optional padding. // // If pad is nil, the padding bit is not sent. // The length of pad must not exceed 255 bytes. @@ -733,32 +733,67 @@ func (f *SettingsFrame) IsAck() bool { return f.FrameHeader.Flags.Has(FlagSettingsAck) } -func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) { +func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) { f.checkValid() - buf := f.p - for len(buf) > 0 { - settingID := SettingID(binary.BigEndian.Uint16(buf[:2])) - if settingID == s { - return binary.BigEndian.Uint32(buf[2:6]), true + for i := 0; i < f.NumSettings(); i++ { + if s := f.Setting(i); s.ID == id { + return s.Val, true } - buf = buf[6:] } return 0, false } +// Setting returns the setting from the frame at the given 0-based index. +// The index must be >= 0 and less than f.NumSettings(). +func (f *SettingsFrame) Setting(i int) Setting { + buf := f.p + return Setting{ + ID: SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])), + Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]), + } +} + +func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 } + +// HasDuplicates reports whether f contains any duplicate setting IDs. +func (f *SettingsFrame) HasDuplicates() bool { + num := f.NumSettings() + if num == 0 { + return false + } + // If it's small enough (the common case), just do the n^2 + // thing and avoid a map allocation. + if num < 10 { + for i := 0; i < num; i++ { + idi := f.Setting(i).ID + for j := i + 1; j < num; j++ { + idj := f.Setting(j).ID + if idi == idj { + return true + } + } + } + return false + } + seen := map[SettingID]bool{} + for i := 0; i < num; i++ { + id := f.Setting(i).ID + if seen[id] { + return true + } + seen[id] = true + } + return false +} + // ForeachSetting runs fn for each setting. // It stops and returns the first error. func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error { f.checkValid() - buf := f.p - for len(buf) > 0 { - if err := fn(Setting{ - SettingID(binary.BigEndian.Uint16(buf[:2])), - binary.BigEndian.Uint32(buf[2:6]), - }); err != nil { + for i := 0; i < f.NumSettings(); i++ { + if err := fn(f.Setting(i)); err != nil { return err } - buf = buf[6:] } return nil } @@ -1442,7 +1477,7 @@ func (fr *Framer) maxHeaderStringLen() int { } // readMetaFrame returns 0 or more CONTINUATION frames from fr and -// merge them into into the provided hf and returns a MetaHeadersFrame +// merge them into the provided hf and returns a MetaHeadersFrame // with the decoded hpack values. func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { if fr.AllowIllegalReads { diff --git a/vendor/golang.org/x/net/http2/go111.go b/vendor/golang.org/x/net/http2/go111.go new file mode 100644 index 000000000..3a131016b --- /dev/null +++ b/vendor/golang.org/x/net/http2/go111.go @@ -0,0 +1,29 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.11 + +package http2 + +import ( + "net/http/httptrace" + "net/textproto" +) + +func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { + return trace != nil && trace.WroteHeaderField != nil +} + +func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) { + if trace != nil && trace.WroteHeaderField != nil { + trace.WroteHeaderField(k, []string{v}) + } +} + +func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { + if trace != nil { + return trace.Got1xxResponse + } + return nil +} diff --git a/vendor/golang.org/x/net/http2/go16.go b/vendor/golang.org/x/net/http2/go16.go deleted file mode 100644 index 00b2e9e3c..000000000 --- a/vendor/golang.org/x/net/http2/go16.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.6 - -package http2 - -import ( - "net/http" - "time" -) - -func transportExpectContinueTimeout(t1 *http.Transport) time.Duration { - return t1.ExpectContinueTimeout -} diff --git a/vendor/golang.org/x/net/http2/go17.go b/vendor/golang.org/x/net/http2/go17.go deleted file mode 100644 index 47b7fae08..000000000 --- a/vendor/golang.org/x/net/http2/go17.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.7 - -package http2 - -import ( - "context" - "net" - "net/http" - "net/http/httptrace" - "time" -) - -type contextContext interface { - context.Context -} - -func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) { - ctx, cancel = context.WithCancel(context.Background()) - ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr()) - if hs := opts.baseConfig(); hs != nil { - ctx = context.WithValue(ctx, http.ServerContextKey, hs) - } - return -} - -func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) { - return context.WithCancel(ctx) -} - -func requestWithContext(req *http.Request, ctx contextContext) *http.Request { - return req.WithContext(ctx) -} - -type clientTrace httptrace.ClientTrace - -func reqContext(r *http.Request) context.Context { return r.Context() } - -func (t *Transport) idleConnTimeout() time.Duration { - if t.t1 != nil { - return t.t1.IdleConnTimeout - } - return 0 -} - -func setResponseUncompressed(res *http.Response) { res.Uncompressed = true } - -func traceGotConn(req *http.Request, cc *ClientConn) { - trace := httptrace.ContextClientTrace(req.Context()) - if trace == nil || trace.GotConn == nil { - return - } - ci := httptrace.GotConnInfo{Conn: cc.tconn} - cc.mu.Lock() - ci.Reused = cc.nextStreamID > 1 - ci.WasIdle = len(cc.streams) == 0 && ci.Reused - if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = time.Now().Sub(cc.lastActive) - } - cc.mu.Unlock() - - trace.GotConn(ci) -} - -func traceWroteHeaders(trace *clientTrace) { - if trace != nil && trace.WroteHeaders != nil { - trace.WroteHeaders() - } -} - -func traceGot100Continue(trace *clientTrace) { - if trace != nil && trace.Got100Continue != nil { - trace.Got100Continue() - } -} - -func traceWait100Continue(trace *clientTrace) { - if trace != nil && trace.Wait100Continue != nil { - trace.Wait100Continue() - } -} - -func traceWroteRequest(trace *clientTrace, err error) { - if trace != nil && trace.WroteRequest != nil { - trace.WroteRequest(httptrace.WroteRequestInfo{Err: err}) - } -} - -func traceFirstResponseByte(trace *clientTrace) { - if trace != nil && trace.GotFirstResponseByte != nil { - trace.GotFirstResponseByte() - } -} - -func requestTrace(req *http.Request) *clientTrace { - trace := httptrace.ContextClientTrace(req.Context()) - return (*clientTrace)(trace) -} - -// Ping sends a PING frame to the server and waits for the ack. -func (cc *ClientConn) Ping(ctx context.Context) error { - return cc.ping(ctx) -} diff --git a/vendor/golang.org/x/net/http2/go17_not18.go b/vendor/golang.org/x/net/http2/go17_not18.go deleted file mode 100644 index b4c52ecec..000000000 --- a/vendor/golang.org/x/net/http2/go17_not18.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.7,!go1.8 - -package http2 - -import "crypto/tls" - -// temporary copy of Go 1.7's private tls.Config.clone: -func cloneTLSConfig(c *tls.Config) *tls.Config { - return &tls.Config{ - Rand: c.Rand, - Time: c.Time, - Certificates: c.Certificates, - NameToCertificate: c.NameToCertificate, - GetCertificate: c.GetCertificate, - RootCAs: c.RootCAs, - NextProtos: c.NextProtos, - ServerName: c.ServerName, - ClientAuth: c.ClientAuth, - ClientCAs: c.ClientCAs, - InsecureSkipVerify: c.InsecureSkipVerify, - CipherSuites: c.CipherSuites, - PreferServerCipherSuites: c.PreferServerCipherSuites, - SessionTicketsDisabled: c.SessionTicketsDisabled, - SessionTicketKey: c.SessionTicketKey, - ClientSessionCache: c.ClientSessionCache, - MinVersion: c.MinVersion, - MaxVersion: c.MaxVersion, - CurvePreferences: c.CurvePreferences, - DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, - Renegotiation: c.Renegotiation, - } -} diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go deleted file mode 100644 index 4f30d228a..000000000 --- a/vendor/golang.org/x/net/http2/go18.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.8 - -package http2 - -import ( - "crypto/tls" - "io" - "net/http" -) - -func cloneTLSConfig(c *tls.Config) *tls.Config { - c2 := c.Clone() - c2.GetClientCertificate = c.GetClientCertificate // golang.org/issue/19264 - return c2 -} - -var _ http.Pusher = (*responseWriter)(nil) - -// Push implements http.Pusher. -func (w *responseWriter) Push(target string, opts *http.PushOptions) error { - internalOpts := pushOptions{} - if opts != nil { - internalOpts.Method = opts.Method - internalOpts.Header = opts.Header - } - return w.push(target, internalOpts) -} - -func configureServer18(h1 *http.Server, h2 *Server) error { - if h2.IdleTimeout == 0 { - if h1.IdleTimeout != 0 { - h2.IdleTimeout = h1.IdleTimeout - } else { - h2.IdleTimeout = h1.ReadTimeout - } - } - return nil -} - -func shouldLogPanic(panicValue interface{}) bool { - return panicValue != nil && panicValue != http.ErrAbortHandler -} - -func reqGetBody(req *http.Request) func() (io.ReadCloser, error) { - return req.GetBody -} - -func reqBodyIsNoBody(body io.ReadCloser) bool { - return body == http.NoBody -} - -func go18httpNoBody() io.ReadCloser { return http.NoBody } // for tests only diff --git a/vendor/golang.org/x/net/http2/go19.go b/vendor/golang.org/x/net/http2/go19.go deleted file mode 100644 index 38124ba56..000000000 --- a/vendor/golang.org/x/net/http2/go19.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.9 - -package http2 - -import ( - "net/http" -) - -func configureServer19(s *http.Server, conf *Server) error { - s.RegisterOnShutdown(conf.state.startGracefulShutdown) - return nil -} diff --git a/pkg/h2c/h2c.go b/vendor/golang.org/x/net/http2/h2c/h2c.go similarity index 77% rename from pkg/h2c/h2c.go rename to vendor/golang.org/x/net/http2/h2c/h2c.go index 9277c9787..07c5c9a60 100644 --- a/pkg/h2c/h2c.go +++ b/vendor/golang.org/x/net/http2/h2c/h2c.go @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package h2c implements the h2c part of HTTP/2. +// Package h2c implements the unencrypted "h2c" form of HTTP/2. // -// The h2c protocol is the non-TLS secured version of HTTP/2 which is not -// available from net/http. +// The h2c protocol is the non-TLS version of HTTP/2 which is not available from +// net/http or golang.org/x/net/http2. package h2c import ( @@ -16,14 +16,13 @@ import ( "errors" "fmt" "io" + "log" "net" "net/http" "net/textproto" "os" "strings" - "github.com/containous/traefik/pkg/log" - "golang.org/x/net/http/httpguts" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" @@ -40,44 +39,64 @@ func init() { } } -// Server implements net.Handler and enables h2c. Users who want h2c just need -// to provide an http.Server. -type Server struct { - *http.Server +// h2cHandler is a Handler which implements h2c by hijacking the HTTP/1 traffic +// that should be h2c traffic. There are two ways to begin a h2c connection +// (RFC 7540 Section 3.2 and 3.4): (1) Starting with Prior Knowledge - this +// works by starting an h2c connection with a string of bytes that is valid +// HTTP/1, but unlikely to occur in practice and (2) Upgrading from HTTP/1 to +// h2c - this works by using the HTTP/1 Upgrade header to request an upgrade to +// h2c. When either of those situations occur we hijack the HTTP/1 connection, +// convert it to a HTTP/2 connection and pass the net.Conn to http2.ServeConn. +type h2cHandler struct { + Handler http.Handler + s *http2.Server } -// Serve Put a middleware around the original handler to handle h2c -func (s Server) Serve(l net.Listener) error { - originalHandler := s.Server.Handler - if originalHandler == nil { - originalHandler = http.DefaultServeMux +// NewHandler returns an http.Handler that wraps h, intercepting any h2c +// traffic. If a request is an h2c connection, it's hijacked and redirected to +// s.ServeConn. Otherwise the returned Handler just forwards requests to h. This +// works because h2c is designed to be parseable as valid HTTP/1, but ignored by +// any HTTP server that does not handle h2c. Therefore we leverage the HTTP/1 +// compatible parts of the Go http library to parse and recognize h2c requests. +// Once a request is recognized as h2c, we hijack the connection and convert it +// to an HTTP/2 connection which is understandable to s.ServeConn. (s.ServeConn +// understands HTTP/2 except for the h2c part of it.) +func NewHandler(h http.Handler, s *http2.Server) http.Handler { + return &h2cHandler{ + Handler: h, + s: s, } - s.Server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "PRI" && r.URL.Path == "*" && r.Proto == "HTTP/2.0" { +} + +// ServeHTTP implement the h2c support that is enabled by h2c.GetH2CHandler. +func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Handle h2c with prior knowledge (RFC 7540 Section 3.4) + if r.Method == "PRI" && len(r.Header) == 0 && r.URL.Path == "*" && r.Proto == "HTTP/2.0" { + if http2VerboseLogs { + log.Print("h2c: attempting h2c with prior knowledge.") + } + conn, err := initH2CWithPriorKnowledge(w) + if err != nil { if http2VerboseLogs { - log.Debugf("Attempting h2c with prior knowledge.") + log.Printf("h2c: error h2c with prior knowledge: %v", err) } - conn, err := initH2CWithPriorKnowledge(w) - if err != nil { - if http2VerboseLogs { - log.Debugf("Error h2c with prior knowledge: %v", err) - } - return - } - defer conn.Close() - h2cSrv := &http2.Server{} - h2cSrv.ServeConn(conn, &http2.ServeConnOpts{Handler: originalHandler}) return } - if conn, err := h2cUpgrade(w, r); err == nil { - defer conn.Close() - h2cSrv := &http2.Server{} - h2cSrv.ServeConn(conn, &http2.ServeConnOpts{Handler: originalHandler}) - return - } - originalHandler.ServeHTTP(w, r) - }) - return s.Server.Serve(l) + defer conn.Close() + + s.s.ServeConn(conn, &http2.ServeConnOpts{Handler: s.Handler}) + return + } + // Handle Upgrade to h2c (RFC 7540 Section 3.2) + if conn, err := h2cUpgrade(w, r); err == nil { + defer conn.Close() + + s.s.ServeConn(conn, &http2.ServeConnOpts{Handler: s.Handler}) + return + } + + s.Handler.ServeHTTP(w, r) + return } // initH2CWithPriorKnowledge implements creating a h2c connection with prior @@ -88,25 +107,25 @@ func (s Server) Serve(l net.Listener) error { func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) { hijacker, ok := w.(http.Hijacker) if !ok { - return nil, errors.New("hijack not supported") + panic("Hijack not supported.") } conn, rw, err := hijacker.Hijack() if err != nil { - return nil, fmt.Errorf("hijack failed: %v", err) + panic(fmt.Sprintf("Hijack failed: %v", err)) } - expectedBody := "SM\r\n\r\n" + const expectedBody = "SM\r\n\r\n" buf := make([]byte, len(expectedBody)) n, err := io.ReadFull(rw, buf) if err != nil { - return nil, fmt.Errorf("fail to read body: %v", err) + return nil, fmt.Errorf("could not read from the buffer: %s", err) } - if bytes.Equal(buf[0:n], []byte(expectedBody)) { + if string(buf[:n]) == expectedBody { c := &rwConn{ Conn: conn, - Reader: io.MultiReader(bytes.NewBuffer([]byte(http2.ClientPreface)), rw), + Reader: io.MultiReader(strings.NewReader(http2.ClientPreface), rw), BufWriter: rw.Writer, } return c, nil @@ -114,8 +133,8 @@ func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) { conn.Close() if http2VerboseLogs { - log.Infof( - "Missing the request body portion of the client preface. Wanted: %v Got: %v", + log.Printf( + "h2c: missing the request body portion of the client preface. Wanted: %v Got: %v", []byte(expectedBody), buf[0:n], ) @@ -127,13 +146,13 @@ func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) { // the supplied reader. func drainClientPreface(r io.Reader) error { var buf bytes.Buffer - prefaceLen := int64(len([]byte(http2.ClientPreface))) + prefaceLen := int64(len(http2.ClientPreface)) n, err := io.CopyN(&buf, r, prefaceLen) if err != nil { return err } if n != prefaceLen || buf.String() != http2.ClientPreface { - return fmt.Errorf("client never sent: %s", http2.ClientPreface) + return fmt.Errorf("Client never sent: %s", http2.ClientPreface) } return nil } @@ -152,7 +171,7 @@ func h2cUpgrade(w http.ResponseWriter, r *http.Request) (net.Conn, error) { hijacker, ok := w.(http.Hijacker) if !ok { - return nil, errors.New("hijack not supported") + return nil, errors.New("hijack not supported.") } conn, rw, err := hijacker.Hijack() if err != nil { @@ -277,7 +296,7 @@ func (c *rwConn) Write(p []byte) (int, error) { return n, err } -// settingsAckSwallowWriter is a writer that normally forwards bytes to it's +// settingsAckSwallowWriter is a writer that normally forwards bytes to its // underlying Writer, but swallows the first SettingsAck frame that it sees. type settingsAckSwallowWriter struct { Writer *bufio.Writer @@ -313,7 +332,7 @@ func (w *settingsAckSwallowWriter) Write(p []byte) (int, error) { } fSize := fh.Length + 9 if uint32(len(w.buf)) < fSize { - // Have not collected whole frame. Stop processing buf, and withhold on + // Have not collected whole frame. Stop processing buf, and withold on // forward bytes to w.Writer until we get the full frame. break } @@ -364,7 +383,7 @@ func getH2Settings(h http.Header) ([]http2.Setting, error) { } settings, err := decodeSettings(vals[0]) if err != nil { - return nil, fmt.Errorf("invalid HTTP2-Settings: %q", vals[0]) + return nil, fmt.Errorf("Invalid HTTP2-Settings: %q", vals[0]) } return settings, nil } diff --git a/vendor/golang.org/x/net/http2/headermap.go b/vendor/golang.org/x/net/http2/headermap.go index c2805f6ac..c3ff3fa1c 100644 --- a/vendor/golang.org/x/net/http2/headermap.go +++ b/vendor/golang.org/x/net/http2/headermap.go @@ -7,15 +7,21 @@ package http2 import ( "net/http" "strings" + "sync" ) var ( - commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case - commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case + commonBuildOnce sync.Once + commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case + commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case ) -func init() { - for _, v := range []string{ +func buildCommonHeaderMapsOnce() { + commonBuildOnce.Do(buildCommonHeaderMaps) +} + +func buildCommonHeaderMaps() { + common := []string{ "accept", "accept-charset", "accept-encoding", @@ -63,7 +69,10 @@ func init() { "vary", "via", "www-authenticate", - } { + } + commonLowerHeader = make(map[string]string, len(common)) + commonCanonHeader = make(map[string]string, len(common)) + for _, v := range common { chk := http.CanonicalHeaderKey(v) commonLowerHeader[chk] = v commonCanonHeader[v] = chk @@ -71,6 +80,7 @@ func init() { } func lowerHeader(v string) string { + buildCommonHeaderMapsOnce() if s, ok := commonLowerHeader[v]; ok { return s } diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index 166788cee..85f18a2b0 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -92,6 +92,8 @@ type Decoder struct { // saveBuf is previous data passed to Write which we weren't able // to fully parse before. Unlike buf, we own this data. saveBuf bytes.Buffer + + firstField bool // processing the first field of the header block } // NewDecoder returns a new decoder with the provided maximum dynamic @@ -101,6 +103,7 @@ func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decod d := &Decoder{ emit: emitFunc, emitEnabled: true, + firstField: true, } d.dynTab.table.init() d.dynTab.allowedMaxSize = maxDynamicTableSize @@ -226,11 +229,15 @@ func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) { return hf, nil } +// Close declares that the decoding is complete and resets the Decoder +// to be reused again for a new header block. If there is any remaining +// data in the decoder's buffer, Close returns an error. func (d *Decoder) Close() error { if d.saveBuf.Len() > 0 { d.saveBuf.Reset() return DecodingError{errors.New("truncated headers")} } + d.firstField = true return nil } @@ -266,6 +273,7 @@ func (d *Decoder) Write(p []byte) (n int, err error) { d.saveBuf.Write(d.buf) return len(p), nil } + d.firstField = false if err != nil { break } @@ -391,7 +399,7 @@ func (d *Decoder) callEmit(hf HeaderField) error { func (d *Decoder) parseDynamicTableSizeUpdate() error { // RFC 7541, sec 4.2: This dynamic table size update MUST occur at the // beginning of the first header block following the change to the dynamic table size. - if d.dynTab.size > 0 { + if !d.firstField && d.dynTab.size > 0 { return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")} } diff --git a/vendor/golang.org/x/net/http2/hpack/huffman.go b/vendor/golang.org/x/net/http2/hpack/huffman.go index 8850e3946..b412a96c5 100644 --- a/vendor/golang.org/x/net/http2/hpack/huffman.go +++ b/vendor/golang.org/x/net/http2/hpack/huffman.go @@ -47,6 +47,7 @@ var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data") // If maxLen is greater than 0, attempts to write more to buf than // maxLen bytes will return ErrStringLength. func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { + rootHuffmanNode := getRootHuffmanNode() n := rootHuffmanNode // cur is the bit buffer that has not been fed into n. // cbits is the number of low order bits in cur that are valid. @@ -106,7 +107,7 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { type node struct { // children is non-nil for internal nodes - children []*node + children *[256]*node // The following are only valid if children is nil: codeLen uint8 // number of bits that led to the output of sym @@ -114,22 +115,31 @@ type node struct { } func newInternalNode() *node { - return &node{children: make([]*node, 256)} + return &node{children: new([256]*node)} } -var rootHuffmanNode = newInternalNode() +var ( + buildRootOnce sync.Once + lazyRootHuffmanNode *node +) -func init() { +func getRootHuffmanNode() *node { + buildRootOnce.Do(buildRootHuffmanNode) + return lazyRootHuffmanNode +} + +func buildRootHuffmanNode() { if len(huffmanCodes) != 256 { panic("unexpected size") } + lazyRootHuffmanNode = newInternalNode() for i, code := range huffmanCodes { addDecoderNode(byte(i), code, huffmanCodeLen[i]) } } func addDecoderNode(sym byte, code uint32, codeLen uint8) { - cur := rootHuffmanNode + cur := lazyRootHuffmanNode for codeLen > 8 { codeLen -= 8 i := uint8(code >> codeLen) diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index c82428254..bdaba1d46 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -201,19 +201,12 @@ func validWireHeaderFieldName(v string) bool { return true } -var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n) - -func init() { - for i := 100; i <= 999; i++ { - if v := http.StatusText(i); v != "" { - httpCodeStringCommon[i] = strconv.Itoa(i) - } - } -} - func httpCodeString(code int) string { - if s, ok := httpCodeStringCommon[code]; ok { - return s + switch code { + case 200: + return "200" + case 404: + return "404" } return strconv.Itoa(code) } diff --git a/vendor/golang.org/x/net/http2/not_go111.go b/vendor/golang.org/x/net/http2/not_go111.go new file mode 100644 index 000000000..161bca7ce --- /dev/null +++ b/vendor/golang.org/x/net/http2/not_go111.go @@ -0,0 +1,20 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.11 + +package http2 + +import ( + "net/http/httptrace" + "net/textproto" +) + +func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { return false } + +func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {} + +func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { + return nil +} diff --git a/vendor/golang.org/x/net/http2/not_go16.go b/vendor/golang.org/x/net/http2/not_go16.go deleted file mode 100644 index 508cebcc4..000000000 --- a/vendor/golang.org/x/net/http2/not_go16.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.6 - -package http2 - -import ( - "net/http" - "time" -) - -func configureTransport(t1 *http.Transport) (*Transport, error) { - return nil, errTransportVersion -} - -func transportExpectContinueTimeout(t1 *http.Transport) time.Duration { - return 0 - -} diff --git a/vendor/golang.org/x/net/http2/not_go17.go b/vendor/golang.org/x/net/http2/not_go17.go deleted file mode 100644 index 140434a79..000000000 --- a/vendor/golang.org/x/net/http2/not_go17.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.7 - -package http2 - -import ( - "crypto/tls" - "net" - "net/http" - "time" -) - -type contextContext interface { - Done() <-chan struct{} - Err() error -} - -type fakeContext struct{} - -func (fakeContext) Done() <-chan struct{} { return nil } -func (fakeContext) Err() error { panic("should not be called") } - -func reqContext(r *http.Request) fakeContext { - return fakeContext{} -} - -func setResponseUncompressed(res *http.Response) { - // Nothing. -} - -type clientTrace struct{} - -func requestTrace(*http.Request) *clientTrace { return nil } -func traceGotConn(*http.Request, *ClientConn) {} -func traceFirstResponseByte(*clientTrace) {} -func traceWroteHeaders(*clientTrace) {} -func traceWroteRequest(*clientTrace, error) {} -func traceGot100Continue(trace *clientTrace) {} -func traceWait100Continue(trace *clientTrace) {} - -func nop() {} - -func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) { - return nil, nop -} - -func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) { - return ctx, nop -} - -func requestWithContext(req *http.Request, ctx contextContext) *http.Request { - return req -} - -// temporary copy of Go 1.6's private tls.Config.clone: -func cloneTLSConfig(c *tls.Config) *tls.Config { - return &tls.Config{ - Rand: c.Rand, - Time: c.Time, - Certificates: c.Certificates, - NameToCertificate: c.NameToCertificate, - GetCertificate: c.GetCertificate, - RootCAs: c.RootCAs, - NextProtos: c.NextProtos, - ServerName: c.ServerName, - ClientAuth: c.ClientAuth, - ClientCAs: c.ClientCAs, - InsecureSkipVerify: c.InsecureSkipVerify, - CipherSuites: c.CipherSuites, - PreferServerCipherSuites: c.PreferServerCipherSuites, - SessionTicketsDisabled: c.SessionTicketsDisabled, - SessionTicketKey: c.SessionTicketKey, - ClientSessionCache: c.ClientSessionCache, - MinVersion: c.MinVersion, - MaxVersion: c.MaxVersion, - CurvePreferences: c.CurvePreferences, - } -} - -func (cc *ClientConn) Ping(ctx contextContext) error { - return cc.ping(ctx) -} - -func (t *Transport) idleConnTimeout() time.Duration { return 0 } diff --git a/vendor/golang.org/x/net/http2/not_go18.go b/vendor/golang.org/x/net/http2/not_go18.go deleted file mode 100644 index 6f8d3f86f..000000000 --- a/vendor/golang.org/x/net/http2/not_go18.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.8 - -package http2 - -import ( - "io" - "net/http" -) - -func configureServer18(h1 *http.Server, h2 *Server) error { - // No IdleTimeout to sync prior to Go 1.8. - return nil -} - -func shouldLogPanic(panicValue interface{}) bool { - return panicValue != nil -} - -func reqGetBody(req *http.Request) func() (io.ReadCloser, error) { - return nil -} - -func reqBodyIsNoBody(io.ReadCloser) bool { return false } - -func go18httpNoBody() io.ReadCloser { return nil } // for tests only diff --git a/vendor/golang.org/x/net/http2/not_go19.go b/vendor/golang.org/x/net/http2/not_go19.go deleted file mode 100644 index 5ae07726b..000000000 --- a/vendor/golang.org/x/net/http2/not_go19.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 - -package http2 - -import ( - "net/http" -) - -func configureServer19(s *http.Server, conf *Server) error { - // not supported prior to go1.9 - return nil -} diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 769c0fe5e..57334dc79 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -28,6 +28,7 @@ package http2 import ( "bufio" "bytes" + "context" "crypto/tls" "errors" "fmt" @@ -209,12 +210,14 @@ func ConfigureServer(s *http.Server, conf *Server) error { conf = new(Server) } conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} - if err := configureServer18(s, conf); err != nil { - return err - } - if err := configureServer19(s, conf); err != nil { - return err + if h1, h2 := s, conf; h2.IdleTimeout == 0 { + if h1.IdleTimeout != 0 { + h2.IdleTimeout = h1.IdleTimeout + } else { + h2.IdleTimeout = h1.ReadTimeout + } } + s.RegisterOnShutdown(conf.state.startGracefulShutdown) if s.TLSConfig == nil { s.TLSConfig = new(tls.Config) @@ -270,7 +273,20 @@ func ConfigureServer(s *http.Server, conf *Server) error { if testHookOnConn != nil { testHookOnConn() } + // The TLSNextProto interface predates contexts, so + // the net/http package passes down its per-connection + // base context via an exported but unadvertised + // method on the Handler. This is for internal + // net/http<=>http2 use only. + var ctx context.Context + type baseContexter interface { + BaseContext() context.Context + } + if bc, ok := h.(baseContexter); ok { + ctx = bc.BaseContext() + } conf.ServeConn(c, &ServeConnOpts{ + Context: ctx, Handler: h, BaseConfig: hs, }) @@ -281,6 +297,10 @@ func ConfigureServer(s *http.Server, conf *Server) error { // ServeConnOpts are options for the Server.ServeConn method. type ServeConnOpts struct { + // Context is the base context to use. + // If nil, context.Background is used. + Context context.Context + // BaseConfig optionally sets the base configuration // for values. If nil, defaults are used. BaseConfig *http.Server @@ -291,6 +311,13 @@ type ServeConnOpts struct { Handler http.Handler } +func (o *ServeConnOpts) context() context.Context { + if o.Context != nil { + return o.Context + } + return context.Background() +} + func (o *ServeConnOpts) baseConfig() *http.Server { if o != nil && o.BaseConfig != nil { return o.BaseConfig @@ -435,6 +462,15 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { sc.serve() } +func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) { + ctx, cancel = context.WithCancel(opts.context()) + ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr()) + if hs := opts.baseConfig(); hs != nil { + ctx = context.WithValue(ctx, http.ServerContextKey, hs) + } + return +} + func (sc *serverConn) rejectConn(err ErrCode, debug string) { sc.vlogf("http2: server rejecting conn: %v, %s", err, debug) // ignoring errors. hanging up anyway. @@ -450,7 +486,7 @@ type serverConn struct { conn net.Conn bw *bufferedWriter // writing to conn handler http.Handler - baseCtx contextContext + baseCtx context.Context framer *Framer doneServing chan struct{} // closed when serverConn.serve ends readFrameCh chan readFrameResult // written by serverConn.readFrames @@ -530,7 +566,7 @@ type stream struct { id uint32 body *pipe // non-nil if expecting DATA frames cw closeWaiter // closed wait stream transitions to closed state - ctx contextContext + ctx context.Context cancelCtx func() // owned by serverConn's serve loop: @@ -663,6 +699,7 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) { func (sc *serverConn) canonicalHeader(v string) string { sc.serveG.check() + buildCommonHeaderMapsOnce() cv, ok := commonCanonHeader[v] if ok { return cv @@ -1109,7 +1146,7 @@ func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) { // errHandlerPanicked is the error given to any callers blocked in a read from // Request.Body when the main goroutine panics. Since most handlers read in the -// the main ServeHTTP goroutine, this will show up rarely. +// main ServeHTTP goroutine, this will show up rarely. var errHandlerPanicked = errors.New("http2: handler panicked") // wroteFrame is called on the serve goroutine with the result of @@ -1487,6 +1524,12 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error { } return nil } + if f.NumSettings() > 100 || f.HasDuplicates() { + // This isn't actually in the spec, but hang up on + // suspiciously large settings frames or those with + // duplicate entries. + return ConnectionError(ErrCodeProtocol) + } if err := f.ForeachSetting(sc.processSetting); err != nil { return err } @@ -1721,6 +1764,13 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // processing this frame. return nil } + // RFC 7540, sec 5.1: If an endpoint receives additional frames, other than + // WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in + // this state, it MUST respond with a stream error (Section 5.4.2) of + // type STREAM_CLOSED. + if st.state == stateHalfClosedRemote { + return streamError(id, ErrCodeStreamClosed) + } return st.processTrailerHeaders(f) } @@ -1862,7 +1912,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream panic("internal error: cannot create stream with id 0") } - ctx, cancelCtx := contextWithCancel(sc.baseCtx) + ctx, cancelCtx := context.WithCancel(sc.baseCtx) st := &stream{ sc: sc, id: id, @@ -2028,7 +2078,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r Body: body, Trailer: trailer, } - req = requestWithContext(req, st.ctx) + req = req.WithContext(st.ctx) rws := responseWriterStatePool.Get().(*responseWriterState) bwSave := rws.bw @@ -2056,7 +2106,7 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler stream: rw.rws.stream, }) // Same as net/http: - if shouldLogPanic(e) { + if e != nil && e != http.ErrAbortHandler { const size = 64 << 10 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] @@ -2281,7 +2331,16 @@ type chunkWriter struct{ rws *responseWriterState } func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } -func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 } +func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 } + +func (rws *responseWriterState) hasNonemptyTrailers() bool { + for _, trailer := range rws.trailers { + if _, ok := rws.handlerHeader[trailer]; ok { + return true + } + } + return false +} // declareTrailer is called for each Trailer header when the // response header is written. It notes that a header will need to be @@ -2327,15 +2386,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { } _, hasContentType := rws.snapHeader["Content-Type"] if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 { - if cto := rws.snapHeader.Get("X-Content-Type-Options"); strings.EqualFold("nosniff", cto) { - // nosniff is an explicit directive not to guess a content-type. - // Content-sniffing is no less susceptible to polyglot attacks via - // hosted content when done on the server. - ctype = "application/octet-stream" - rws.conn.logf("http2: WriteHeader called with X-Content-Type-Options:nosniff but no Content-Type") - } else { - ctype = http.DetectContentType(p) - } + ctype = http.DetectContentType(p) } var date string if _, ok := rws.snapHeader["Date"]; !ok { @@ -2347,6 +2398,19 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { foreachHeaderElement(v, rws.declareTrailer) } + // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2), + // but respect "Connection" == "close" to mean sending a GOAWAY and tearing + // down the TCP connection when idle, like we do for HTTP/1. + // TODO: remove more Connection-specific header fields here, in addition + // to "Connection". + if _, ok := rws.snapHeader["Connection"]; ok { + v := rws.snapHeader.Get("Connection") + delete(rws.snapHeader, "Connection") + if v == "close" { + rws.conn.startGracefulShutdown() + } + } + endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ streamID: rws.stream.id, @@ -2376,7 +2440,10 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { rws.promoteUndeclaredTrailers() } - endStream := rws.handlerDone && !rws.hasTrailers() + // only send trailers if they have actually been defined by the + // server handler. + hasNonemptyTrailers := rws.hasNonemptyTrailers() + endStream := rws.handlerDone && !hasNonemptyTrailers if len(p) > 0 || endStream { // only send a 0 byte DATA frame if we're ending the stream. if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil { @@ -2385,7 +2452,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { } } - if rws.handlerDone && rws.hasTrailers() { + if rws.handlerDone && hasNonemptyTrailers { err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ streamID: rws.stream.id, h: rws.handlerHeader, @@ -2613,14 +2680,9 @@ var ( ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS") ) -// pushOptions is the internal version of http.PushOptions, which we -// cannot include here because it's only defined in Go 1.8 and later. -type pushOptions struct { - Method string - Header http.Header -} +var _ http.Pusher = (*responseWriter)(nil) -func (w *responseWriter) push(target string, opts pushOptions) error { +func (w *responseWriter) Push(target string, opts *http.PushOptions) error { st := w.rws.stream sc := st.sc sc.serveG.checkNotOn() @@ -2631,6 +2693,10 @@ func (w *responseWriter) push(target string, opts pushOptions) error { return ErrRecursivePush } + if opts == nil { + opts = new(http.PushOptions) + } + // Default options. if opts.Method == "" { opts.Method = "GET" diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index d23a22625..c0c80d893 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -10,6 +10,7 @@ import ( "bufio" "bytes" "compress/gzip" + "context" "crypto/rand" "crypto/tls" "errors" @@ -21,10 +22,13 @@ import ( mathrand "math/rand" "net" "net/http" + "net/http/httptrace" + "net/textproto" "sort" "strconv" "strings" "sync" + "sync/atomic" "time" "golang.org/x/net/http/httpguts" @@ -94,6 +98,16 @@ type Transport struct { // to mean no limit. MaxHeaderListSize uint32 + // StrictMaxConcurrentStreams controls whether the server's + // SETTINGS_MAX_CONCURRENT_STREAMS should be respected + // globally. If false, new TCP connections are created to the + // server as needed to keep each under the per-connection + // SETTINGS_MAX_CONCURRENT_STREAMS limit. If true, the + // server's SETTINGS_MAX_CONCURRENT_STREAMS is interpreted as + // a global limit and callers of RoundTrip block when needed, + // waiting for their turn. + StrictMaxConcurrentStreams bool + // t1, if non-nil, is the standard library Transport using // this transport. Its settings are used (but not its // RoundTrip method, etc). @@ -117,16 +131,56 @@ func (t *Transport) disableCompression() bool { return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression) } -var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6") - // ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2. -// It requires Go 1.6 or later and returns an error if the net/http package is too old -// or if t1 has already been HTTP/2-enabled. +// It returns an error if t1 has already been HTTP/2-enabled. func ConfigureTransport(t1 *http.Transport) error { - _, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go + _, err := configureTransport(t1) return err } +func configureTransport(t1 *http.Transport) (*Transport, error) { + connPool := new(clientConnPool) + t2 := &Transport{ + ConnPool: noDialClientConnPool{connPool}, + t1: t1, + } + connPool.t = t2 + if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil { + return nil, err + } + if t1.TLSClientConfig == nil { + t1.TLSClientConfig = new(tls.Config) + } + if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") { + t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...) + } + if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") { + t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1") + } + upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper { + addr := authorityAddr("https", authority) + if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil { + go c.Close() + return erringRoundTripper{err} + } else if !used { + // Turns out we don't need this c. + // For example, two goroutines made requests to the same host + // at the same time, both kicking off TCP dials. (since protocol + // was unknown) + go c.Close() + } + return t2 + } + if m := t1.TLSNextProto; len(m) == 0 { + t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{ + "h2": upgradeFn, + } + } else { + m["h2"] = upgradeFn + } + return t2, nil +} + func (t *Transport) connPool() ClientConnPool { t.connPoolOnce.Do(t.initConnPool) return t.connPoolOrDef @@ -146,6 +200,7 @@ type ClientConn struct { t *Transport tconn net.Conn // usually *tls.Conn, except specialized impls tlsState *tls.ConnectionState // nil only for specialized impls + reused uint32 // whether conn is being reused; atomic singleUse bool // whether being used for a single http.Request // readLoop goroutine fields: @@ -159,6 +214,7 @@ type ClientConn struct { cond *sync.Cond // hold mu; broadcast on flow/closed changes flow flow // our conn-level flow control quota (cs.flow is per stream) inflow flow // peer's conn-level flow control + closing bool closed bool wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received @@ -190,7 +246,7 @@ type ClientConn struct { type clientStream struct { cc *ClientConn req *http.Request - trace *clientTrace // or nil + trace *httptrace.ClientTrace // or nil ID uint32 resc chan resAndError bufPipe pipe // buffered pipe with the flow-controlled response payload @@ -211,9 +267,10 @@ type clientStream struct { done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu // owned by clientConnReadLoop: - firstByte bool // got the first response byte - pastHeaders bool // got first MetaHeadersFrame (actual headers) - pastTrailers bool // got optional second MetaHeadersFrame (trailers) + firstByte bool // got the first response byte + pastHeaders bool // got first MetaHeadersFrame (actual headers) + pastTrailers bool // got optional second MetaHeadersFrame (trailers) + num1xx uint8 // number of 1xx responses seen trailer http.Header // accumulated trailers resTrailer *http.Header // client's Response.Trailer @@ -223,7 +280,7 @@ type clientStream struct { // channel to be signaled. A non-nil error is returned only if the request was // canceled. func awaitRequestCancel(req *http.Request, done <-chan struct{}) error { - ctx := reqContext(req) + ctx := req.Context() if req.Cancel == nil && ctx.Done() == nil { return nil } @@ -237,6 +294,17 @@ func awaitRequestCancel(req *http.Request, done <-chan struct{}) error { } } +var got1xxFuncForTests func(int, textproto.MIMEHeader) error + +// get1xxTraceFunc returns the value of request's httptrace.ClientTrace.Got1xxResponse func, +// if any. It returns nil if not set or if the Go version is too old. +func (cs *clientStream) get1xxTraceFunc() func(int, textproto.MIMEHeader) error { + if fn := got1xxFuncForTests; fn != nil { + return fn + } + return traceGot1xxResponseFunc(cs.trace) +} + // awaitRequestCancel waits for the user to cancel a request, its context to // expire, or for the request to be done (any way it might be removed from the // cc.streams map: peer reset, successful completion, TCP connection breakage, @@ -374,7 +442,8 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err) return nil, err } - traceGotConn(req, cc) + reused := !atomic.CompareAndSwapUint32(&cc.reused, 0, 1) + traceGotConn(req, cc, reused) res, gotErrAfterReqBodyWrite, err := cc.roundTrip(req) if err != nil && retry <= 6 { if req, err = shouldRetryRequest(req, err, gotErrAfterReqBodyWrite); err == nil { @@ -387,8 +456,8 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res select { case <-time.After(time.Second * time.Duration(backoff)): continue - case <-reqContext(req).Done(): - return nil, reqContext(req).Err() + case <-req.Context().Done(): + return nil, req.Context().Err() } } } @@ -423,27 +492,35 @@ func shouldRetryRequest(req *http.Request, err error, afterBodyWrite bool) (*htt if !canRetryError(err) { return nil, err } + // If the Body is nil (or http.NoBody), it's safe to reuse + // this request and its Body. + if req.Body == nil || req.Body == http.NoBody { + return req, nil + } + + // If the request body can be reset back to its original + // state via the optional req.GetBody, do that. + if req.GetBody != nil { + // TODO: consider a req.Body.Close here? or audit that all caller paths do? + body, err := req.GetBody() + if err != nil { + return nil, err + } + newReq := *req + newReq.Body = body + return &newReq, nil + } + + // The Request.Body can't reset back to the beginning, but we + // don't seem to have started to read from it yet, so reuse + // the request directly. The "afterBodyWrite" means the + // bodyWrite process has started, which becomes true before + // the first Read. if !afterBodyWrite { return req, nil } - // If the Body is nil (or http.NoBody), it's safe to reuse - // this request and its Body. - if req.Body == nil || reqBodyIsNoBody(req.Body) { - return req, nil - } - // Otherwise we depend on the Request having its GetBody - // func defined. - getBody := reqGetBody(req) // Go 1.8: getBody = req.GetBody - if getBody == nil { - return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err) - } - body, err := getBody() - if err != nil { - return nil, err - } - newReq := *req - newReq.Body = body - return &newReq, nil + + return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err) } func canRetryError(err error) bool { @@ -471,7 +548,7 @@ func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, er func (t *Transport) newTLSConfig(host string) *tls.Config { cfg := new(tls.Config) if t.TLSClientConfig != nil { - *cfg = *cloneTLSConfig(t.TLSClientConfig) + *cfg = *t.TLSClientConfig.Clone() } if !strSliceContains(cfg.NextProtos, NextProtoTLS) { cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...) @@ -522,7 +599,7 @@ func (t *Transport) expectContinueTimeout() time.Duration { if t.t1 == nil { return 0 } - return transportExpectContinueTimeout(t.t1) + return t.t1.ExpectContinueTimeout } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { @@ -630,12 +707,43 @@ func (cc *ClientConn) CanTakeNewRequest() bool { return cc.canTakeNewRequestLocked() } -func (cc *ClientConn) canTakeNewRequestLocked() bool { +// clientConnIdleState describes the suitability of a client +// connection to initiate a new RoundTrip request. +type clientConnIdleState struct { + canTakeNewRequest bool + freshConn bool // whether it's unused by any previous request +} + +func (cc *ClientConn) idleState() clientConnIdleState { + cc.mu.Lock() + defer cc.mu.Unlock() + return cc.idleStateLocked() +} + +func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { if cc.singleUse && cc.nextStreamID > 1 { - return false + return } - return cc.goAway == nil && !cc.closed && - int64(cc.nextStreamID)+int64(cc.pendingRequests) < math.MaxInt32 + var maxConcurrentOkay bool + if cc.t.StrictMaxConcurrentStreams { + // We'll tell the caller we can take a new request to + // prevent the caller from dialing a new TCP + // connection, but then we'll block later before + // writing it. + maxConcurrentOkay = true + } else { + maxConcurrentOkay = int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) + } + + st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay && + int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 + st.freshConn = cc.nextStreamID == 1 && st.canTakeNewRequest + return +} + +func (cc *ClientConn) canTakeNewRequestLocked() bool { + st := cc.idleStateLocked() + return st.canTakeNewRequest } // onIdleTimeout is called from a time.AfterFunc goroutine. It will @@ -665,6 +773,87 @@ func (cc *ClientConn) closeIfIdle() { cc.tconn.Close() } +var shutdownEnterWaitStateHook = func() {} + +// Shutdown gracefully close the client connection, waiting for running streams to complete. +func (cc *ClientConn) Shutdown(ctx context.Context) error { + if err := cc.sendGoAway(); err != nil { + return err + } + // Wait for all in-flight streams to complete or connection to close + done := make(chan error, 1) + cancelled := false // guarded by cc.mu + go func() { + cc.mu.Lock() + defer cc.mu.Unlock() + for { + if len(cc.streams) == 0 || cc.closed { + cc.closed = true + done <- cc.tconn.Close() + break + } + if cancelled { + break + } + cc.cond.Wait() + } + }() + shutdownEnterWaitStateHook() + select { + case err := <-done: + return err + case <-ctx.Done(): + cc.mu.Lock() + // Free the goroutine above + cancelled = true + cc.cond.Broadcast() + cc.mu.Unlock() + return ctx.Err() + } +} + +func (cc *ClientConn) sendGoAway() error { + cc.mu.Lock() + defer cc.mu.Unlock() + cc.wmu.Lock() + defer cc.wmu.Unlock() + if cc.closing { + // GOAWAY sent already + return nil + } + // Send a graceful shutdown frame to server + maxStreamID := cc.nextStreamID + if err := cc.fr.WriteGoAway(maxStreamID, ErrCodeNo, nil); err != nil { + return err + } + if err := cc.bw.Flush(); err != nil { + return err + } + // Prevent new requests + cc.closing = true + return nil +} + +// Close closes the client connection immediately. +// +// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead. +func (cc *ClientConn) Close() error { + cc.mu.Lock() + defer cc.cond.Broadcast() + defer cc.mu.Unlock() + err := errors.New("http2: client connection force closed via ClientConn.Close") + for id, cs := range cc.streams { + select { + case cs.resc <- resAndError{err: err}: + default: + } + cs.bufPipe.CloseWithError(err) + delete(cc.streams, id) + } + cc.closed = true + return cc.tconn.Close() +} + const maxAllocFrameSize = 512 << 10 // frameBuffer returns a scratch buffer suitable for writing DATA frames. @@ -747,7 +936,7 @@ func checkConnHeaders(req *http.Request) error { if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv) } - if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "close" && vv[0] != "keep-alive") { + if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !strings.EqualFold(vv[0], "close") && !strings.EqualFold(vv[0], "keep-alive")) { return fmt.Errorf("http2: invalid Connection request header: %q", vv) } return nil @@ -757,7 +946,7 @@ func checkConnHeaders(req *http.Request) error { // req.ContentLength, where 0 actually means zero (not unknown) and -1 // means unknown. func actualContentLength(req *http.Request) int64 { - if req.Body == nil || reqBodyIsNoBody(req.Body) { + if req.Body == nil || req.Body == http.NoBody { return 0 } if req.ContentLength != 0 { @@ -827,7 +1016,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf cs := cc.newStream() cs.req = req - cs.trace = requestTrace(req) + cs.trace = httptrace.ContextClientTrace(req.Context()) cs.requestedGzip = requestedGzip bodyWriter := cc.t.getBodyWriterState(cs, body) cs.on100 = bodyWriter.on100 @@ -865,7 +1054,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf readLoopResCh := cs.resc bodyWritten := false - ctx := reqContext(req) + ctx := req.Context() handleReadLoopResponse := func(re resAndError) (*http.Response, bool, error) { res := re.res @@ -935,6 +1124,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf default: } if err != nil { + cc.forgetStreamID(cs.ID) return nil, cs.getStartedWrite(), err } bodyWritten = true @@ -1056,6 +1246,7 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( sawEOF = true err = nil } else if err != nil { + cc.writeStreamReset(cs.ID, ErrCodeCancel, err) return err } @@ -1223,7 +1414,11 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail // followed by the query production (see Sections 3.3 and 3.4 of // [RFC3986]). f(":authority", host) - f(":method", req.Method) + m := req.Method + if m == "" { + m = http.MethodGet + } + f(":method", m) if req.Method != "CONNECT" { f(":path", path) f(":scheme", req.URL.Scheme) @@ -1291,9 +1486,16 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail return nil, errRequestHeaderListSize } + trace := httptrace.ContextClientTrace(req.Context()) + traceHeaders := traceHasWroteHeaderField(trace) + // Header list size is ok. Write the headers. enumerateHeaders(func(name, value string) { - cc.writeHeader(strings.ToLower(name), value) + name = strings.ToLower(name) + cc.writeHeader(name, value) + if traceHeaders { + traceWroteHeaderField(trace, name, value) + } }) return cc.hbuf.Bytes(), nil @@ -1615,8 +1817,7 @@ func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { // is the detail. // // As a special case, handleResponse may return (nil, nil) to skip the -// frame (currently only used for 100 expect continue). This special -// case is going away after Issue 13851 is fixed. +// frame (currently only used for 1xx responses). func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) { if f.Truncated { return nil, errResponseHeaderListSize @@ -1631,15 +1832,6 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header") } - if statusCode == 100 { - traceGot100Continue(cs.trace) - if cs.on100 != nil { - cs.on100() // forces any write delay timer to fire - } - cs.pastHeaders = false // do it all again - return nil, nil - } - header := make(http.Header) res := &http.Response{ Proto: "HTTP/2.0", @@ -1664,6 +1856,27 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra } } + if statusCode >= 100 && statusCode <= 199 { + cs.num1xx++ + const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http + if cs.num1xx > max1xxResponses { + return nil, errors.New("http2: too many 1xx informational responses") + } + if fn := cs.get1xxTraceFunc(); fn != nil { + if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil { + return nil, err + } + } + if statusCode == 100 { + traceGot100Continue(cs.trace) + if cs.on100 != nil { + cs.on100() // forces any write delay timer to fire + } + } + cs.pastHeaders = false // do it all again + return nil, nil + } + streamEnded := f.StreamEnded() isHead := cs.req.Method == "HEAD" if !streamEnded || isHead { @@ -1696,7 +1909,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra res.Header.Del("Content-Length") res.ContentLength = -1 res.Body = &gzipReader{body: res.Body} - setResponseUncompressed(res) + res.Uncompressed = true } return res, nil } @@ -2073,8 +2286,7 @@ func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { } // Ping sends a PING frame to the server and waits for the ack. -// Public implementation is in go17.go and not_go17.go -func (cc *ClientConn) ping(ctx contextContext) error { +func (cc *ClientConn) Ping(ctx context.Context) error { c := make(chan struct{}) // Generate a random payload var p [8]byte @@ -2308,3 +2520,91 @@ func (s bodyWriterState) scheduleBodyWrite() { func isConnectionCloseRequest(req *http.Request) bool { return req.Close || httpguts.HeaderValuesContainsToken(req.Header["Connection"], "close") } + +// registerHTTPSProtocol calls Transport.RegisterProtocol but +// converting panics into errors. +func registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err error) { + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("%v", e) + } + }() + t.RegisterProtocol("https", rt) + return nil +} + +// noDialH2RoundTripper is a RoundTripper which only tries to complete the request +// if there's already has a cached connection to the host. +// (The field is exported so it can be accessed via reflect from net/http; tested +// by TestNoDialH2RoundTripperType) +type noDialH2RoundTripper struct{ *Transport } + +func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + res, err := rt.Transport.RoundTrip(req) + if isNoCachedConnError(err) { + return nil, http.ErrSkipAltProtocol + } + return res, err +} + +func (t *Transport) idleConnTimeout() time.Duration { + if t.t1 != nil { + return t.t1.IdleConnTimeout + } + return 0 +} + +func traceGetConn(req *http.Request, hostPort string) { + trace := httptrace.ContextClientTrace(req.Context()) + if trace == nil || trace.GetConn == nil { + return + } + trace.GetConn(hostPort) +} + +func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { + trace := httptrace.ContextClientTrace(req.Context()) + if trace == nil || trace.GotConn == nil { + return + } + ci := httptrace.GotConnInfo{Conn: cc.tconn} + ci.Reused = reused + cc.mu.Lock() + ci.WasIdle = len(cc.streams) == 0 && reused + if ci.WasIdle && !cc.lastActive.IsZero() { + ci.IdleTime = time.Now().Sub(cc.lastActive) + } + cc.mu.Unlock() + + trace.GotConn(ci) +} + +func traceWroteHeaders(trace *httptrace.ClientTrace) { + if trace != nil && trace.WroteHeaders != nil { + trace.WroteHeaders() + } +} + +func traceGot100Continue(trace *httptrace.ClientTrace) { + if trace != nil && trace.Got100Continue != nil { + trace.Got100Continue() + } +} + +func traceWait100Continue(trace *httptrace.ClientTrace) { + if trace != nil && trace.Wait100Continue != nil { + trace.Wait100Continue() + } +} + +func traceWroteRequest(trace *httptrace.ClientTrace, err error) { + if trace != nil && trace.WroteRequest != nil { + trace.WroteRequest(httptrace.WroteRequestInfo{Err: err}) + } +} + +func traceFirstResponseByte(trace *httptrace.ClientTrace) { + if trace != nil && trace.GotFirstResponseByte != nil { + trace.GotFirstResponseByte() + } +} diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go index 8a9711f6e..3849bc263 100644 --- a/vendor/golang.org/x/net/http2/write.go +++ b/vendor/golang.org/x/net/http2/write.go @@ -199,7 +199,7 @@ func (w *writeResHeaders) staysWithinBuffer(max int) bool { // TODO: this is a common one. It'd be nice to return true // here and get into the fast path if we could be clever and // calculate the size fast enough, or at least a conservative - // uppper bound that usually fires. (Maybe if w.h and + // upper bound that usually fires. (Maybe if w.h and // w.trailers are nil, so we don't need to enumerate it.) // Otherwise I'm afraid that just calculating the length to // answer this question would be slower than the ~2µs benefit. @@ -329,7 +329,7 @@ func (wu writeWindowUpdate) writeFrame(ctx writeContext) error { } // encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k]) -// is encoded only only if k is in keys. +// is encoded only if k is in keys. func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { if keys == nil { sorter := sorterPool.Get().(*sorter) diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna10.0.0.go similarity index 99% rename from vendor/golang.org/x/net/idna/idna.go rename to vendor/golang.org/x/net/idna/idna10.0.0.go index 346fe4423..a98a31f40 100644 --- a/vendor/golang.org/x/net/idna/idna.go +++ b/vendor/golang.org/x/net/idna/idna10.0.0.go @@ -4,14 +4,16 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build go1.10 + // Package idna implements IDNA2008 using the compatibility processing // defined by UTS (Unicode Technical Standard) #46, which defines a standard to // deal with the transition from IDNA2003. // // IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC // 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894. -// UTS #46 is defined in http://www.unicode.org/reports/tr46. -// See http://unicode.org/cldr/utility/idna.jsp for a visualization of the +// UTS #46 is defined in https://www.unicode.org/reports/tr46. +// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the // differences between these two standards. package idna // import "golang.org/x/net/idna" @@ -297,7 +299,7 @@ func (e runeError) Error() string { } // process implements the algorithm described in section 4 of UTS #46, -// see http://www.unicode.org/reports/tr46. +// see https://www.unicode.org/reports/tr46. func (p *Profile) process(s string, toASCII bool) (string, error) { var err error var isBidi bool diff --git a/vendor/golang.org/x/net/idna/idna9.0.0.go b/vendor/golang.org/x/net/idna/idna9.0.0.go new file mode 100644 index 000000000..8842146b5 --- /dev/null +++ b/vendor/golang.org/x/net/idna/idna9.0.0.go @@ -0,0 +1,682 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.10 + +// Package idna implements IDNA2008 using the compatibility processing +// defined by UTS (Unicode Technical Standard) #46, which defines a standard to +// deal with the transition from IDNA2003. +// +// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC +// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894. +// UTS #46 is defined in https://www.unicode.org/reports/tr46. +// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the +// differences between these two standards. +package idna // import "golang.org/x/net/idna" + +import ( + "fmt" + "strings" + "unicode/utf8" + + "golang.org/x/text/secure/bidirule" + "golang.org/x/text/unicode/norm" +) + +// NOTE: Unlike common practice in Go APIs, the functions will return a +// sanitized domain name in case of errors. Browsers sometimes use a partially +// evaluated string as lookup. +// TODO: the current error handling is, in my opinion, the least opinionated. +// Other strategies are also viable, though: +// Option 1) Return an empty string in case of error, but allow the user to +// specify explicitly which errors to ignore. +// Option 2) Return the partially evaluated string if it is itself a valid +// string, otherwise return the empty string in case of error. +// Option 3) Option 1 and 2. +// Option 4) Always return an empty string for now and implement Option 1 as +// needed, and document that the return string may not be empty in case of +// error in the future. +// I think Option 1 is best, but it is quite opinionated. + +// ToASCII is a wrapper for Punycode.ToASCII. +func ToASCII(s string) (string, error) { + return Punycode.process(s, true) +} + +// ToUnicode is a wrapper for Punycode.ToUnicode. +func ToUnicode(s string) (string, error) { + return Punycode.process(s, false) +} + +// An Option configures a Profile at creation time. +type Option func(*options) + +// Transitional sets a Profile to use the Transitional mapping as defined in UTS +// #46. This will cause, for example, "ß" to be mapped to "ss". Using the +// transitional mapping provides a compromise between IDNA2003 and IDNA2008 +// compatibility. It is used by most browsers when resolving domain names. This +// option is only meaningful if combined with MapForLookup. +func Transitional(transitional bool) Option { + return func(o *options) { o.transitional = true } +} + +// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts +// are longer than allowed by the RFC. +func VerifyDNSLength(verify bool) Option { + return func(o *options) { o.verifyDNSLength = verify } +} + +// RemoveLeadingDots removes leading label separators. Leading runes that map to +// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well. +// +// This is the behavior suggested by the UTS #46 and is adopted by some +// browsers. +func RemoveLeadingDots(remove bool) Option { + return func(o *options) { o.removeLeadingDots = remove } +} + +// ValidateLabels sets whether to check the mandatory label validation criteria +// as defined in Section 5.4 of RFC 5891. This includes testing for correct use +// of hyphens ('-'), normalization, validity of runes, and the context rules. +func ValidateLabels(enable bool) Option { + return func(o *options) { + // Don't override existing mappings, but set one that at least checks + // normalization if it is not set. + if o.mapping == nil && enable { + o.mapping = normalize + } + o.trie = trie + o.validateLabels = enable + o.fromPuny = validateFromPunycode + } +} + +// StrictDomainName limits the set of permissable ASCII characters to those +// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the +// hyphen). This is set by default for MapForLookup and ValidateForRegistration. +// +// This option is useful, for instance, for browsers that allow characters +// outside this range, for example a '_' (U+005F LOW LINE). See +// http://www.rfc-editor.org/std/std3.txt for more details This option +// corresponds to the UseSTD3ASCIIRules option in UTS #46. +func StrictDomainName(use bool) Option { + return func(o *options) { + o.trie = trie + o.useSTD3Rules = use + o.fromPuny = validateFromPunycode + } +} + +// NOTE: the following options pull in tables. The tables should not be linked +// in as long as the options are not used. + +// BidiRule enables the Bidi rule as defined in RFC 5893. Any application +// that relies on proper validation of labels should include this rule. +func BidiRule() Option { + return func(o *options) { o.bidirule = bidirule.ValidString } +} + +// ValidateForRegistration sets validation options to verify that a given IDN is +// properly formatted for registration as defined by Section 4 of RFC 5891. +func ValidateForRegistration() Option { + return func(o *options) { + o.mapping = validateRegistration + StrictDomainName(true)(o) + ValidateLabels(true)(o) + VerifyDNSLength(true)(o) + BidiRule()(o) + } +} + +// MapForLookup sets validation and mapping options such that a given IDN is +// transformed for domain name lookup according to the requirements set out in +// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894, +// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option +// to add this check. +// +// The mappings include normalization and mapping case, width and other +// compatibility mappings. +func MapForLookup() Option { + return func(o *options) { + o.mapping = validateAndMap + StrictDomainName(true)(o) + ValidateLabels(true)(o) + RemoveLeadingDots(true)(o) + } +} + +type options struct { + transitional bool + useSTD3Rules bool + validateLabels bool + verifyDNSLength bool + removeLeadingDots bool + + trie *idnaTrie + + // fromPuny calls validation rules when converting A-labels to U-labels. + fromPuny func(p *Profile, s string) error + + // mapping implements a validation and mapping step as defined in RFC 5895 + // or UTS 46, tailored to, for example, domain registration or lookup. + mapping func(p *Profile, s string) (string, error) + + // bidirule, if specified, checks whether s conforms to the Bidi Rule + // defined in RFC 5893. + bidirule func(s string) bool +} + +// A Profile defines the configuration of a IDNA mapper. +type Profile struct { + options +} + +func apply(o *options, opts []Option) { + for _, f := range opts { + f(o) + } +} + +// New creates a new Profile. +// +// With no options, the returned Profile is the most permissive and equals the +// Punycode Profile. Options can be passed to further restrict the Profile. The +// MapForLookup and ValidateForRegistration options set a collection of options, +// for lookup and registration purposes respectively, which can be tailored by +// adding more fine-grained options, where later options override earlier +// options. +func New(o ...Option) *Profile { + p := &Profile{} + apply(&p.options, o) + return p +} + +// ToASCII converts a domain or domain label to its ASCII form. For example, +// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and +// ToASCII("golang") is "golang". If an error is encountered it will return +// an error and a (partially) processed result. +func (p *Profile) ToASCII(s string) (string, error) { + return p.process(s, true) +} + +// ToUnicode converts a domain or domain label to its Unicode form. For example, +// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and +// ToUnicode("golang") is "golang". If an error is encountered it will return +// an error and a (partially) processed result. +func (p *Profile) ToUnicode(s string) (string, error) { + pp := *p + pp.transitional = false + return pp.process(s, false) +} + +// String reports a string with a description of the profile for debugging +// purposes. The string format may change with different versions. +func (p *Profile) String() string { + s := "" + if p.transitional { + s = "Transitional" + } else { + s = "NonTransitional" + } + if p.useSTD3Rules { + s += ":UseSTD3Rules" + } + if p.validateLabels { + s += ":ValidateLabels" + } + if p.verifyDNSLength { + s += ":VerifyDNSLength" + } + return s +} + +var ( + // Punycode is a Profile that does raw punycode processing with a minimum + // of validation. + Punycode *Profile = punycode + + // Lookup is the recommended profile for looking up domain names, according + // to Section 5 of RFC 5891. The exact configuration of this profile may + // change over time. + Lookup *Profile = lookup + + // Display is the recommended profile for displaying domain names. + // The configuration of this profile may change over time. + Display *Profile = display + + // Registration is the recommended profile for checking whether a given + // IDN is valid for registration, according to Section 4 of RFC 5891. + Registration *Profile = registration + + punycode = &Profile{} + lookup = &Profile{options{ + transitional: true, + useSTD3Rules: true, + validateLabels: true, + removeLeadingDots: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + display = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + removeLeadingDots: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + registration = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + verifyDNSLength: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateRegistration, + bidirule: bidirule.ValidString, + }} + + // TODO: profiles + // Register: recommended for approving domain names: don't do any mappings + // but rather reject on invalid input. Bundle or block deviation characters. +) + +type labelError struct{ label, code_ string } + +func (e labelError) code() string { return e.code_ } +func (e labelError) Error() string { + return fmt.Sprintf("idna: invalid label %q", e.label) +} + +type runeError rune + +func (e runeError) code() string { return "P1" } +func (e runeError) Error() string { + return fmt.Sprintf("idna: disallowed rune %U", e) +} + +// process implements the algorithm described in section 4 of UTS #46, +// see https://www.unicode.org/reports/tr46. +func (p *Profile) process(s string, toASCII bool) (string, error) { + var err error + if p.mapping != nil { + s, err = p.mapping(p, s) + } + // Remove leading empty labels. + if p.removeLeadingDots { + for ; len(s) > 0 && s[0] == '.'; s = s[1:] { + } + } + // It seems like we should only create this error on ToASCII, but the + // UTS 46 conformance tests suggests we should always check this. + if err == nil && p.verifyDNSLength && s == "" { + err = &labelError{s, "A4"} + } + labels := labelIter{orig: s} + for ; !labels.done(); labels.next() { + label := labels.label() + if label == "" { + // Empty labels are not okay. The label iterator skips the last + // label if it is empty. + if err == nil && p.verifyDNSLength { + err = &labelError{s, "A4"} + } + continue + } + if strings.HasPrefix(label, acePrefix) { + u, err2 := decode(label[len(acePrefix):]) + if err2 != nil { + if err == nil { + err = err2 + } + // Spec says keep the old label. + continue + } + labels.set(u) + if err == nil && p.validateLabels { + err = p.fromPuny(p, u) + } + if err == nil { + // This should be called on NonTransitional, according to the + // spec, but that currently does not have any effect. Use the + // original profile to preserve options. + err = p.validateLabel(u) + } + } else if err == nil { + err = p.validateLabel(label) + } + } + if toASCII { + for labels.reset(); !labels.done(); labels.next() { + label := labels.label() + if !ascii(label) { + a, err2 := encode(acePrefix, label) + if err == nil { + err = err2 + } + label = a + labels.set(a) + } + n := len(label) + if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { + err = &labelError{label, "A4"} + } + } + } + s = labels.result() + if toASCII && p.verifyDNSLength && err == nil { + // Compute the length of the domain name minus the root label and its dot. + n := len(s) + if n > 0 && s[n-1] == '.' { + n-- + } + if len(s) < 1 || n > 253 { + err = &labelError{s, "A4"} + } + } + return s, err +} + +func normalize(p *Profile, s string) (string, error) { + return norm.NFC.String(s), nil +} + +func validateRegistration(p *Profile, s string) (string, error) { + if !norm.NFC.IsNormalString(s) { + return s, &labelError{s, "V1"} + } + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + // TODO: handle the NV8 defined in the Unicode idna data set to allow + // for strict conformance to IDNA2008. + case valid, deviation: + case disallowed, mapped, unknown, ignored: + r, _ := utf8.DecodeRuneInString(s[i:]) + return s, runeError(r) + } + i += sz + } + return s, nil +} + +func validateAndMap(p *Profile, s string) (string, error) { + var ( + err error + b []byte + k int + ) + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + start := i + i += sz + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + case valid: + continue + case disallowed: + if err == nil { + r, _ := utf8.DecodeRuneInString(s[start:]) + err = runeError(r) + } + continue + case mapped, deviation: + b = append(b, s[k:start]...) + b = info(v).appendMapping(b, s[start:i]) + case ignored: + b = append(b, s[k:start]...) + // drop the rune + case unknown: + b = append(b, s[k:start]...) + b = append(b, "\ufffd"...) + } + k = i + } + if k == 0 { + // No changes so far. + s = norm.NFC.String(s) + } else { + b = append(b, s[k:]...) + if norm.NFC.QuickSpan(b) != len(b) { + b = norm.NFC.Bytes(b) + } + // TODO: the punycode converters require strings as input. + s = string(b) + } + return s, err +} + +// A labelIter allows iterating over domain name labels. +type labelIter struct { + orig string + slice []string + curStart int + curEnd int + i int +} + +func (l *labelIter) reset() { + l.curStart = 0 + l.curEnd = 0 + l.i = 0 +} + +func (l *labelIter) done() bool { + return l.curStart >= len(l.orig) +} + +func (l *labelIter) result() string { + if l.slice != nil { + return strings.Join(l.slice, ".") + } + return l.orig +} + +func (l *labelIter) label() string { + if l.slice != nil { + return l.slice[l.i] + } + p := strings.IndexByte(l.orig[l.curStart:], '.') + l.curEnd = l.curStart + p + if p == -1 { + l.curEnd = len(l.orig) + } + return l.orig[l.curStart:l.curEnd] +} + +// next sets the value to the next label. It skips the last label if it is empty. +func (l *labelIter) next() { + l.i++ + if l.slice != nil { + if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" { + l.curStart = len(l.orig) + } + } else { + l.curStart = l.curEnd + 1 + if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { + l.curStart = len(l.orig) + } + } +} + +func (l *labelIter) set(s string) { + if l.slice == nil { + l.slice = strings.Split(l.orig, ".") + } + l.slice[l.i] = s +} + +// acePrefix is the ASCII Compatible Encoding prefix. +const acePrefix = "xn--" + +func (p *Profile) simplify(cat category) category { + switch cat { + case disallowedSTD3Mapped: + if p.useSTD3Rules { + cat = disallowed + } else { + cat = mapped + } + case disallowedSTD3Valid: + if p.useSTD3Rules { + cat = disallowed + } else { + cat = valid + } + case deviation: + if !p.transitional { + cat = valid + } + case validNV8, validXV8: + // TODO: handle V2008 + cat = valid + } + return cat +} + +func validateFromPunycode(p *Profile, s string) error { + if !norm.NFC.IsNormalString(s) { + return &labelError{s, "V1"} + } + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + if c := p.simplify(info(v).category()); c != valid && c != deviation { + return &labelError{s, "V6"} + } + i += sz + } + return nil +} + +const ( + zwnj = "\u200c" + zwj = "\u200d" +) + +type joinState int8 + +const ( + stateStart joinState = iota + stateVirama + stateBefore + stateBeforeVirama + stateAfter + stateFAIL +) + +var joinStates = [][numJoinTypes]joinState{ + stateStart: { + joiningL: stateBefore, + joiningD: stateBefore, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateVirama, + }, + stateVirama: { + joiningL: stateBefore, + joiningD: stateBefore, + }, + stateBefore: { + joiningL: stateBefore, + joiningD: stateBefore, + joiningT: stateBefore, + joinZWNJ: stateAfter, + joinZWJ: stateFAIL, + joinVirama: stateBeforeVirama, + }, + stateBeforeVirama: { + joiningL: stateBefore, + joiningD: stateBefore, + joiningT: stateBefore, + }, + stateAfter: { + joiningL: stateFAIL, + joiningD: stateBefore, + joiningT: stateAfter, + joiningR: stateStart, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateAfter, // no-op as we can't accept joiners here + }, + stateFAIL: { + 0: stateFAIL, + joiningL: stateFAIL, + joiningD: stateFAIL, + joiningT: stateFAIL, + joiningR: stateFAIL, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateFAIL, + }, +} + +// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are +// already implicitly satisfied by the overall implementation. +func (p *Profile) validateLabel(s string) error { + if s == "" { + if p.verifyDNSLength { + return &labelError{s, "A4"} + } + return nil + } + if p.bidirule != nil && !p.bidirule(s) { + return &labelError{s, "B"} + } + if !p.validateLabels { + return nil + } + trie := p.trie // p.validateLabels is only set if trie is set. + if len(s) > 4 && s[2] == '-' && s[3] == '-' { + return &labelError{s, "V2"} + } + if s[0] == '-' || s[len(s)-1] == '-' { + return &labelError{s, "V3"} + } + // TODO: merge the use of this in the trie. + v, sz := trie.lookupString(s) + x := info(v) + if x.isModifier() { + return &labelError{s, "V5"} + } + // Quickly return in the absence of zero-width (non) joiners. + if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { + return nil + } + st := stateStart + for i := 0; ; { + jt := x.joinType() + if s[i:i+sz] == zwj { + jt = joinZWJ + } else if s[i:i+sz] == zwnj { + jt = joinZWNJ + } + st = joinStates[st][jt] + if x.isViramaModifier() { + st = joinStates[st][joinVirama] + } + if i += sz; i == len(s) { + break + } + v, sz = trie.lookupString(s[i:]) + x = info(v) + } + if st == stateFAIL || st == stateAfter { + return &labelError{s, "C"} + } + return nil +} + +func ascii(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= utf8.RuneSelf { + return false + } + } + return true +} diff --git a/vendor/golang.org/x/net/idna/tables.go b/vendor/golang.org/x/net/idna/tables10.0.0.go similarity index 99% rename from vendor/golang.org/x/net/idna/tables.go rename to vendor/golang.org/x/net/idna/tables10.0.0.go index f910b2691..54fddb4b1 100644 --- a/vendor/golang.org/x/net/idna/tables.go +++ b/vendor/golang.org/x/net/idna/tables10.0.0.go @@ -1,11 +1,13 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. +// +build go1.10,!go1.13 + package idna // UnicodeVersion is the Unicode version from which the tables in this package are derived. const UnicodeVersion = "10.0.0" -var mappings string = "" + // Size: 8176 bytes +var mappings string = "" + // Size: 8175 bytes "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + @@ -4554,4 +4556,4 @@ var idnaSparseValues = [1915]valueRange{ {value: 0x0040, lo: 0xb0, hi: 0xbf}, } -// Total table size 42115 bytes (41KiB); checksum: F4A1FA4E +// Total table size 42114 bytes (41KiB); checksum: 355A58A4 diff --git a/vendor/golang.org/x/net/idna/tables11.0.0.go b/vendor/golang.org/x/net/idna/tables11.0.0.go new file mode 100644 index 000000000..c515d7ad2 --- /dev/null +++ b/vendor/golang.org/x/net/idna/tables11.0.0.go @@ -0,0 +1,4653 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.13 + +package idna + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "11.0.0" + +var mappings string = "" + // Size: 8175 bytes + "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + + "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + + "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + + "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" + + "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" + + "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" + + "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" + + "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" + + "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" + + "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" + + "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" + + "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" + + "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" + + "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" + + "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" + + "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" + + "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" + + "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" + + "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" + + "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" + + "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" + + "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" + + "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" + + "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" + + "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" + + "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" + + ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" + + "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" + + "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" + + "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" + + "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" + + "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" + + "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" + + "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" + + "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" + + "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" + + "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" + + "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" + + "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" + + "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" + + "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" + + "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" + + "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" + + "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" + + "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" + + "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" + + "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" + + "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" + + "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" + + "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" + + "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" + + "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" + + "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" + + "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" + + "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" + + "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" + + "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" + + "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" + + "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" + + "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" + + "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" + + "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" + + "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" + + "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" + + "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" + + "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" + + "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" + + "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" + + "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" + + "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" + + "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" + + "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" + + "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" + + " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" + + "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" + + "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" + + "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" + + "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" + + "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" + + "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" + + "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" + + "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" + + "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" + + "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" + + "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" + + "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" + + "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" + + "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" + + "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" + + "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" + + "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" + + "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" + + "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" + + "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" + + "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" + + "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" + + "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" + + "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" + + "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" + + "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" + + "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" + + "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" + + "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" + + "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" + + "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" + + "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" + + "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" + + "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" + + "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" + + "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" + + "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" + + "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" + + "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" + + "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" + + "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" + + "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" + + "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" + + "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" + + "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" + + "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" + + "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" + + "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" + + "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" + + "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" + + "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" + + "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" + + "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" + + "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" + + "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" + + "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" + + "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" + + "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" + + "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" + + "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" + + "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" + + "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" + + "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻" + +var xorData string = "" + // Size: 4855 bytes + "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" + + "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" + + "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" + + "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" + + "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" + + "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" + + "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" + + "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" + + "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" + + "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" + + "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" + + "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" + + "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" + + "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" + + "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" + + "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" + + "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" + + "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" + + "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" + + "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" + + "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" + + "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" + + "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" + + "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" + + "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" + + "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" + + "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" + + "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" + + "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" + + "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" + + "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" + + "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" + + "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" + + "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" + + "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" + + "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" + + "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " + + "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" + + "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" + + "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" + + "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" + + "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" + + ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" + + "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" + + "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" + + "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" + + "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" + + "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" + + "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" + + "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" + + "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" + + "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" + + "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" + + "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" + + "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" + + "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" + + "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" + + "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" + + "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" + + "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" + + "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" + + "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" + + "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" + + "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" + + "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" + + "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" + + "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" + + "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" + + "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" + + "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" + + "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" + + "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" + + "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" + + "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" + + "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" + + "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" + + "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" + + "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" + + "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" + + "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" + + "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" + + "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" + + "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" + + "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" + + "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" + + "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" + + "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" + + "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" + + "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," + + "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" + + "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" + + "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" + + "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" + + ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" + + "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" + + "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" + + "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" + + "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" + + "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" + + "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" + + "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" + + "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" + + "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" + + "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" + + "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" + + "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" + + "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" + + "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" + + "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" + + "\x08\x1a\x0a\x03\x07\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" + + "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" + + "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" + + "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" + + "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" + + "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" + + "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" + + "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" + + "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" + + "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" + + "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" + + "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" + + "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" + + "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" + + "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" + + "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" + + "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" + + "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." + + "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" + + "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" + + "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " + + "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" + + "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" + + "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" + + "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" + + "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" + + "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" + + "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," + + "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" + + "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" + + "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" + + "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" + + "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" + + "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" + + "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" + + "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" + + "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" + + "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" + + "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" + + "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" + + "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" + + "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" + + "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" + + "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" + + "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" + + "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" + + "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" + + "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" + + "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" + + "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" + + "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" + + "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" + + "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" + + "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" + + "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" + + "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" + + "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" + + "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" + + "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" + + "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" + + "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" + + "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" + + "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" + + "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" + + "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" + + "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" + + "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," + + "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" + + "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" + + "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" + + "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" + + "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" + + "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" + + "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" + + "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" + + "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" + + "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" + + "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" + + "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" + + "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" + + "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" + + "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" + + "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" + + "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" + + "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" + + "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" + + "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" + + "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" + + "\x04\x03\x0c?\x05\x03\x0c" + + "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" + + "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" + + "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" + + "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" + + "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" + + "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" + + "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" + + "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" + + "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" + + "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" + + "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" + + "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" + + "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" + + "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" + + "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" + + "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" + + "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" + + "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" + + "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" + + "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" + + "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" + + "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" + + "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" + + "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" + + "\x05\x22\x05\x03\x050\x1d" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// idnaTrie. Total size: 29404 bytes (28.71 KiB). Checksum: 848c45acb5f7991c. +type idnaTrie struct{} + +func newIdnaTrie(i int) *idnaTrie { + return &idnaTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 125: + return uint16(idnaValues[n<<6+uint32(b)]) + default: + n -= 125 + return uint16(idnaSparse.lookup(n, b)) + } +} + +// idnaValues: 127 blocks, 8128 entries, 16256 bytes +// The third block is the zero block. +var idnaValues = [8128]uint16{ + // Block 0x0, offset 0x0 + 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, + 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, + 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080, + 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080, + 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080, + 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080, + 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080, + 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080, + 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008, + 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080, + 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080, + // Block 0x1, offset 0x40 + 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105, + 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105, + 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105, + 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105, + 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080, + 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008, + 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008, + 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008, + 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008, + 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080, + 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018, + 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018, + 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a, + 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005, + 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018, + 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018, + // Block 0x4, offset 0x100 + 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008, + 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008, + 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008, + 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008, + 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008, + 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008, + 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008, + 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008, + 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008, + 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d, + 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199, + // Block 0x5, offset 0x140 + 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d, + 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008, + 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008, + 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008, + 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008, + 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008, + 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008, + 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008, + 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008, + 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d, + 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9, + // Block 0x6, offset 0x180 + 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008, + 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d, + 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d, + 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d, + 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155, + 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008, + 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d, + 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd, + 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d, + 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008, + 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9, + 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d, + 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d, + 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d, + 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008, + 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008, + 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008, + 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008, + 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008, + 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008, + 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008, + // Block 0x8, offset 0x200 + 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008, + 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008, + 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008, + 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008, + 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008, + 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008, + 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008, + 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008, + 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008, + 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d, + 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008, + // Block 0x9, offset 0x240 + 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018, + 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008, + 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008, + 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018, + 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a, + 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369, + 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018, + 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018, + 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018, + 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, + 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, + // Block 0xa, offset 0x280 + 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, + 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, + 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, + 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, + 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, + 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, + 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, + 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, + 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, + 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, + 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2, + 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040, + 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105, + 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105, + 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105, + 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d, + 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d, + 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008, + 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008, + 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008, + 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008, + // Block 0xc, offset 0x300 + 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008, + 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008, + 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd, + 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008, + 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008, + 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008, + 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008, + 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008, + 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd, + 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008, + 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d, + // Block 0xd, offset 0x340 + 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008, + 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008, + 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008, + 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008, + 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008, + 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008, + 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008, + 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008, + 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008, + 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, + 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, + // Block 0xe, offset 0x380 + 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, + 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, + 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, + 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, + 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, + 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008, + 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008, + 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008, + 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008, + 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008, + 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d, + 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d, + 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008, + 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008, + 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008, + 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008, + 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008, + 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008, + 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008, + 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008, + 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008, + // Block 0x10, offset 0x400 + 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008, + 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008, + 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008, + 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008, + 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008, + 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008, + 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008, + 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008, + 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5, + 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, + 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, + // Block 0x11, offset 0x440 + 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, + 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, + 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, + 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, + 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, + 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, + 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, + 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, + 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, + 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, + 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, + // Block 0x12, offset 0x480 + 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, + 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, + 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, + 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, + 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, + 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, + 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, + 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, + 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, + 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, + 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, + 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, + 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, + 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, + 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, + 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, + 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, + 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, + 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, + 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, + 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, + // Block 0x14, offset 0x500 + 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, + 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, + 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, + 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, + 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, + 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, + 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, + 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, + 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, + 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, + 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, + // Block 0x15, offset 0x540 + 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08, + 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08, + 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08, + 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808, + 0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040, + 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08, + 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08, + 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040, + 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040, + 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040, + 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040, + // Block 0x16, offset 0x580 + 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308, + 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008, + 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308, + 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308, + 0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1, + 0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308, + 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008, + 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, + 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008, + 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008, + 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008, + 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008, + 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040, + 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008, + 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008, + 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008, + 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040, + 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, + 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040, + 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040, + 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008, + // Block 0x18, offset 0x600 + 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040, + 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008, + 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040, + 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008, + 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1, + 0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308, + 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008, + 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, + 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018, + 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018, + 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040, + // Block 0x19, offset 0x640 + 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008, + 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040, + 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040, + 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008, + 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008, + 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008, + 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040, + 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, + 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008, + 0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040, + 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008, + // Block 0x1a, offset 0x680 + 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040, + 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308, + 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308, + 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040, + 0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040, + 0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040, + 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008, + 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, + 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308, + 0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040, + 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008, + 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008, + 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008, + 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008, + 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008, + 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008, + 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040, + 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, + 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008, + 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, + 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008, + // Block 0x1c, offset 0x700 + 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308, + 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008, + 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040, + 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040, + 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040, + 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308, + 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008, + 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, + 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040, + 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308, + 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308, + // Block 0x1d, offset 0x740 + 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008, + 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008, + 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040, + 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008, + 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008, + 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008, + 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040, + 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, + 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008, + 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040, + 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308, + // Block 0x1e, offset 0x780 + 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040, + 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008, + 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040, + 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008, + 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9, + 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308, + 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008, + 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008, + 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018, + 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040, + 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008, + 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040, + 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040, + 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040, + 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040, + 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008, + 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008, + 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008, + 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008, + 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040, + 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008, + // Block 0x20, offset 0x800 + 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040, + 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308, + 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040, + 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040, + 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040, + 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308, + 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008, + 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, + 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040, + 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018, + 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018, + // Block 0x21, offset 0x840 + 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008, + 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008, + 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040, + 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008, + 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008, + 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008, + 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040, + 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, + 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008, + 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040, + 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308, + // Block 0x22, offset 0x880 + 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040, + 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, + 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040, + 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040, + 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040, + 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, + 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, + 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, + 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040, + 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040, + 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040, + 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008, + 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040, + 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008, + 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018, + 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308, + 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008, + 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, + 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018, + 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008, + 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008, + // Block 0x24, offset 0x900 + 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040, + 0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040, + 0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040, + 0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008, + 0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008, + 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, + 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040, + 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008, + 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308, + 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308, + 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040, + // Block 0x25, offset 0x940 + 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008, + 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, + 0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008, + 0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79, + 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008, + 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008, + 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9, + 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040, + 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59, + 0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308, + 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008, + // Block 0x26, offset 0x980 + 0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018, + 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, + 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308, + 0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308, + 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11, + 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308, + 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308, + 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308, + 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308, + 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308, + 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008, + 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008, + 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008, + 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008, + 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008, + 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008, + 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008, + 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008, + 0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41, + 0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008, + 0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269, + // Block 0x28, offset 0xa00 + 0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1, + 0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011, + 0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041, + 0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9, + 0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099, + 0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269, + 0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1, + 0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008, + 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008, + 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008, + 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008, + // Block 0x29, offset 0xa40 + 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008, + 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008, + 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008, + 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008, + 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169, + 0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9, + 0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251, + 0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9, + 0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359, + 0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1, + 0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429, + // Block 0x2a, offset 0xa80 + 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, + 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, + 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, + 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008, + 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008, + 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, + 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, + 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, + 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, + 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, + 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, + // Block 0x2b, offset 0xac0 + 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008, + 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008, + 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008, + 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, + 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008, + 0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008, + 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008, + 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008, + 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008, + 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008, + 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008, + // Block 0x2c, offset 0xb00 + 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008, + 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045, + 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008, + 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008, + 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045, + 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008, + 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045, + 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045, + 0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489, + 0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1, + 0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040, + // Block 0x2d, offset 0xb40 + 0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1, + 0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591, + 0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1, + 0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1, + 0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771, + 0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891, + 0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831, + 0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951, + 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040, + 0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459, + 0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686, + // Block 0x2e, offset 0xb80 + 0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040, + 0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489, + 0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008, + 0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008, + 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2, + 0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61, + 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045, + 0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa, + 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040, + 0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9, + 0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a, + 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0, + 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d, + 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e, + 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, + 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018, + 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040, + 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a, + 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018, + 0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018, + 0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018, + // Block 0x30, offset 0xc00 + 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018, + 0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018, + 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018, + 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9, + 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018, + 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340, + 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040, + 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340, + 0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61, + 0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd, + 0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71, + // Block 0x31, offset 0xc40 + 0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61, + 0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5, + 0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09, + 0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359, + 0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040, + 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018, + 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018, + 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018, + 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018, + 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018, + 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018, + // Block 0x32, offset 0xc80 + 0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e, + 0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249, + 0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41, + 0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018, + 0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269, + 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018, + 0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018, + 0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09, + 0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9, + 0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd, + 0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9, + 0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018, + 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151, + 0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279, + 0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399, + 0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439, + 0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369, + 0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61, + 0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451, + 0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5, + 0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61, + // Block 0x34, offset 0xd00 + 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018, + 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040, + 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, + 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, + 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040, + 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51, + 0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601, + 0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691, + 0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26, + 0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6, + 0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a, + // Block 0x35, offset 0xd40 + 0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a, + 0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040, + 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040, + 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040, + 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46, + 0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06, + 0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6, + 0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86, + 0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46, + 0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199, + 0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259, + // Block 0x36, offset 0xd80 + 0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99, + 0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089, + 0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9, + 0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249, + 0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71, + 0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9, + 0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1, + 0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018, + 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018, + 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018, + 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008, + 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008, + 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008, + 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008, + 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008, + 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd, + 0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d, + 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9, + 0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d, + 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008, + 0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9, + // Block 0x38, offset 0xe00 + 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008, + 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008, + 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008, + 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008, + 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008, + 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008, + 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018, + 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308, + 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040, + 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018, + 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018, + // Block 0x39, offset 0xe40 + 0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d, + 0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d, + 0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d, + 0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040, + 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040, + 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040, + 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040, + 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040, + 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040, + 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040, + 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040, + // Block 0x3a, offset 0xe80 + 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008, + 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018, + 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018, + 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018, + 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018, + 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018, + 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018, + 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018, + 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018, + 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018, + 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018, + // Block 0x3b, offset 0xec0 + 0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd, + 0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd, + 0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d, + 0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d, + 0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d, + 0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd, + 0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d, + 0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd, + 0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d, + 0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd, + 0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d, + // Block 0x3c, offset 0xf00 + 0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd, + 0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d, + 0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018, + 0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd, + 0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d, + 0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008, + 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008, + 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008, + 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008, + 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040, + 0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040, + // Block 0x3d, offset 0xf40 + 0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd, + 0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018, + 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761, + 0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1, + 0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881, + 0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd, + 0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d, + 0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d, + 0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd, + 0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d, + 0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018, + // Block 0x3e, offset 0xf80 + 0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d, + 0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d, + 0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd, + 0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd, + 0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d, + 0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d, + 0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd, + 0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d, + 0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999, + 0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29, + 0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69, + 0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69, + 0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15, + 0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75, + 0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded, + 0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d, + 0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5, + 0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d, + 0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d, + 0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd, + 0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040, + // Block 0x40, offset 0x1000 + 0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9, + 0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1, + 0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9, + 0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549, + 0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1, + 0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11, + 0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91, + 0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9, + 0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011, + 0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209, + 0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361, + // Block 0x41, offset 0x1040 + 0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541, + 0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781, + 0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979, + 0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89, + 0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1, + 0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99, + 0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9, + 0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9, + 0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069, + 0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9, + 0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9, + // Block 0x42, offset 0x1080 + 0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271, + 0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9, + 0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed, + 0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371, + 0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9, + 0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d, + 0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211, + 0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1, + 0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599, + 0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9, + 0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671, + 0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709, + 0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781, + 0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1, + 0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811, + 0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901, + 0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1, + 0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11, + 0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31, + 0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51, + 0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d, + // Block 0x44, offset 0x1100 + 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, + 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, + 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, + 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, + 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008, + 0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008, + 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008, + 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308, + 0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308, + 0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308, + 0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008, + // Block 0x45, offset 0x1140 + 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008, + 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008, + 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008, + 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008, + 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11, + 0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008, + 0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008, + 0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008, + 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008, + 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008, + 0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008, + // Block 0x46, offset 0x1180 + 0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018, + 0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018, + 0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018, + 0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008, + 0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008, + 0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008, + 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, + 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, + 0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008, + 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008, + 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008, + // Block 0x47, offset 0x11c0 + 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, + 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008, + 0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, + 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, + 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, + 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, + 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, + 0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008, + 0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008, + 0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d, + 0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008, + // Block 0x48, offset 0x1200 + 0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008, + 0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d, + 0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008, + 0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008, + 0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008, + 0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008, + 0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008, + 0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0008, + 0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008, + 0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0008, 0x123a: 0x0040, 0x123b: 0x0040, + 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040, + // Block 0x49, offset 0x1240 + 0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575, + 0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635, + 0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008, + 0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715, + 0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5, + 0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008, + 0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008, + 0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935, + 0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5, + 0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5, + 0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35, + // Block 0x4a, offset 0x1280 + 0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35, + 0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5, + 0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19, + 0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91, + 0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040, + 0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040, + 0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040, + 0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040, + 0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040, + 0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040, + 0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001, + 0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040, + 0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040, + 0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9, + 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1, + 0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149, + 0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2, + 0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1, + 0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1, + 0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479, + 0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040, + // Block 0x4c, offset 0x1300 + 0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040, + 0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659, + 0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721, + 0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751, + 0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769, + 0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799, + 0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1, + 0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1, + 0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9, + 0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829, + 0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841, + // Block 0x4d, offset 0x1340 + 0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871, + 0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9, + 0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9, + 0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919, + 0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931, + 0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961, + 0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991, + 0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1, + 0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818, + 0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818, + 0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040, + 0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040, + 0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040, + 0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09, + 0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479, + 0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81, + 0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1, + 0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19, + 0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91, + 0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1, + 0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1, + 0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1, + 0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1, + 0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991, + 0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81, + 0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a, + 0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99, + 0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89, + 0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79, + 0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19, + 0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469, + // Block 0x50, offset 0x1400 + 0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649, + 0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9, + 0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49, + 0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21, + 0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9, + 0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01, + 0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91, + 0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9, + 0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171, + 0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289, + 0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329, + // Block 0x51, offset 0x1440 + 0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1, + 0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621, + 0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739, + 0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1, + 0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9, + 0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29, + 0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079, + 0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1, + 0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171, + 0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261, + 0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301, + // Block 0x52, offset 0x1480 + 0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1, + 0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1, + 0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171, + 0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261, + 0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351, + 0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441, + 0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509, + 0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1, + 0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081, + 0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239, + 0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040, + 0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, + 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609, + 0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721, + 0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839, + 0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919, + 0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9, + 0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9, + 0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9, + 0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1, + 0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79, + // Block 0x54, offset 0x1500 + 0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989, + 0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040, + 0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040, + 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040, + 0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, + 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040, + 0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040, + 0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040, + 0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9, + 0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12, + 0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040, + // Block 0x55, offset 0x1540 + 0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0, + 0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0, + 0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55, + 0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75, + 0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040, + 0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308, + 0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308, + 0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308, + 0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2, + 0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35, + 0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55, + // Block 0x56, offset 0x1580 + 0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018, + 0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56, + 0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95, + 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa, + 0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95, + 0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99, + 0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda, + 0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040, + 0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040, + 0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081, + 0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1, + // Block 0x57, offset 0x15c0 + 0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141, + 0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171, + 0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1, + 0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1, + 0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201, + 0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219, + 0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249, + 0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291, + 0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1, + 0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9, + 0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1, + // Block 0x58, offset 0x1600 + 0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321, + 0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339, + 0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369, + 0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381, + 0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1, + 0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9, + 0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9, + 0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1, + 0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441, + 0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9, + 0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea, + 0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2, + 0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9, + 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81, + 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2, + 0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159, + 0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41, + 0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9, + 0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9, + 0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a, + 0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09, + 0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51, + 0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039, + 0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279, + 0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a, + 0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115, + 0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5, + 0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295, + 0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355, + 0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415, + 0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515, + 0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595, + 0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5, + 0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655, + 0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115, + 0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735, + 0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5, + 0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5, + 0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5, + 0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5, + 0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040, + // Block 0x5c, offset 0x1700 + 0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5, + 0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715, + 0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040, + 0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935, + 0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040, + 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6, + 0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35, + 0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040, + 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040, + 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340, + 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, + // Block 0x5d, offset 0x1740 + 0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08, + 0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808, + 0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08, + 0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908, + 0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08, + 0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808, + 0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040, + 0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18, + 0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818, + 0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, + 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, + // Block 0x5e, offset 0x1780 + 0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08, + 0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08, + 0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08, + 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040, + 0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040, + 0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040, + 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18, + 0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818, + 0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040, + 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040, + 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008, + 0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008, + 0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040, + 0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008, + 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008, + 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008, + 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040, + 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008, + 0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008, + 0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x3308, + 0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008, + // Block 0x60, offset 0x1800 + 0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040, + 0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008, + 0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040, + 0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008, + 0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008, + 0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008, + 0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308, + 0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040, + 0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040, + 0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040, + 0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040, + // Block 0x61, offset 0x1840 + 0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199, + 0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359, + 0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269, + 0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369, + 0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9, + 0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259, + 0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99, + 0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089, + 0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9, + 0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249, + 0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359, + // Block 0x62, offset 0x1880 + 0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269, + 0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369, + 0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9, + 0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259, + 0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99, + 0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089, + 0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9, + 0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249, + 0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71, + 0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9, + 0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9, + 0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259, + 0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99, + 0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089, + 0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040, + 0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040, + 0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71, + 0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9, + 0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1, + 0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199, + 0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259, + // Block 0x64, offset 0x1900 + 0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99, + 0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089, + 0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9, + 0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249, + 0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71, + 0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9, + 0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1, + 0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199, + 0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359, + 0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269, + 0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089, + // Block 0x65, offset 0x1940 + 0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9, + 0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040, + 0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71, + 0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9, + 0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040, + 0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199, + 0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359, + 0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269, + 0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369, + 0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9, + 0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040, + // Block 0x66, offset 0x1980 + 0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040, + 0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9, + 0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040, + 0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199, + 0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359, + 0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269, + 0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369, + 0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9, + 0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259, + 0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99, + 0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1, + 0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199, + 0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359, + 0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269, + 0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369, + 0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9, + 0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259, + 0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99, + 0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089, + 0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9, + 0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359, + 0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269, + 0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369, + 0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9, + 0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259, + 0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99, + 0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089, + 0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9, + 0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249, + 0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71, + 0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369, + 0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9, + 0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259, + 0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99, + 0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089, + 0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9, + 0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249, + 0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71, + 0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9, + 0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1, + 0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259, + 0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99, + 0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089, + 0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9, + 0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249, + 0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71, + 0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9, + 0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1, + 0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199, + 0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359, + 0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089, + 0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9, + 0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249, + 0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71, + 0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9, + 0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1, + 0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099, + 0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429, + 0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71, + 0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9, + 0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9, + 0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11, + 0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109, + 0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1, + 0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429, + 0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099, + 0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429, + 0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71, + 0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9, + 0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01, + 0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11, + 0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109, + 0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1, + 0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429, + 0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099, + 0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429, + 0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71, + 0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9, + 0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01, + 0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1, + 0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109, + 0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1, + 0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429, + 0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099, + 0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429, + 0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71, + 0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9, + 0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01, + 0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1, + 0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41, + 0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1, + 0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429, + 0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099, + 0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429, + 0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71, + 0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9, + 0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01, + 0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1, + 0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41, + 0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1, + 0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429, + 0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41, + 0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079, + 0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1, + 0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61, + 0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9, + 0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81, + 0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079, + 0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1, + 0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61, + 0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1, + // Block 0x71, offset 0x1c40 + 0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115, + 0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135, + 0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115, + 0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175, + 0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115, + 0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08, + 0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08, + 0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08, + 0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08, + 0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08, + 0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08, + // Block 0x72, offset 0x1c80 + 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411, + 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1, + 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9, + 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231, + 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949, + 0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, + 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429, + 0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, + 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, + 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351, + 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040, + 0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, + 0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9, + 0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231, + 0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949, + 0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040, + 0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, + 0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, + 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, + 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, + 0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040, + // Block 0x74, offset 0x1d00 + 0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411, + 0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1, + 0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9, + 0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231, + 0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040, + 0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249, + 0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429, + 0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339, + 0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1, + 0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351, + 0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02, + 0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018, + 0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2, + 0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72, + 0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32, + 0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2, + 0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2, + 0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0018, + 0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199, + 0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359, + 0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089, + 0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1, + 0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018, + 0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018, + 0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018, + 0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018, + 0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018, + 0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040, + 0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018, + 0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018, + 0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040, + 0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040, + 0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289, + 0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349, + 0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409, + 0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9, + 0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589, + 0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649, + 0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709, + 0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9, + 0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040, + // Block 0x78, offset 0x1e00 + 0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79, + 0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39, + 0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9, + 0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39, + 0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9, + 0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79, + 0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39, + 0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9, + 0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059, + 0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9, + 0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179, + // Block 0x79, offset 0x1e40 + 0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239, + 0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9, + 0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399, + 0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459, + 0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309, + 0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559, + 0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9, + 0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679, + 0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9, + 0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d, + 0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9, + 0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959, + 0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d, + 0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d, + 0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9, + 0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99, + 0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9, + 0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9, + 0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99, + 0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39, + 0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639, + 0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9, + 0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d, + 0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9, + 0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d, + 0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd, + 0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979, + 0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19, + 0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d, + 0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d, + 0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99, + 0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39, + 0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9, + 0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39, + 0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd, + 0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19, + 0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9, + 0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59, + 0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd, + 0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d, + 0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d, + 0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d, + 0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879, + 0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919, + 0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd, + 0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9, + 0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99, + 0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39, + 0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9, + 0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d, + 0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19, + 0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9, + 0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59, + 0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9, + 0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d, + 0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040, + 0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040, + 0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040, + 0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040, + 0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040, + 0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040, +} + +// idnaIndex: 36 blocks, 2304 entries, 4608 bytes +// Block 0 is the zero block. +var idnaIndex = [2304]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, + 0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21, + // Block 0x4, offset 0x100 + 0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16, + 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d, + 0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91, + 0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96, + // Block 0x5, offset 0x140 + 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, + 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, + 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, + 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, + 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, + 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, + 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3, + 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c, + // Block 0x6, offset 0x180 + 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b, + 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b, + 0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, + 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, + 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, + 0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0, + 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5, + 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1, + 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41, + 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, + 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, + 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, + 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, + 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, + 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, + // Block 0x8, offset 0x200 + 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, + 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, + 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, + 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, + 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, + 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, + 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, + 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, + // Block 0x9, offset 0x240 + 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, + 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, + 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, + 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, + 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, + 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, + 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, + 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, + // Block 0xa, offset 0x280 + 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, + 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, + 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, + 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, + 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, + 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, + 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, + 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, + 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, + 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, + 0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8, + 0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0, + 0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8, + 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, + 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, + // Block 0xc, offset 0x300 + 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, + 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, + 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, + 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa, + // Block 0xd, offset 0x340 + 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, + 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, + 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, + 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, + 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, + 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, + 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, + 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, + // Block 0xe, offset 0x380 + 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, + 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, + 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, + 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, + 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe, + 0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c, + 0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52, + 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108, + 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e, + 0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba, + 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba, + 0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c, + 0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba, + 0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0x126, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, + 0x3f8: 0xba, 0x3f9: 0x127, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0x128, 0x3fd: 0x129, 0x3fe: 0xba, 0x3ff: 0xba, + // Block 0x10, offset 0x400 + 0x400: 0x12a, 0x401: 0x12b, 0x402: 0x12c, 0x403: 0x12d, 0x404: 0x12e, 0x405: 0x12f, 0x406: 0x130, 0x407: 0x131, + 0x408: 0x132, 0x409: 0xba, 0x40a: 0x133, 0x40b: 0x134, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba, + 0x410: 0x135, 0x411: 0x136, 0x412: 0x137, 0x413: 0x138, 0x414: 0xba, 0x415: 0xba, 0x416: 0x139, 0x417: 0x13a, + 0x418: 0x13b, 0x419: 0x13c, 0x41a: 0x13d, 0x41b: 0x13e, 0x41c: 0x13f, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, + 0x420: 0x140, 0x421: 0xba, 0x422: 0x141, 0x423: 0x142, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba, + 0x428: 0x143, 0x429: 0x144, 0x42a: 0x145, 0x42b: 0x146, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, + 0x430: 0x147, 0x431: 0x148, 0x432: 0x149, 0x433: 0xba, 0x434: 0x14a, 0x435: 0x14b, 0x436: 0x14c, 0x437: 0xba, + 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0x14d, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba, + // Block 0x11, offset 0x440 + 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, + 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x14e, 0x44f: 0xba, + 0x450: 0x9b, 0x451: 0x14f, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x150, 0x456: 0xba, 0x457: 0xba, + 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, + 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, + 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, + 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, + 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, + // Block 0x12, offset 0x480 + 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, + 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, + 0x490: 0x151, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, + 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, + 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, + 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, + 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, + 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, + // Block 0x13, offset 0x4c0 + 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, + 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, + 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, + 0x4d8: 0x9f, 0x4d9: 0x152, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, + 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, + 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, + 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, + 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, + // Block 0x14, offset 0x500 + 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, + 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, + 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, + 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, + 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, + 0x528: 0x146, 0x529: 0x153, 0x52a: 0xba, 0x52b: 0x154, 0x52c: 0x155, 0x52d: 0x156, 0x52e: 0x157, 0x52f: 0xba, + 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, + 0x538: 0xba, 0x539: 0x158, 0x53a: 0x159, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x15a, 0x53e: 0x15b, 0x53f: 0x15c, + // Block 0x15, offset 0x540 + 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, + 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, + 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, + 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x15d, + 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, + 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x15e, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, + 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, + 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, + // Block 0x16, offset 0x580 + 0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x15f, 0x585: 0x160, 0x586: 0x9f, 0x587: 0x9f, + 0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x161, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, + 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, + 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, + 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, + 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, + 0x5b0: 0x9f, 0x5b1: 0x162, 0x5b2: 0x163, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, + 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x164, 0x5c4: 0x165, 0x5c5: 0x166, 0x5c6: 0x167, 0x5c7: 0x168, + 0x5c8: 0x9b, 0x5c9: 0x169, 0x5ca: 0xba, 0x5cb: 0x16a, 0x5cc: 0x9b, 0x5cd: 0x16b, 0x5ce: 0xba, 0x5cf: 0xba, + 0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66, + 0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e, + 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, + 0x5e8: 0x16c, 0x5e9: 0x16d, 0x5ea: 0x16e, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, + 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, + 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, + // Block 0x18, offset 0x600 + 0x600: 0x16f, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba, + 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, + 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, + 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, + 0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x170, 0x624: 0x6f, 0x625: 0x171, 0x626: 0xba, 0x627: 0xba, + 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, + 0x630: 0xba, 0x631: 0x172, 0x632: 0x173, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, + 0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x174, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, + // Block 0x19, offset 0x640 + 0x640: 0x175, 0x641: 0x9b, 0x642: 0x176, 0x643: 0x177, 0x644: 0x73, 0x645: 0x74, 0x646: 0x178, 0x647: 0x179, + 0x648: 0x75, 0x649: 0x17a, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, + 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, + 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x17b, 0x65c: 0x9b, 0x65d: 0x17c, 0x65e: 0x9b, 0x65f: 0x17d, + 0x660: 0x17e, 0x661: 0x17f, 0x662: 0x180, 0x663: 0xba, 0x664: 0x181, 0x665: 0x182, 0x666: 0x183, 0x667: 0x184, + 0x668: 0xba, 0x669: 0x185, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, + 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, + 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, + // Block 0x1a, offset 0x680 + 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, + 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, + 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, + 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x186, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, + 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, + 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, + 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, + 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, + 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, + 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, + 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x187, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, + 0x6e0: 0x188, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, + 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, + 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, + 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, + // Block 0x1c, offset 0x700 + 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, + 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, + 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, + 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, + 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, + 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, + 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, + 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x189, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f, + // Block 0x1d, offset 0x740 + 0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f, + 0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f, + 0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f, + 0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f, + 0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f, + 0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x18a, + 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, + 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, + // Block 0x1e, offset 0x780 + 0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba, + 0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba, + 0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba, + 0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba, + 0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x18b, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x18c, 0x7a7: 0x7b, + 0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba, + 0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba, + 0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba, + // Block 0x1f, offset 0x7c0 + 0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07, + 0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17, + 0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07, + 0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c, + 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, + 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, + // Block 0x20, offset 0x800 + 0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b, + 0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b, + 0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b, + 0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b, + 0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b, + 0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b, + 0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b, + 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b, + // Block 0x21, offset 0x840 + 0x840: 0x18d, 0x841: 0x18e, 0x842: 0xba, 0x843: 0xba, 0x844: 0x18f, 0x845: 0x18f, 0x846: 0x18f, 0x847: 0x190, + 0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba, + 0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba, + 0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba, + 0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba, + 0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba, + 0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba, + 0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba, + // Block 0x22, offset 0x880 + 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, + 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, + 0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b, + 0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b, + 0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b, + 0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b, + 0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b, + 0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b, + 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b, +} + +// idnaSparseOffset: 276 entries, 552 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x86, 0x8b, 0x94, 0xa4, 0xb2, 0xbe, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x224, 0x22e, 0x23a, 0x246, 0x252, 0x25a, 0x25f, 0x269, 0x27a, 0x27e, 0x289, 0x28d, 0x296, 0x29e, 0x2a4, 0x2a9, 0x2ac, 0x2b0, 0x2b6, 0x2ba, 0x2be, 0x2c2, 0x2c7, 0x2cd, 0x2d5, 0x2dc, 0x2e7, 0x2f1, 0x2f5, 0x2f8, 0x2fe, 0x302, 0x304, 0x307, 0x309, 0x30c, 0x316, 0x319, 0x328, 0x32c, 0x331, 0x334, 0x338, 0x33d, 0x342, 0x348, 0x34e, 0x35d, 0x363, 0x367, 0x376, 0x37b, 0x383, 0x38d, 0x398, 0x3a0, 0x3b1, 0x3ba, 0x3ca, 0x3d7, 0x3e1, 0x3e6, 0x3f3, 0x3f7, 0x3fc, 0x3fe, 0x402, 0x404, 0x408, 0x411, 0x417, 0x41b, 0x42b, 0x435, 0x43a, 0x43d, 0x443, 0x44a, 0x44f, 0x453, 0x459, 0x45e, 0x467, 0x46c, 0x472, 0x479, 0x480, 0x487, 0x48b, 0x490, 0x493, 0x498, 0x4a4, 0x4aa, 0x4af, 0x4b6, 0x4be, 0x4c3, 0x4c7, 0x4d7, 0x4de, 0x4e2, 0x4e6, 0x4ed, 0x4ef, 0x4f2, 0x4f5, 0x4f9, 0x502, 0x506, 0x50e, 0x516, 0x51c, 0x525, 0x531, 0x538, 0x541, 0x54b, 0x552, 0x560, 0x56d, 0x57a, 0x583, 0x587, 0x596, 0x59e, 0x5a9, 0x5b2, 0x5b8, 0x5c0, 0x5c9, 0x5d3, 0x5d6, 0x5e2, 0x5eb, 0x5ee, 0x5f3, 0x5fe, 0x607, 0x613, 0x616, 0x620, 0x629, 0x635, 0x642, 0x64f, 0x65d, 0x664, 0x667, 0x66c, 0x66f, 0x672, 0x675, 0x67c, 0x683, 0x687, 0x692, 0x695, 0x698, 0x69b, 0x6a1, 0x6a6, 0x6aa, 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6be, 0x6c8, 0x6cb, 0x6cf, 0x6de, 0x6ea, 0x6ee, 0x6f3, 0x6f7, 0x6fc, 0x700, 0x705, 0x70e, 0x719, 0x71f, 0x727, 0x72a, 0x72d, 0x731, 0x735, 0x73b, 0x741, 0x746, 0x749, 0x759, 0x760, 0x763, 0x766, 0x76a, 0x770, 0x775, 0x77a, 0x782, 0x787, 0x78b, 0x78f, 0x792, 0x795, 0x799, 0x79d, 0x7a0, 0x7b0, 0x7c1, 0x7c6, 0x7c8, 0x7ca} + +// idnaSparseValues: 1997 entries, 7988 bytes +var idnaSparseValues = [1997]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x07}, + {value: 0xe105, lo: 0x80, hi: 0x96}, + {value: 0x0018, lo: 0x97, hi: 0x97}, + {value: 0xe105, lo: 0x98, hi: 0x9e}, + {value: 0x001f, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbf}, + // Block 0x1, offset 0x8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0xe01d, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0335, lo: 0x83, hi: 0x83}, + {value: 0x034d, lo: 0x84, hi: 0x84}, + {value: 0x0365, lo: 0x85, hi: 0x85}, + {value: 0xe00d, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0xe00d, lo: 0x88, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x89}, + {value: 0xe00d, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe00d, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0x8d}, + {value: 0xe00d, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0xbf}, + // Block 0x2, offset 0x19 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0249, lo: 0xb0, hi: 0xb0}, + {value: 0x037d, lo: 0xb1, hi: 0xb1}, + {value: 0x0259, lo: 0xb2, hi: 0xb2}, + {value: 0x0269, lo: 0xb3, hi: 0xb3}, + {value: 0x034d, lo: 0xb4, hi: 0xb4}, + {value: 0x0395, lo: 0xb5, hi: 0xb5}, + {value: 0xe1bd, lo: 0xb6, hi: 0xb6}, + {value: 0x0279, lo: 0xb7, hi: 0xb7}, + {value: 0x0289, lo: 0xb8, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbf}, + // Block 0x3, offset 0x25 + {value: 0x0000, lo: 0x01}, + {value: 0x3308, lo: 0x80, hi: 0xbf}, + // Block 0x4, offset 0x27 + {value: 0x0000, lo: 0x04}, + {value: 0x03f5, lo: 0x80, hi: 0x8f}, + {value: 0xe105, lo: 0x90, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x5, offset 0x2c + {value: 0x0000, lo: 0x06}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x0545, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x0008, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x6, offset 0x33 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0401, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0018, lo: 0x89, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x7, offset 0x3e + {value: 0x0000, lo: 0x0b}, + {value: 0x0818, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x82}, + {value: 0x0818, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x85}, + {value: 0x0818, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xae}, + {value: 0x0808, lo: 0xaf, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x8, offset 0x4a + {value: 0x0000, lo: 0x03}, + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0c08, lo: 0x88, hi: 0x99}, + {value: 0x0a08, lo: 0x9a, hi: 0xbf}, + // Block 0x9, offset 0x4e + {value: 0x0000, lo: 0x0e}, + {value: 0x3308, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0c08, lo: 0x8d, hi: 0x8d}, + {value: 0x0a08, lo: 0x8e, hi: 0x98}, + {value: 0x0c08, lo: 0x99, hi: 0x9b}, + {value: 0x0a08, lo: 0x9c, hi: 0xaa}, + {value: 0x0c08, lo: 0xab, hi: 0xac}, + {value: 0x0a08, lo: 0xad, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xb5, hi: 0xb7}, + {value: 0x0c08, lo: 0xb8, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbf}, + // Block 0xa, offset 0x5d + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xb, offset 0x62 + {value: 0x0000, lo: 0x09}, + {value: 0x0808, lo: 0x80, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbf}, + // Block 0xc, offset 0x6c + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x99}, + {value: 0x0808, lo: 0x9a, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa3}, + {value: 0x0808, lo: 0xa4, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa7}, + {value: 0x0808, lo: 0xa8, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0818, lo: 0xb0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd, offset 0x78 + {value: 0x0000, lo: 0x0d}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0a08, lo: 0xa0, hi: 0xa9}, + {value: 0x0c08, lo: 0xaa, hi: 0xac}, + {value: 0x0808, lo: 0xad, hi: 0xad}, + {value: 0x0c08, lo: 0xae, hi: 0xae}, + {value: 0x0a08, lo: 0xaf, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb2}, + {value: 0x0a08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0a08, lo: 0xb6, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xe, offset 0x86 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0xa1}, + {value: 0x0840, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xbf}, + // Block 0xf, offset 0x8b + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x10, offset 0x94 + {value: 0x0000, lo: 0x0f}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x85}, + {value: 0x3008, lo: 0x86, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8c}, + {value: 0x3b08, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x11, offset 0xa4 + {value: 0x0000, lo: 0x0d}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x12, offset 0xb2 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xba}, + {value: 0x3b08, lo: 0xbb, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x13, offset 0xbe + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x14, offset 0xca + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x89}, + {value: 0x3b08, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x3008, lo: 0x98, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x15, offset 0xdb + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb2}, + {value: 0x08f1, lo: 0xb3, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb9}, + {value: 0x3b08, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0x16, offset 0xe5 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x8e}, + {value: 0x0018, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0xbf}, + // Block 0x17, offset 0xec + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0961, lo: 0x9c, hi: 0x9c}, + {value: 0x0999, lo: 0x9d, hi: 0x9d}, + {value: 0x0008, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x18, offset 0xf9 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe03d, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x19, offset 0x10a + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0x1a, offset 0x111 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x1b, offset 0x11c + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xa1}, + {value: 0x3008, lo: 0xa2, hi: 0xa4}, + {value: 0x0008, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xbf}, + // Block 0x1c, offset 0x12b + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x8c}, + {value: 0x3308, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x3008, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x1d, offset 0x139 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x86}, + {value: 0x055d, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8c}, + {value: 0x055d, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0xe105, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0x1e, offset 0x143 + {value: 0x0000, lo: 0x01}, + {value: 0x0018, lo: 0x80, hi: 0xbf}, + // Block 0x1f, offset 0x145 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa0}, + {value: 0x2018, lo: 0xa1, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x20, offset 0x14a + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa7}, + {value: 0x2018, lo: 0xa8, hi: 0xbf}, + // Block 0x21, offset 0x14d + {value: 0x0000, lo: 0x02}, + {value: 0x2018, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0xbf}, + // Block 0x22, offset 0x150 + {value: 0x0000, lo: 0x01}, + {value: 0x0008, lo: 0x80, hi: 0xbf}, + // Block 0x23, offset 0x152 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x24, offset 0x15e + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x25, offset 0x169 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x26, offset 0x171 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x27, offset 0x177 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x28, offset 0x17d + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x29, offset 0x182 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x2a, offset 0x187 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x2b, offset 0x18a + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xbf}, + // Block 0x2c, offset 0x18e + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2d, offset 0x194 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x2e, offset 0x199 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x3b08, lo: 0x94, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x2f, offset 0x1a5 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x30, offset 0x1af + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xb3}, + {value: 0x3340, lo: 0xb4, hi: 0xb5}, + {value: 0x3008, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x31, offset 0x1b5 + {value: 0x0000, lo: 0x10}, + {value: 0x3008, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x91}, + {value: 0x3b08, lo: 0x92, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0x93}, + {value: 0x0018, lo: 0x94, hi: 0x96}, + {value: 0x0008, lo: 0x97, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x32, offset 0x1c6 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x86}, + {value: 0x0218, lo: 0x87, hi: 0x87}, + {value: 0x0018, lo: 0x88, hi: 0x8a}, + {value: 0x33c0, lo: 0x8b, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0208, lo: 0xa0, hi: 0xbf}, + // Block 0x33, offset 0x1d0 + {value: 0x0000, lo: 0x02}, + {value: 0x0208, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x34, offset 0x1d3 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0208, lo: 0x87, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xa9}, + {value: 0x0208, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x35, offset 0x1db + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0x36, offset 0x1de + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x37, offset 0x1eb + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x38, offset 0x1f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x39, offset 0x1f7 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0028, lo: 0x9a, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xbf}, + // Block 0x3a, offset 0x1fe + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x3308, lo: 0x97, hi: 0x98}, + {value: 0x3008, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x3b, offset 0x206 + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x94}, + {value: 0x3008, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xac}, + {value: 0x3008, lo: 0xad, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3c, offset 0x216 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xbd}, + {value: 0x3318, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x222 + {value: 0x0000, lo: 0x01}, + {value: 0x0040, lo: 0x80, hi: 0xbf}, + // Block 0x3e, offset 0x224 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3008, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x3f, offset 0x22e + {value: 0x0000, lo: 0x0b}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x3808, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x40, offset 0x23a + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3808, lo: 0xaa, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xbf}, + // Block 0x41, offset 0x246 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3008, lo: 0xaa, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3808, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x42, offset 0x252 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x3008, lo: 0xa4, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbf}, + // Block 0x43, offset 0x25a + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x44, offset 0x25f + {value: 0x0000, lo: 0x09}, + {value: 0x0e29, lo: 0x80, hi: 0x80}, + {value: 0x0e41, lo: 0x81, hi: 0x81}, + {value: 0x0e59, lo: 0x82, hi: 0x82}, + {value: 0x0e71, lo: 0x83, hi: 0x83}, + {value: 0x0e89, lo: 0x84, hi: 0x85}, + {value: 0x0ea1, lo: 0x86, hi: 0x86}, + {value: 0x0eb9, lo: 0x87, hi: 0x87}, + {value: 0x057d, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0x45, offset 0x269 + {value: 0x0000, lo: 0x10}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x92}, + {value: 0x0018, lo: 0x93, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa8}, + {value: 0x0008, lo: 0xa9, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x46, offset 0x27a + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0x47, offset 0x27e + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x87}, + {value: 0xe045, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0xe045, lo: 0x98, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0xe045, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbf}, + // Block 0x48, offset 0x289 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x3318, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbf}, + // Block 0x49, offset 0x28d + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x24c1, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x4a, offset 0x296 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x24f1, lo: 0xac, hi: 0xac}, + {value: 0x2529, lo: 0xad, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xae}, + {value: 0x2579, lo: 0xaf, hi: 0xaf}, + {value: 0x25b1, lo: 0xb0, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0x4b, offset 0x29e + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x9f}, + {value: 0x0080, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xad}, + {value: 0x0080, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x4c, offset 0x2a4 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa8}, + {value: 0x09c5, lo: 0xa9, hi: 0xa9}, + {value: 0x09e5, lo: 0xaa, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xbf}, + // Block 0x4d, offset 0x2a9 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0x4e, offset 0x2ac + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x28c1, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x4f, offset 0x2b0 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0e66, lo: 0xb4, hi: 0xb4}, + {value: 0x292a, lo: 0xb5, hi: 0xb5}, + {value: 0x0e86, lo: 0xb6, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x50, offset 0x2b6 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x9b}, + {value: 0x2941, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0xbf}, + // Block 0x51, offset 0x2ba + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x52, offset 0x2be + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0xbf}, + // Block 0x53, offset 0x2c2 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x54, offset 0x2c7 + {value: 0x0000, lo: 0x05}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x03f5, lo: 0x90, hi: 0x9f}, + {value: 0x0ea5, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x55, offset 0x2cd + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x56, offset 0x2d5 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xae}, + {value: 0xe075, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0x57, offset 0x2dc + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x58, offset 0x2e7 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xbf}, + // Block 0x59, offset 0x2f1 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x5a, offset 0x2f5 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0xbf}, + // Block 0x5b, offset 0x2f8 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9e}, + {value: 0x0edd, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x5c, offset 0x2fe + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb2}, + {value: 0x0efd, lo: 0xb3, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x5d, offset 0x302 + {value: 0x0020, lo: 0x01}, + {value: 0x0f1d, lo: 0x80, hi: 0xbf}, + // Block 0x5e, offset 0x304 + {value: 0x0020, lo: 0x02}, + {value: 0x171d, lo: 0x80, hi: 0x8f}, + {value: 0x18fd, lo: 0x90, hi: 0xbf}, + // Block 0x5f, offset 0x307 + {value: 0x0020, lo: 0x01}, + {value: 0x1efd, lo: 0x80, hi: 0xbf}, + // Block 0x60, offset 0x309 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x61, offset 0x30c + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9a}, + {value: 0x29e2, lo: 0x9b, hi: 0x9b}, + {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9e}, + {value: 0x2a31, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x62, offset 0x316 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbe}, + {value: 0x2a69, lo: 0xbf, hi: 0xbf}, + // Block 0x63, offset 0x319 + {value: 0x0000, lo: 0x0e}, + {value: 0x0040, lo: 0x80, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb0}, + {value: 0x2a1d, lo: 0xb1, hi: 0xb1}, + {value: 0x2a3d, lo: 0xb2, hi: 0xb2}, + {value: 0x2a5d, lo: 0xb3, hi: 0xb3}, + {value: 0x2a7d, lo: 0xb4, hi: 0xb4}, + {value: 0x2a5d, lo: 0xb5, hi: 0xb5}, + {value: 0x2a9d, lo: 0xb6, hi: 0xb6}, + {value: 0x2abd, lo: 0xb7, hi: 0xb7}, + {value: 0x2add, lo: 0xb8, hi: 0xb9}, + {value: 0x2afd, lo: 0xba, hi: 0xbb}, + {value: 0x2b1d, lo: 0xbc, hi: 0xbd}, + {value: 0x2afd, lo: 0xbe, hi: 0xbf}, + // Block 0x64, offset 0x328 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x65, offset 0x32c + {value: 0x0030, lo: 0x04}, + {value: 0x2aa2, lo: 0x80, hi: 0x9d}, + {value: 0x305a, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x30a2, lo: 0xa0, hi: 0xbf}, + // Block 0x66, offset 0x331 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x67, offset 0x334 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x68, offset 0x338 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x69, offset 0x33d + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0x6a, offset 0x342 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb1}, + {value: 0x0018, lo: 0xb2, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6b, offset 0x348 + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0xb6}, + {value: 0x0008, lo: 0xb7, hi: 0xb7}, + {value: 0x2009, lo: 0xb8, hi: 0xb8}, + {value: 0x6e89, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xbf}, + // Block 0x6c, offset 0x34e + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x3308, lo: 0x8b, hi: 0x8b}, + {value: 0x0008, lo: 0x8c, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x6d, offset 0x35d + {value: 0x0000, lo: 0x05}, + {value: 0x0208, lo: 0x80, hi: 0xb1}, + {value: 0x0108, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6e, offset 0x363 + {value: 0x0000, lo: 0x03}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xbf}, + // Block 0x6f, offset 0x367 + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0008, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x70, offset 0x376 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x71, offset 0x37b + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x91}, + {value: 0x3008, lo: 0x92, hi: 0x92}, + {value: 0x3808, lo: 0x93, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x72, offset 0x383 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb9}, + {value: 0x3008, lo: 0xba, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x73, offset 0x38d + {value: 0x0000, lo: 0x0a}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x74, offset 0x398 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x75, offset 0x3a0 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8c}, + {value: 0x3008, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbd}, + {value: 0x0008, lo: 0xbe, hi: 0xbf}, + // Block 0x76, offset 0x3b1 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x77, offset 0x3ba + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x9a}, + {value: 0x0008, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3b08, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x78, offset 0x3ca + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x90}, + {value: 0x0008, lo: 0x91, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x79, offset 0x3d7 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x4465, lo: 0x9c, hi: 0x9c}, + {value: 0x447d, lo: 0x9d, hi: 0x9d}, + {value: 0x2971, lo: 0x9e, hi: 0x9e}, + {value: 0xe06d, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xaf}, + {value: 0x4495, lo: 0xb0, hi: 0xbf}, + // Block 0x7a, offset 0x3e1 + {value: 0x0000, lo: 0x04}, + {value: 0x44b5, lo: 0x80, hi: 0x8f}, + {value: 0x44d5, lo: 0x90, hi: 0x9f}, + {value: 0x44f5, lo: 0xa0, hi: 0xaf}, + {value: 0x44d5, lo: 0xb0, hi: 0xbf}, + // Block 0x7b, offset 0x3e6 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3b08, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x7c, offset 0x3f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x7d, offset 0x3f7 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x7e, offset 0x3fc + {value: 0x0020, lo: 0x01}, + {value: 0x4515, lo: 0x80, hi: 0xbf}, + // Block 0x7f, offset 0x3fe + {value: 0x0020, lo: 0x03}, + {value: 0x4d15, lo: 0x80, hi: 0x94}, + {value: 0x4ad5, lo: 0x95, hi: 0x95}, + {value: 0x4fb5, lo: 0x96, hi: 0xbf}, + // Block 0x80, offset 0x402 + {value: 0x0020, lo: 0x01}, + {value: 0x54f5, lo: 0x80, hi: 0xbf}, + // Block 0x81, offset 0x404 + {value: 0x0020, lo: 0x03}, + {value: 0x5cf5, lo: 0x80, hi: 0x84}, + {value: 0x5655, lo: 0x85, hi: 0x85}, + {value: 0x5d95, lo: 0x86, hi: 0xbf}, + // Block 0x82, offset 0x408 + {value: 0x0020, lo: 0x08}, + {value: 0x6b55, lo: 0x80, hi: 0x8f}, + {value: 0x6d15, lo: 0x90, hi: 0x90}, + {value: 0x6d55, lo: 0x91, hi: 0xab}, + {value: 0x6ea1, lo: 0xac, hi: 0xac}, + {value: 0x70b5, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x70d5, lo: 0xb0, hi: 0xbf}, + // Block 0x83, offset 0x411 + {value: 0x0020, lo: 0x05}, + {value: 0x72d5, lo: 0x80, hi: 0xad}, + {value: 0x6535, lo: 0xae, hi: 0xae}, + {value: 0x7895, lo: 0xaf, hi: 0xb5}, + {value: 0x6f55, lo: 0xb6, hi: 0xb6}, + {value: 0x7975, lo: 0xb7, hi: 0xbf}, + // Block 0x84, offset 0x417 + {value: 0x0028, lo: 0x03}, + {value: 0x7c21, lo: 0x80, hi: 0x82}, + {value: 0x7be1, lo: 0x83, hi: 0x83}, + {value: 0x7c99, lo: 0x84, hi: 0xbf}, + // Block 0x85, offset 0x41b + {value: 0x0038, lo: 0x0f}, + {value: 0x9db1, lo: 0x80, hi: 0x83}, + {value: 0x9e59, lo: 0x84, hi: 0x85}, + {value: 0x9e91, lo: 0x86, hi: 0x87}, + {value: 0x9ec9, lo: 0x88, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0xa089, lo: 0x92, hi: 0x97}, + {value: 0xa1a1, lo: 0x98, hi: 0x9c}, + {value: 0xa281, lo: 0x9d, hi: 0xb3}, + {value: 0x9d41, lo: 0xb4, hi: 0xb4}, + {value: 0x9db1, lo: 0xb5, hi: 0xb5}, + {value: 0xa789, lo: 0xb6, hi: 0xbb}, + {value: 0xa869, lo: 0xbc, hi: 0xbc}, + {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, + {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, + // Block 0x86, offset 0x42b + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0008, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x87, offset 0x435 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0x88, offset 0x43a + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x89, offset 0x43d + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x8a, offset 0x443 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x8b, offset 0x44a + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x8c, offset 0x44f + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x8d, offset 0x453 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x8e, offset 0x459 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xbf}, + // Block 0x8f, offset 0x45e + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x90, offset 0x467 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x91, offset 0x46c + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x92, offset 0x472 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x97}, + {value: 0x8ad5, lo: 0x98, hi: 0x9f}, + {value: 0x8aed, lo: 0xa0, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xbf}, + // Block 0x93, offset 0x479 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x8aed, lo: 0xb0, hi: 0xb7}, + {value: 0x8ad5, lo: 0xb8, hi: 0xbf}, + // Block 0x94, offset 0x480 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x95, offset 0x487 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x96, offset 0x48b + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xae}, + {value: 0x0018, lo: 0xaf, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x97, offset 0x490 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x98, offset 0x493 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xbf}, + // Block 0x99, offset 0x498 + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0808, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0808, lo: 0x8a, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb6}, + {value: 0x0808, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbb}, + {value: 0x0808, lo: 0xbc, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x0808, lo: 0xbf, hi: 0xbf}, + // Block 0x9a, offset 0x4a4 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x96}, + {value: 0x0818, lo: 0x97, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0818, lo: 0xb7, hi: 0xbf}, + // Block 0x9b, offset 0x4aa + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa6}, + {value: 0x0818, lo: 0xa7, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x9c, offset 0x4af + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x0818, lo: 0xbb, hi: 0xbf}, + // Block 0x9d, offset 0x4b6 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0818, lo: 0x96, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbe}, + {value: 0x0818, lo: 0xbf, hi: 0xbf}, + // Block 0x9e, offset 0x4be + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbb}, + {value: 0x0818, lo: 0xbc, hi: 0xbd}, + {value: 0x0808, lo: 0xbe, hi: 0xbf}, + // Block 0x9f, offset 0x4c3 + {value: 0x0000, lo: 0x03}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0xa0, offset 0x4c7 + {value: 0x0000, lo: 0x0f}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x94}, + {value: 0x0808, lo: 0x95, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x98}, + {value: 0x0808, lo: 0x99, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xa1, offset 0x4d7 + {value: 0x0000, lo: 0x06}, + {value: 0x0818, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0818, lo: 0x90, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xbc}, + {value: 0x0818, lo: 0xbd, hi: 0xbf}, + // Block 0xa2, offset 0x4de + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xa3, offset 0x4e2 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb8}, + {value: 0x0018, lo: 0xb9, hi: 0xbf}, + // Block 0xa4, offset 0x4e6 + {value: 0x0000, lo: 0x06}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0818, lo: 0x98, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb7}, + {value: 0x0818, lo: 0xb8, hi: 0xbf}, + // Block 0xa5, offset 0x4ed + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa6, offset 0x4ef + {value: 0x0000, lo: 0x02}, + {value: 0x0808, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xa7, offset 0x4f2 + {value: 0x0000, lo: 0x02}, + {value: 0x03dd, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xa8, offset 0x4f5 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xa9, offset 0x4f9 + {value: 0x0000, lo: 0x08}, + {value: 0x0908, lo: 0x80, hi: 0x80}, + {value: 0x0a08, lo: 0x81, hi: 0xa1}, + {value: 0x0c08, lo: 0xa2, hi: 0xa2}, + {value: 0x0a08, lo: 0xa3, hi: 0xa3}, + {value: 0x3308, lo: 0xa4, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0808, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xaa, offset 0x502 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xab, offset 0x506 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0xa6}, + {value: 0x0808, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0a08, lo: 0xb0, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb3}, + {value: 0x0a08, lo: 0xb4, hi: 0xbf}, + // Block 0xac, offset 0x50e + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x84}, + {value: 0x0808, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x90}, + {value: 0x0a18, lo: 0x91, hi: 0x93}, + {value: 0x0c18, lo: 0x94, hi: 0x94}, + {value: 0x0818, lo: 0x95, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xad, offset 0x516 + {value: 0x0000, lo: 0x05}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xae, offset 0x51c + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x91}, + {value: 0x0018, lo: 0x92, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xaf, offset 0x525 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0xb0, offset 0x531 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb1, offset 0x538 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb2}, + {value: 0x3b08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xbf}, + // Block 0xb2, offset 0x541 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xb3, offset 0x54b + {value: 0x0000, lo: 0x06}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xbe}, + {value: 0x3008, lo: 0xbf, hi: 0xbf}, + // Block 0xb4, offset 0x552 + {value: 0x0000, lo: 0x0d}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xb5, offset 0x560 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3808, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xb6, offset 0x56d + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0008, lo: 0x9f, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xb7, offset 0x57a + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x3308, lo: 0x9f, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa9}, + {value: 0x3b08, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb8, offset 0x583 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xb9, offset 0x587 + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xba, offset 0x596 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xbb, offset 0x59e + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x85}, + {value: 0x0018, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xbc, offset 0x5a9 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbd, offset 0x5b2 + {value: 0x0000, lo: 0x05}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9b}, + {value: 0x3308, lo: 0x9c, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xbe, offset 0x5b8 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbf, offset 0x5c0 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xc0, offset 0x5c9 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb5}, + {value: 0x3808, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0xc1, offset 0x5d3 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0xc2, offset 0x5d6 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0xc3, offset 0x5e2 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xc4, offset 0x5eb + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xbf}, + // Block 0xc5, offset 0x5ee + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0xc6, offset 0x5f3 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xc7, offset 0x5fe + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x3b08, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0xbf}, + // Block 0xc8, offset 0x607 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x98}, + {value: 0x3b08, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xbf}, + // Block 0xc9, offset 0x613 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xca, offset 0x616 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xcb, offset 0x620 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xbf}, + // Block 0xcc, offset 0x629 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xaa, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xcd, offset 0x635 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xce, offset 0x642 + {value: 0x0000, lo: 0x0c}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xbf}, + // Block 0xcf, offset 0x64f + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x3008, lo: 0x93, hi: 0x94}, + {value: 0x3308, lo: 0x95, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x96}, + {value: 0x3b08, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xbf}, + // Block 0xd0, offset 0x65d + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xd1, offset 0x664 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xd2, offset 0x667 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xd3, offset 0x66c + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0xbf}, + // Block 0xd4, offset 0x66f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xbf}, + // Block 0xd5, offset 0x672 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xbf}, + // Block 0xd6, offset 0x675 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xd7, offset 0x67c + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xd8, offset 0x683 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0xd9, offset 0x687 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0xda, offset 0x692 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xdb, offset 0x695 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0xdc, offset 0x698 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0xdd, offset 0x69b + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3008, lo: 0x91, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xde, offset 0x6a1 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xdf, offset 0x6a6 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xbf}, + // Block 0xe0, offset 0x6aa + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe1, offset 0x6ad + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xe2, offset 0x6b0 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xe3, offset 0x6b3 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xe4, offset 0x6b6 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xe5, offset 0x6b9 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0xe6, offset 0x6be + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x03c0, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xbf}, + // Block 0xe7, offset 0x6c8 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xe8, offset 0x6cb + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xbf}, + // Block 0xe9, offset 0x6cf + {value: 0x0000, lo: 0x0e}, + {value: 0x0018, lo: 0x80, hi: 0x9d}, + {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, + {value: 0xb601, lo: 0x9f, hi: 0x9f}, + {value: 0xb649, lo: 0xa0, hi: 0xa0}, + {value: 0xb6b1, lo: 0xa1, hi: 0xa1}, + {value: 0xb719, lo: 0xa2, hi: 0xa2}, + {value: 0xb781, lo: 0xa3, hi: 0xa3}, + {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, + {value: 0x3018, lo: 0xa5, hi: 0xa6}, + {value: 0x3318, lo: 0xa7, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xac}, + {value: 0x3018, lo: 0xad, hi: 0xb2}, + {value: 0x0340, lo: 0xb3, hi: 0xba}, + {value: 0x3318, lo: 0xbb, hi: 0xbf}, + // Block 0xea, offset 0x6de + {value: 0x0000, lo: 0x0b}, + {value: 0x3318, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0x84}, + {value: 0x3318, lo: 0x85, hi: 0x8b}, + {value: 0x0018, lo: 0x8c, hi: 0xa9}, + {value: 0x3318, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xba}, + {value: 0xb851, lo: 0xbb, hi: 0xbb}, + {value: 0xb899, lo: 0xbc, hi: 0xbc}, + {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, + {value: 0xb949, lo: 0xbe, hi: 0xbe}, + {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, + // Block 0xeb, offset 0x6ea + {value: 0x0000, lo: 0x03}, + {value: 0xba19, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xbf}, + // Block 0xec, offset 0x6ee + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x3318, lo: 0x82, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0xbf}, + // Block 0xed, offset 0x6f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0xee, offset 0x6f7 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xef, offset 0x6fc + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xf0, offset 0x700 + {value: 0x0000, lo: 0x04}, + {value: 0x3308, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0xf1, offset 0x705 + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x3308, lo: 0xa1, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xf2, offset 0x70e + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0xf3, offset 0x719 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x86}, + {value: 0x0818, lo: 0x87, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xf4, offset 0x71f + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xf5, offset 0x727 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xb0}, + {value: 0x0818, lo: 0xb1, hi: 0xbf}, + // Block 0xf6, offset 0x72a + {value: 0x0000, lo: 0x02}, + {value: 0x0818, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xf7, offset 0x72d + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xf8, offset 0x731 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0xf9, offset 0x735 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0xfa, offset 0x73b + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xfb, offset 0x741 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0xc1c1, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xfc, offset 0x746 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xbf}, + // Block 0xfd, offset 0x749 + {value: 0x0000, lo: 0x0f}, + {value: 0xc7e9, lo: 0x80, hi: 0x80}, + {value: 0xc839, lo: 0x81, hi: 0x81}, + {value: 0xc889, lo: 0x82, hi: 0x82}, + {value: 0xc8d9, lo: 0x83, hi: 0x83}, + {value: 0xc929, lo: 0x84, hi: 0x84}, + {value: 0xc979, lo: 0x85, hi: 0x85}, + {value: 0xc9c9, lo: 0x86, hi: 0x86}, + {value: 0xca19, lo: 0x87, hi: 0x87}, + {value: 0xca69, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0xcab9, lo: 0x90, hi: 0x90}, + {value: 0xcad9, lo: 0x91, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xbf}, + // Block 0xfe, offset 0x759 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xff, offset 0x760 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x100, offset 0x763 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0xbf}, + // Block 0x101, offset 0x766 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x102, offset 0x76a + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x103, offset 0x770 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0x104, offset 0x775 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x105, offset 0x77a + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb2}, + {value: 0x0018, lo: 0xb3, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x106, offset 0x782 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x107, offset 0x787 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x108, offset 0x78b + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0x109, offset 0x78f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0x10a, offset 0x792 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x10b, offset 0x795 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x10c, offset 0x799 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x10d, offset 0x79d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x10e, offset 0x7a0 + {value: 0x0020, lo: 0x0f}, + {value: 0xdeb9, lo: 0x80, hi: 0x89}, + {value: 0x8dfd, lo: 0x8a, hi: 0x8a}, + {value: 0xdff9, lo: 0x8b, hi: 0x9c}, + {value: 0x8e1d, lo: 0x9d, hi: 0x9d}, + {value: 0xe239, lo: 0x9e, hi: 0xa2}, + {value: 0x8e3d, lo: 0xa3, hi: 0xa3}, + {value: 0xe2d9, lo: 0xa4, hi: 0xab}, + {value: 0x7ed5, lo: 0xac, hi: 0xac}, + {value: 0xe3d9, lo: 0xad, hi: 0xaf}, + {value: 0x8e5d, lo: 0xb0, hi: 0xb0}, + {value: 0xe439, lo: 0xb1, hi: 0xb6}, + {value: 0x8e7d, lo: 0xb7, hi: 0xb9}, + {value: 0xe4f9, lo: 0xba, hi: 0xba}, + {value: 0x8edd, lo: 0xbb, hi: 0xbb}, + {value: 0xe519, lo: 0xbc, hi: 0xbf}, + // Block 0x10f, offset 0x7b0 + {value: 0x0020, lo: 0x10}, + {value: 0x937d, lo: 0x80, hi: 0x80}, + {value: 0xf099, lo: 0x81, hi: 0x86}, + {value: 0x939d, lo: 0x87, hi: 0x8a}, + {value: 0xd9f9, lo: 0x8b, hi: 0x8b}, + {value: 0xf159, lo: 0x8c, hi: 0x96}, + {value: 0x941d, lo: 0x97, hi: 0x97}, + {value: 0xf2b9, lo: 0x98, hi: 0xa3}, + {value: 0x943d, lo: 0xa4, hi: 0xa6}, + {value: 0xf439, lo: 0xa7, hi: 0xaa}, + {value: 0x949d, lo: 0xab, hi: 0xab}, + {value: 0xf4b9, lo: 0xac, hi: 0xac}, + {value: 0x94bd, lo: 0xad, hi: 0xad}, + {value: 0xf4d9, lo: 0xae, hi: 0xaf}, + {value: 0x94dd, lo: 0xb0, hi: 0xb1}, + {value: 0xf519, lo: 0xb2, hi: 0xbe}, + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0x110, offset 0x7c1 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0340, lo: 0x81, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x9f}, + {value: 0x0340, lo: 0xa0, hi: 0xbf}, + // Block 0x111, offset 0x7c6 + {value: 0x0000, lo: 0x01}, + {value: 0x0340, lo: 0x80, hi: 0xbf}, + // Block 0x112, offset 0x7c8 + {value: 0x0000, lo: 0x01}, + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x113, offset 0x7ca + {value: 0x0000, lo: 0x02}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, +} + +// Total table size 42466 bytes (41KiB); checksum: 355A58A4 diff --git a/vendor/golang.org/x/net/idna/tables9.0.0.go b/vendor/golang.org/x/net/idna/tables9.0.0.go new file mode 100644 index 000000000..8b65fa167 --- /dev/null +++ b/vendor/golang.org/x/net/idna/tables9.0.0.go @@ -0,0 +1,4486 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build !go1.10 + +package idna + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "9.0.0" + +var mappings string = "" + // Size: 8175 bytes + "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + + "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + + "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + + "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" + + "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" + + "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" + + "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" + + "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" + + "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" + + "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" + + "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" + + "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" + + "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" + + "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" + + "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" + + "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" + + "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" + + "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" + + "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" + + "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" + + "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" + + "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" + + "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" + + "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" + + "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" + + "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" + + ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" + + "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" + + "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" + + "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" + + "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" + + "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" + + "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" + + "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" + + "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" + + "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" + + "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" + + "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" + + "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" + + "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" + + "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" + + "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" + + "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" + + "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" + + "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" + + "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" + + "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" + + "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" + + "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" + + "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" + + "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" + + "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" + + "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" + + "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" + + "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" + + "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" + + "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" + + "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" + + "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" + + "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" + + "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" + + "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" + + "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" + + "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" + + "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" + + "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" + + "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" + + "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" + + "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" + + "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" + + "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" + + "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" + + "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" + + " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" + + "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" + + "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" + + "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" + + "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" + + "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" + + "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" + + "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" + + "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" + + "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" + + "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" + + "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" + + "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" + + "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" + + "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" + + "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" + + "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" + + "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" + + "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" + + "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" + + "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" + + "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" + + "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" + + "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" + + "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" + + "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" + + "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" + + "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" + + "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" + + "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" + + "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" + + "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" + + "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" + + "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" + + "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" + + "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" + + "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" + + "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" + + "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" + + "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" + + "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" + + "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" + + "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" + + "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" + + "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" + + "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" + + "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" + + "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" + + "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" + + "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" + + "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" + + "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" + + "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" + + "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" + + "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" + + "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" + + "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" + + "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" + + "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" + + "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" + + "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" + + "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" + + "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" + + "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻" + +var xorData string = "" + // Size: 4855 bytes + "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" + + "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" + + "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" + + "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" + + "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" + + "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" + + "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" + + "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" + + "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" + + "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" + + "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" + + "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" + + "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" + + "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" + + "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" + + "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" + + "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" + + "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" + + "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" + + "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" + + "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" + + "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" + + "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" + + "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" + + "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" + + "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" + + "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" + + "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" + + "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" + + "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" + + "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" + + "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" + + "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" + + "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" + + "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" + + "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" + + "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " + + "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" + + "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" + + "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" + + "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" + + "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" + + ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" + + "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" + + "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" + + "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" + + "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" + + "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" + + "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" + + "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" + + "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" + + "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" + + "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" + + "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" + + "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" + + "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" + + "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" + + "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" + + "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" + + "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" + + "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" + + "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" + + "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" + + "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" + + "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" + + "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" + + "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" + + "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" + + "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" + + "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" + + "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" + + "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" + + "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" + + "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" + + "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" + + "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" + + "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" + + "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" + + "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" + + "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" + + "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" + + "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" + + "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" + + "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" + + "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" + + "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" + + "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" + + "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" + + "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," + + "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" + + "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" + + "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" + + "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" + + ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" + + "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" + + "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" + + "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" + + "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" + + "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" + + "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" + + "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" + + "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" + + "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" + + "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" + + "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" + + "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" + + "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" + + "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" + + "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" + + "\x08\x1a\x0a\x03\x07\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" + + "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" + + "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" + + "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" + + "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" + + "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" + + "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" + + "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" + + "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" + + "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" + + "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" + + "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" + + "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" + + "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" + + "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" + + "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" + + "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" + + "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." + + "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" + + "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" + + "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " + + "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" + + "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" + + "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" + + "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" + + "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" + + "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" + + "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," + + "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" + + "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" + + "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" + + "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" + + "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" + + "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" + + "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" + + "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" + + "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" + + "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" + + "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" + + "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" + + "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" + + "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" + + "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" + + "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" + + "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" + + "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" + + "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" + + "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" + + "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" + + "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" + + "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" + + "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" + + "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" + + "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" + + "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" + + "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" + + "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" + + "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" + + "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" + + "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" + + "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" + + "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" + + "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" + + "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" + + "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" + + "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" + + "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," + + "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" + + "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" + + "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" + + "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" + + "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" + + "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" + + "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" + + "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" + + "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" + + "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" + + "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" + + "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" + + "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" + + "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" + + "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" + + "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" + + "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" + + "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" + + "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" + + "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" + + "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" + + "\x04\x03\x0c?\x05\x03\x0c" + + "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" + + "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" + + "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" + + "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" + + "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" + + "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" + + "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" + + "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" + + "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" + + "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" + + "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" + + "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" + + "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" + + "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" + + "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" + + "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" + + "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" + + "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" + + "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" + + "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" + + "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" + + "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" + + "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" + + "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" + + "\x05\x22\x05\x03\x050\x1d" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// idnaTrie. Total size: 28600 bytes (27.93 KiB). Checksum: 95575047b5d8fff. +type idnaTrie struct{} + +func newIdnaTrie(i int) *idnaTrie { + return &idnaTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 124: + return uint16(idnaValues[n<<6+uint32(b)]) + default: + n -= 124 + return uint16(idnaSparse.lookup(n, b)) + } +} + +// idnaValues: 126 blocks, 8064 entries, 16128 bytes +// The third block is the zero block. +var idnaValues = [8064]uint16{ + // Block 0x0, offset 0x0 + 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, + 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, + 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080, + 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080, + 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080, + 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080, + 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080, + 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080, + 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008, + 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080, + 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080, + // Block 0x1, offset 0x40 + 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105, + 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105, + 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105, + 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105, + 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080, + 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008, + 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008, + 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008, + 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008, + 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080, + 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018, + 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018, + 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a, + 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005, + 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018, + 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018, + // Block 0x4, offset 0x100 + 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008, + 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008, + 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008, + 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008, + 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008, + 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008, + 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008, + 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008, + 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008, + 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d, + 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199, + // Block 0x5, offset 0x140 + 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d, + 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008, + 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008, + 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008, + 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008, + 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008, + 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008, + 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008, + 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008, + 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d, + 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9, + // Block 0x6, offset 0x180 + 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008, + 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d, + 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d, + 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d, + 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155, + 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008, + 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d, + 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd, + 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d, + 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008, + 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9, + 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d, + 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d, + 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d, + 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008, + 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008, + 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008, + 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008, + 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008, + 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008, + 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008, + // Block 0x8, offset 0x200 + 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008, + 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008, + 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008, + 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008, + 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008, + 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008, + 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008, + 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008, + 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008, + 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d, + 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008, + // Block 0x9, offset 0x240 + 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018, + 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008, + 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008, + 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018, + 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a, + 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369, + 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018, + 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018, + 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018, + 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, + 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, + // Block 0xa, offset 0x280 + 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, + 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, + 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, + 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, + 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, + 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, + 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, + 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, + 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, + 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, + 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2, + 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040, + 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105, + 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105, + 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105, + 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d, + 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d, + 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008, + 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008, + 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008, + 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008, + // Block 0xc, offset 0x300 + 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008, + 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008, + 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd, + 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008, + 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008, + 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008, + 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008, + 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008, + 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd, + 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008, + 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d, + // Block 0xd, offset 0x340 + 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008, + 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008, + 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008, + 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008, + 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008, + 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008, + 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008, + 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008, + 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008, + 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, + 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, + // Block 0xe, offset 0x380 + 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, + 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, + 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, + 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, + 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, + 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008, + 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008, + 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008, + 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008, + 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008, + 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d, + 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d, + 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008, + 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008, + 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008, + 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008, + 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008, + 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008, + 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008, + 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008, + 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008, + // Block 0x10, offset 0x400 + 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008, + 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008, + 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008, + 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008, + 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008, + 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008, + 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008, + 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008, + 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5, + 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, + 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, + // Block 0x11, offset 0x440 + 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, + 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, + 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, + 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, + 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, + 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, + 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, + 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, + 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, + 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, + 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, + // Block 0x12, offset 0x480 + 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, + 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, + 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, + 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, + 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, + 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, + 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, + 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, + 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, + 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, + 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, + 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, + 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, + 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, + 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, + 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, + 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, + 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, + 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, + 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, + 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, + // Block 0x14, offset 0x500 + 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, + 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, + 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, + 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, + 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, + 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, + 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, + 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, + 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, + 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, + 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, + // Block 0x15, offset 0x540 + 0x540: 0x3008, 0x541: 0x3308, 0x542: 0x3308, 0x543: 0x3308, 0x544: 0x3308, 0x545: 0x3308, + 0x546: 0x3308, 0x547: 0x3308, 0x548: 0x3308, 0x549: 0x3008, 0x54a: 0x3008, 0x54b: 0x3008, + 0x54c: 0x3008, 0x54d: 0x3b08, 0x54e: 0x3008, 0x54f: 0x3008, 0x550: 0x0008, 0x551: 0x3308, + 0x552: 0x3308, 0x553: 0x3308, 0x554: 0x3308, 0x555: 0x3308, 0x556: 0x3308, 0x557: 0x3308, + 0x558: 0x04c9, 0x559: 0x0501, 0x55a: 0x0539, 0x55b: 0x0571, 0x55c: 0x05a9, 0x55d: 0x05e1, + 0x55e: 0x0619, 0x55f: 0x0651, 0x560: 0x0008, 0x561: 0x0008, 0x562: 0x3308, 0x563: 0x3308, + 0x564: 0x0018, 0x565: 0x0018, 0x566: 0x0008, 0x567: 0x0008, 0x568: 0x0008, 0x569: 0x0008, + 0x56a: 0x0008, 0x56b: 0x0008, 0x56c: 0x0008, 0x56d: 0x0008, 0x56e: 0x0008, 0x56f: 0x0008, + 0x570: 0x0018, 0x571: 0x0008, 0x572: 0x0008, 0x573: 0x0008, 0x574: 0x0008, 0x575: 0x0008, + 0x576: 0x0008, 0x577: 0x0008, 0x578: 0x0008, 0x579: 0x0008, 0x57a: 0x0008, 0x57b: 0x0008, + 0x57c: 0x0008, 0x57d: 0x0008, 0x57e: 0x0008, 0x57f: 0x0008, + // Block 0x16, offset 0x580 + 0x580: 0x0008, 0x581: 0x3308, 0x582: 0x3008, 0x583: 0x3008, 0x584: 0x0040, 0x585: 0x0008, + 0x586: 0x0008, 0x587: 0x0008, 0x588: 0x0008, 0x589: 0x0008, 0x58a: 0x0008, 0x58b: 0x0008, + 0x58c: 0x0008, 0x58d: 0x0040, 0x58e: 0x0040, 0x58f: 0x0008, 0x590: 0x0008, 0x591: 0x0040, + 0x592: 0x0040, 0x593: 0x0008, 0x594: 0x0008, 0x595: 0x0008, 0x596: 0x0008, 0x597: 0x0008, + 0x598: 0x0008, 0x599: 0x0008, 0x59a: 0x0008, 0x59b: 0x0008, 0x59c: 0x0008, 0x59d: 0x0008, + 0x59e: 0x0008, 0x59f: 0x0008, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x0008, 0x5a3: 0x0008, + 0x5a4: 0x0008, 0x5a5: 0x0008, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0040, + 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, + 0x5b0: 0x0008, 0x5b1: 0x0040, 0x5b2: 0x0008, 0x5b3: 0x0040, 0x5b4: 0x0040, 0x5b5: 0x0040, + 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0040, 0x5bb: 0x0040, + 0x5bc: 0x3308, 0x5bd: 0x0008, 0x5be: 0x3008, 0x5bf: 0x3008, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x3008, 0x5c1: 0x3308, 0x5c2: 0x3308, 0x5c3: 0x3308, 0x5c4: 0x3308, 0x5c5: 0x0040, + 0x5c6: 0x0040, 0x5c7: 0x3008, 0x5c8: 0x3008, 0x5c9: 0x0040, 0x5ca: 0x0040, 0x5cb: 0x3008, + 0x5cc: 0x3008, 0x5cd: 0x3b08, 0x5ce: 0x0008, 0x5cf: 0x0040, 0x5d0: 0x0040, 0x5d1: 0x0040, + 0x5d2: 0x0040, 0x5d3: 0x0040, 0x5d4: 0x0040, 0x5d5: 0x0040, 0x5d6: 0x0040, 0x5d7: 0x3008, + 0x5d8: 0x0040, 0x5d9: 0x0040, 0x5da: 0x0040, 0x5db: 0x0040, 0x5dc: 0x0689, 0x5dd: 0x06c1, + 0x5de: 0x0040, 0x5df: 0x06f9, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x3308, 0x5e3: 0x3308, + 0x5e4: 0x0040, 0x5e5: 0x0040, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0008, + 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, + 0x5f0: 0x0008, 0x5f1: 0x0008, 0x5f2: 0x0018, 0x5f3: 0x0018, 0x5f4: 0x0018, 0x5f5: 0x0018, + 0x5f6: 0x0018, 0x5f7: 0x0018, 0x5f8: 0x0018, 0x5f9: 0x0018, 0x5fa: 0x0018, 0x5fb: 0x0018, + 0x5fc: 0x0040, 0x5fd: 0x0040, 0x5fe: 0x0040, 0x5ff: 0x0040, + // Block 0x18, offset 0x600 + 0x600: 0x0040, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3008, 0x604: 0x0040, 0x605: 0x0008, + 0x606: 0x0008, 0x607: 0x0008, 0x608: 0x0008, 0x609: 0x0008, 0x60a: 0x0008, 0x60b: 0x0040, + 0x60c: 0x0040, 0x60d: 0x0040, 0x60e: 0x0040, 0x60f: 0x0008, 0x610: 0x0008, 0x611: 0x0040, + 0x612: 0x0040, 0x613: 0x0008, 0x614: 0x0008, 0x615: 0x0008, 0x616: 0x0008, 0x617: 0x0008, + 0x618: 0x0008, 0x619: 0x0008, 0x61a: 0x0008, 0x61b: 0x0008, 0x61c: 0x0008, 0x61d: 0x0008, + 0x61e: 0x0008, 0x61f: 0x0008, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x0008, 0x623: 0x0008, + 0x624: 0x0008, 0x625: 0x0008, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0040, + 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, + 0x630: 0x0008, 0x631: 0x0040, 0x632: 0x0008, 0x633: 0x0731, 0x634: 0x0040, 0x635: 0x0008, + 0x636: 0x0769, 0x637: 0x0040, 0x638: 0x0008, 0x639: 0x0008, 0x63a: 0x0040, 0x63b: 0x0040, + 0x63c: 0x3308, 0x63d: 0x0040, 0x63e: 0x3008, 0x63f: 0x3008, + // Block 0x19, offset 0x640 + 0x640: 0x3008, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x0040, 0x644: 0x0040, 0x645: 0x0040, + 0x646: 0x0040, 0x647: 0x3308, 0x648: 0x3308, 0x649: 0x0040, 0x64a: 0x0040, 0x64b: 0x3308, + 0x64c: 0x3308, 0x64d: 0x3b08, 0x64e: 0x0040, 0x64f: 0x0040, 0x650: 0x0040, 0x651: 0x3308, + 0x652: 0x0040, 0x653: 0x0040, 0x654: 0x0040, 0x655: 0x0040, 0x656: 0x0040, 0x657: 0x0040, + 0x658: 0x0040, 0x659: 0x07a1, 0x65a: 0x07d9, 0x65b: 0x0811, 0x65c: 0x0008, 0x65d: 0x0040, + 0x65e: 0x0849, 0x65f: 0x0040, 0x660: 0x0040, 0x661: 0x0040, 0x662: 0x0040, 0x663: 0x0040, + 0x664: 0x0040, 0x665: 0x0040, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0008, + 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, + 0x670: 0x3308, 0x671: 0x3308, 0x672: 0x0008, 0x673: 0x0008, 0x674: 0x0008, 0x675: 0x3308, + 0x676: 0x0040, 0x677: 0x0040, 0x678: 0x0040, 0x679: 0x0040, 0x67a: 0x0040, 0x67b: 0x0040, + 0x67c: 0x0040, 0x67d: 0x0040, 0x67e: 0x0040, 0x67f: 0x0040, + // Block 0x1a, offset 0x680 + 0x680: 0x0040, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x3008, 0x684: 0x0040, 0x685: 0x0008, + 0x686: 0x0008, 0x687: 0x0008, 0x688: 0x0008, 0x689: 0x0008, 0x68a: 0x0008, 0x68b: 0x0008, + 0x68c: 0x0008, 0x68d: 0x0008, 0x68e: 0x0040, 0x68f: 0x0008, 0x690: 0x0008, 0x691: 0x0008, + 0x692: 0x0040, 0x693: 0x0008, 0x694: 0x0008, 0x695: 0x0008, 0x696: 0x0008, 0x697: 0x0008, + 0x698: 0x0008, 0x699: 0x0008, 0x69a: 0x0008, 0x69b: 0x0008, 0x69c: 0x0008, 0x69d: 0x0008, + 0x69e: 0x0008, 0x69f: 0x0008, 0x6a0: 0x0008, 0x6a1: 0x0008, 0x6a2: 0x0008, 0x6a3: 0x0008, + 0x6a4: 0x0008, 0x6a5: 0x0008, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0040, + 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, + 0x6b0: 0x0008, 0x6b1: 0x0040, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0040, 0x6b5: 0x0008, + 0x6b6: 0x0008, 0x6b7: 0x0008, 0x6b8: 0x0008, 0x6b9: 0x0008, 0x6ba: 0x0040, 0x6bb: 0x0040, + 0x6bc: 0x3308, 0x6bd: 0x0008, 0x6be: 0x3008, 0x6bf: 0x3008, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x3008, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3308, 0x6c4: 0x3308, 0x6c5: 0x3308, + 0x6c6: 0x0040, 0x6c7: 0x3308, 0x6c8: 0x3308, 0x6c9: 0x3008, 0x6ca: 0x0040, 0x6cb: 0x3008, + 0x6cc: 0x3008, 0x6cd: 0x3b08, 0x6ce: 0x0040, 0x6cf: 0x0040, 0x6d0: 0x0008, 0x6d1: 0x0040, + 0x6d2: 0x0040, 0x6d3: 0x0040, 0x6d4: 0x0040, 0x6d5: 0x0040, 0x6d6: 0x0040, 0x6d7: 0x0040, + 0x6d8: 0x0040, 0x6d9: 0x0040, 0x6da: 0x0040, 0x6db: 0x0040, 0x6dc: 0x0040, 0x6dd: 0x0040, + 0x6de: 0x0040, 0x6df: 0x0040, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x3308, 0x6e3: 0x3308, + 0x6e4: 0x0040, 0x6e5: 0x0040, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0008, + 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, + 0x6f0: 0x0018, 0x6f1: 0x0018, 0x6f2: 0x0040, 0x6f3: 0x0040, 0x6f4: 0x0040, 0x6f5: 0x0040, + 0x6f6: 0x0040, 0x6f7: 0x0040, 0x6f8: 0x0040, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, + 0x6fc: 0x0040, 0x6fd: 0x0040, 0x6fe: 0x0040, 0x6ff: 0x0040, + // Block 0x1c, offset 0x700 + 0x700: 0x0040, 0x701: 0x3308, 0x702: 0x3008, 0x703: 0x3008, 0x704: 0x0040, 0x705: 0x0008, + 0x706: 0x0008, 0x707: 0x0008, 0x708: 0x0008, 0x709: 0x0008, 0x70a: 0x0008, 0x70b: 0x0008, + 0x70c: 0x0008, 0x70d: 0x0040, 0x70e: 0x0040, 0x70f: 0x0008, 0x710: 0x0008, 0x711: 0x0040, + 0x712: 0x0040, 0x713: 0x0008, 0x714: 0x0008, 0x715: 0x0008, 0x716: 0x0008, 0x717: 0x0008, + 0x718: 0x0008, 0x719: 0x0008, 0x71a: 0x0008, 0x71b: 0x0008, 0x71c: 0x0008, 0x71d: 0x0008, + 0x71e: 0x0008, 0x71f: 0x0008, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x0008, 0x723: 0x0008, + 0x724: 0x0008, 0x725: 0x0008, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0040, + 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, + 0x730: 0x0008, 0x731: 0x0040, 0x732: 0x0008, 0x733: 0x0008, 0x734: 0x0040, 0x735: 0x0008, + 0x736: 0x0008, 0x737: 0x0008, 0x738: 0x0008, 0x739: 0x0008, 0x73a: 0x0040, 0x73b: 0x0040, + 0x73c: 0x3308, 0x73d: 0x0008, 0x73e: 0x3008, 0x73f: 0x3308, + // Block 0x1d, offset 0x740 + 0x740: 0x3008, 0x741: 0x3308, 0x742: 0x3308, 0x743: 0x3308, 0x744: 0x3308, 0x745: 0x0040, + 0x746: 0x0040, 0x747: 0x3008, 0x748: 0x3008, 0x749: 0x0040, 0x74a: 0x0040, 0x74b: 0x3008, + 0x74c: 0x3008, 0x74d: 0x3b08, 0x74e: 0x0040, 0x74f: 0x0040, 0x750: 0x0040, 0x751: 0x0040, + 0x752: 0x0040, 0x753: 0x0040, 0x754: 0x0040, 0x755: 0x0040, 0x756: 0x3308, 0x757: 0x3008, + 0x758: 0x0040, 0x759: 0x0040, 0x75a: 0x0040, 0x75b: 0x0040, 0x75c: 0x0881, 0x75d: 0x08b9, + 0x75e: 0x0040, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x3308, 0x763: 0x3308, + 0x764: 0x0040, 0x765: 0x0040, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0008, + 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, + 0x770: 0x0018, 0x771: 0x0008, 0x772: 0x0018, 0x773: 0x0018, 0x774: 0x0018, 0x775: 0x0018, + 0x776: 0x0018, 0x777: 0x0018, 0x778: 0x0040, 0x779: 0x0040, 0x77a: 0x0040, 0x77b: 0x0040, + 0x77c: 0x0040, 0x77d: 0x0040, 0x77e: 0x0040, 0x77f: 0x0040, + // Block 0x1e, offset 0x780 + 0x780: 0x0040, 0x781: 0x0040, 0x782: 0x3308, 0x783: 0x0008, 0x784: 0x0040, 0x785: 0x0008, + 0x786: 0x0008, 0x787: 0x0008, 0x788: 0x0008, 0x789: 0x0008, 0x78a: 0x0008, 0x78b: 0x0040, + 0x78c: 0x0040, 0x78d: 0x0040, 0x78e: 0x0008, 0x78f: 0x0008, 0x790: 0x0008, 0x791: 0x0040, + 0x792: 0x0008, 0x793: 0x0008, 0x794: 0x0008, 0x795: 0x0008, 0x796: 0x0040, 0x797: 0x0040, + 0x798: 0x0040, 0x799: 0x0008, 0x79a: 0x0008, 0x79b: 0x0040, 0x79c: 0x0008, 0x79d: 0x0040, + 0x79e: 0x0008, 0x79f: 0x0008, 0x7a0: 0x0040, 0x7a1: 0x0040, 0x7a2: 0x0040, 0x7a3: 0x0008, + 0x7a4: 0x0008, 0x7a5: 0x0040, 0x7a6: 0x0040, 0x7a7: 0x0040, 0x7a8: 0x0008, 0x7a9: 0x0008, + 0x7aa: 0x0008, 0x7ab: 0x0040, 0x7ac: 0x0040, 0x7ad: 0x0040, 0x7ae: 0x0008, 0x7af: 0x0008, + 0x7b0: 0x0008, 0x7b1: 0x0008, 0x7b2: 0x0008, 0x7b3: 0x0008, 0x7b4: 0x0008, 0x7b5: 0x0008, + 0x7b6: 0x0008, 0x7b7: 0x0008, 0x7b8: 0x0008, 0x7b9: 0x0008, 0x7ba: 0x0040, 0x7bb: 0x0040, + 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x3008, 0x7bf: 0x3008, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x3308, 0x7c1: 0x3008, 0x7c2: 0x3008, 0x7c3: 0x3008, 0x7c4: 0x3008, 0x7c5: 0x0040, + 0x7c6: 0x3308, 0x7c7: 0x3308, 0x7c8: 0x3308, 0x7c9: 0x0040, 0x7ca: 0x3308, 0x7cb: 0x3308, + 0x7cc: 0x3308, 0x7cd: 0x3b08, 0x7ce: 0x0040, 0x7cf: 0x0040, 0x7d0: 0x0040, 0x7d1: 0x0040, + 0x7d2: 0x0040, 0x7d3: 0x0040, 0x7d4: 0x0040, 0x7d5: 0x3308, 0x7d6: 0x3308, 0x7d7: 0x0040, + 0x7d8: 0x0008, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0040, 0x7dd: 0x0040, + 0x7de: 0x0040, 0x7df: 0x0040, 0x7e0: 0x0008, 0x7e1: 0x0008, 0x7e2: 0x3308, 0x7e3: 0x3308, + 0x7e4: 0x0040, 0x7e5: 0x0040, 0x7e6: 0x0008, 0x7e7: 0x0008, 0x7e8: 0x0008, 0x7e9: 0x0008, + 0x7ea: 0x0008, 0x7eb: 0x0008, 0x7ec: 0x0008, 0x7ed: 0x0008, 0x7ee: 0x0008, 0x7ef: 0x0008, + 0x7f0: 0x0040, 0x7f1: 0x0040, 0x7f2: 0x0040, 0x7f3: 0x0040, 0x7f4: 0x0040, 0x7f5: 0x0040, + 0x7f6: 0x0040, 0x7f7: 0x0040, 0x7f8: 0x0018, 0x7f9: 0x0018, 0x7fa: 0x0018, 0x7fb: 0x0018, + 0x7fc: 0x0018, 0x7fd: 0x0018, 0x7fe: 0x0018, 0x7ff: 0x0018, + // Block 0x20, offset 0x800 + 0x800: 0x0008, 0x801: 0x3308, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x0040, 0x805: 0x0008, + 0x806: 0x0008, 0x807: 0x0008, 0x808: 0x0008, 0x809: 0x0008, 0x80a: 0x0008, 0x80b: 0x0008, + 0x80c: 0x0008, 0x80d: 0x0040, 0x80e: 0x0008, 0x80f: 0x0008, 0x810: 0x0008, 0x811: 0x0040, + 0x812: 0x0008, 0x813: 0x0008, 0x814: 0x0008, 0x815: 0x0008, 0x816: 0x0008, 0x817: 0x0008, + 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0008, 0x81c: 0x0008, 0x81d: 0x0008, + 0x81e: 0x0008, 0x81f: 0x0008, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x0008, 0x823: 0x0008, + 0x824: 0x0008, 0x825: 0x0008, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0040, + 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, + 0x830: 0x0008, 0x831: 0x0008, 0x832: 0x0008, 0x833: 0x0008, 0x834: 0x0040, 0x835: 0x0008, + 0x836: 0x0008, 0x837: 0x0008, 0x838: 0x0008, 0x839: 0x0008, 0x83a: 0x0040, 0x83b: 0x0040, + 0x83c: 0x3308, 0x83d: 0x0008, 0x83e: 0x3008, 0x83f: 0x3308, + // Block 0x21, offset 0x840 + 0x840: 0x3008, 0x841: 0x3008, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x3008, 0x845: 0x0040, + 0x846: 0x3308, 0x847: 0x3008, 0x848: 0x3008, 0x849: 0x0040, 0x84a: 0x3008, 0x84b: 0x3008, + 0x84c: 0x3308, 0x84d: 0x3b08, 0x84e: 0x0040, 0x84f: 0x0040, 0x850: 0x0040, 0x851: 0x0040, + 0x852: 0x0040, 0x853: 0x0040, 0x854: 0x0040, 0x855: 0x3008, 0x856: 0x3008, 0x857: 0x0040, + 0x858: 0x0040, 0x859: 0x0040, 0x85a: 0x0040, 0x85b: 0x0040, 0x85c: 0x0040, 0x85d: 0x0040, + 0x85e: 0x0008, 0x85f: 0x0040, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x3308, 0x863: 0x3308, + 0x864: 0x0040, 0x865: 0x0040, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0008, + 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, + 0x870: 0x0040, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0040, 0x874: 0x0040, 0x875: 0x0040, + 0x876: 0x0040, 0x877: 0x0040, 0x878: 0x0040, 0x879: 0x0040, 0x87a: 0x0040, 0x87b: 0x0040, + 0x87c: 0x0040, 0x87d: 0x0040, 0x87e: 0x0040, 0x87f: 0x0040, + // Block 0x22, offset 0x880 + 0x880: 0x3008, 0x881: 0x3308, 0x882: 0x3308, 0x883: 0x3308, 0x884: 0x3308, 0x885: 0x0040, + 0x886: 0x3008, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, + 0x88c: 0x3008, 0x88d: 0x3b08, 0x88e: 0x0008, 0x88f: 0x0018, 0x890: 0x0040, 0x891: 0x0040, + 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0008, 0x895: 0x0008, 0x896: 0x0008, 0x897: 0x3008, + 0x898: 0x0018, 0x899: 0x0018, 0x89a: 0x0018, 0x89b: 0x0018, 0x89c: 0x0018, 0x89d: 0x0018, + 0x89e: 0x0018, 0x89f: 0x0008, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, + 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, + 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, + 0x8b0: 0x0018, 0x8b1: 0x0018, 0x8b2: 0x0018, 0x8b3: 0x0018, 0x8b4: 0x0018, 0x8b5: 0x0018, + 0x8b6: 0x0018, 0x8b7: 0x0018, 0x8b8: 0x0018, 0x8b9: 0x0018, 0x8ba: 0x0008, 0x8bb: 0x0008, + 0x8bc: 0x0008, 0x8bd: 0x0008, 0x8be: 0x0008, 0x8bf: 0x0008, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0040, 0x8c1: 0x0008, 0x8c2: 0x0008, 0x8c3: 0x0040, 0x8c4: 0x0008, 0x8c5: 0x0040, + 0x8c6: 0x0040, 0x8c7: 0x0008, 0x8c8: 0x0008, 0x8c9: 0x0040, 0x8ca: 0x0008, 0x8cb: 0x0040, + 0x8cc: 0x0040, 0x8cd: 0x0008, 0x8ce: 0x0040, 0x8cf: 0x0040, 0x8d0: 0x0040, 0x8d1: 0x0040, + 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x0008, + 0x8d8: 0x0040, 0x8d9: 0x0008, 0x8da: 0x0008, 0x8db: 0x0008, 0x8dc: 0x0008, 0x8dd: 0x0008, + 0x8de: 0x0008, 0x8df: 0x0008, 0x8e0: 0x0040, 0x8e1: 0x0008, 0x8e2: 0x0008, 0x8e3: 0x0008, + 0x8e4: 0x0040, 0x8e5: 0x0008, 0x8e6: 0x0040, 0x8e7: 0x0008, 0x8e8: 0x0040, 0x8e9: 0x0040, + 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0040, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, + 0x8f0: 0x0008, 0x8f1: 0x3308, 0x8f2: 0x0008, 0x8f3: 0x0929, 0x8f4: 0x3308, 0x8f5: 0x3308, + 0x8f6: 0x3308, 0x8f7: 0x3308, 0x8f8: 0x3308, 0x8f9: 0x3308, 0x8fa: 0x0040, 0x8fb: 0x3308, + 0x8fc: 0x3308, 0x8fd: 0x0008, 0x8fe: 0x0040, 0x8ff: 0x0040, + // Block 0x24, offset 0x900 + 0x900: 0x0008, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x09d1, 0x904: 0x0008, 0x905: 0x0008, + 0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0040, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0008, + 0x90c: 0x0008, 0x90d: 0x0a09, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008, + 0x912: 0x0a41, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0a79, + 0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0ab1, 0x91d: 0x0008, + 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, + 0x924: 0x0008, 0x925: 0x0008, 0x926: 0x0008, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0ae9, + 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0040, 0x92e: 0x0040, 0x92f: 0x0040, + 0x930: 0x0040, 0x931: 0x3308, 0x932: 0x3308, 0x933: 0x0b21, 0x934: 0x3308, 0x935: 0x0b59, + 0x936: 0x0b91, 0x937: 0x0bc9, 0x938: 0x0c19, 0x939: 0x0c51, 0x93a: 0x3308, 0x93b: 0x3308, + 0x93c: 0x3308, 0x93d: 0x3308, 0x93e: 0x3308, 0x93f: 0x3008, + // Block 0x25, offset 0x940 + 0x940: 0x3308, 0x941: 0x0ca1, 0x942: 0x3308, 0x943: 0x3308, 0x944: 0x3b08, 0x945: 0x0018, + 0x946: 0x3308, 0x947: 0x3308, 0x948: 0x0008, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, + 0x94c: 0x0008, 0x94d: 0x3308, 0x94e: 0x3308, 0x94f: 0x3308, 0x950: 0x3308, 0x951: 0x3308, + 0x952: 0x3308, 0x953: 0x0cd9, 0x954: 0x3308, 0x955: 0x3308, 0x956: 0x3308, 0x957: 0x3308, + 0x958: 0x0040, 0x959: 0x3308, 0x95a: 0x3308, 0x95b: 0x3308, 0x95c: 0x3308, 0x95d: 0x0d11, + 0x95e: 0x3308, 0x95f: 0x3308, 0x960: 0x3308, 0x961: 0x3308, 0x962: 0x0d49, 0x963: 0x3308, + 0x964: 0x3308, 0x965: 0x3308, 0x966: 0x3308, 0x967: 0x0d81, 0x968: 0x3308, 0x969: 0x3308, + 0x96a: 0x3308, 0x96b: 0x3308, 0x96c: 0x0db9, 0x96d: 0x3308, 0x96e: 0x3308, 0x96f: 0x3308, + 0x970: 0x3308, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x3308, 0x974: 0x3308, 0x975: 0x3308, + 0x976: 0x3308, 0x977: 0x3308, 0x978: 0x3308, 0x979: 0x0df1, 0x97a: 0x3308, 0x97b: 0x3308, + 0x97c: 0x3308, 0x97d: 0x0040, 0x97e: 0x0018, 0x97f: 0x0018, + // Block 0x26, offset 0x980 + 0x980: 0x0008, 0x981: 0x0008, 0x982: 0x0008, 0x983: 0x0008, 0x984: 0x0008, 0x985: 0x0008, + 0x986: 0x0008, 0x987: 0x0008, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, + 0x98c: 0x0008, 0x98d: 0x0008, 0x98e: 0x0008, 0x98f: 0x0008, 0x990: 0x0008, 0x991: 0x0008, + 0x992: 0x0008, 0x993: 0x0008, 0x994: 0x0008, 0x995: 0x0008, 0x996: 0x0008, 0x997: 0x0008, + 0x998: 0x0008, 0x999: 0x0008, 0x99a: 0x0008, 0x99b: 0x0008, 0x99c: 0x0008, 0x99d: 0x0008, + 0x99e: 0x0008, 0x99f: 0x0008, 0x9a0: 0x0008, 0x9a1: 0x0008, 0x9a2: 0x0008, 0x9a3: 0x0008, + 0x9a4: 0x0008, 0x9a5: 0x0008, 0x9a6: 0x0008, 0x9a7: 0x0008, 0x9a8: 0x0008, 0x9a9: 0x0008, + 0x9aa: 0x0008, 0x9ab: 0x0008, 0x9ac: 0x0039, 0x9ad: 0x0ed1, 0x9ae: 0x0ee9, 0x9af: 0x0008, + 0x9b0: 0x0ef9, 0x9b1: 0x0f09, 0x9b2: 0x0f19, 0x9b3: 0x0f31, 0x9b4: 0x0249, 0x9b5: 0x0f41, + 0x9b6: 0x0259, 0x9b7: 0x0f51, 0x9b8: 0x0359, 0x9b9: 0x0f61, 0x9ba: 0x0f71, 0x9bb: 0x0008, + 0x9bc: 0x00d9, 0x9bd: 0x0f81, 0x9be: 0x0f99, 0x9bf: 0x0269, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0fa9, 0x9c1: 0x0fb9, 0x9c2: 0x0279, 0x9c3: 0x0039, 0x9c4: 0x0fc9, 0x9c5: 0x0fe1, + 0x9c6: 0x059d, 0x9c7: 0x0ee9, 0x9c8: 0x0ef9, 0x9c9: 0x0f09, 0x9ca: 0x0ff9, 0x9cb: 0x1011, + 0x9cc: 0x1029, 0x9cd: 0x0f31, 0x9ce: 0x0008, 0x9cf: 0x0f51, 0x9d0: 0x0f61, 0x9d1: 0x1041, + 0x9d2: 0x00d9, 0x9d3: 0x1059, 0x9d4: 0x05b5, 0x9d5: 0x05b5, 0x9d6: 0x0f99, 0x9d7: 0x0fa9, + 0x9d8: 0x0fb9, 0x9d9: 0x059d, 0x9da: 0x1071, 0x9db: 0x1089, 0x9dc: 0x05cd, 0x9dd: 0x1099, + 0x9de: 0x10b1, 0x9df: 0x10c9, 0x9e0: 0x10e1, 0x9e1: 0x10f9, 0x9e2: 0x0f41, 0x9e3: 0x0269, + 0x9e4: 0x0fb9, 0x9e5: 0x1089, 0x9e6: 0x1099, 0x9e7: 0x10b1, 0x9e8: 0x1111, 0x9e9: 0x10e1, + 0x9ea: 0x10f9, 0x9eb: 0x0008, 0x9ec: 0x0008, 0x9ed: 0x0008, 0x9ee: 0x0008, 0x9ef: 0x0008, + 0x9f0: 0x0008, 0x9f1: 0x0008, 0x9f2: 0x0008, 0x9f3: 0x0008, 0x9f4: 0x0008, 0x9f5: 0x0008, + 0x9f6: 0x0008, 0x9f7: 0x0008, 0x9f8: 0x1129, 0x9f9: 0x0008, 0x9fa: 0x0008, 0x9fb: 0x0008, + 0x9fc: 0x0008, 0x9fd: 0x0008, 0x9fe: 0x0008, 0x9ff: 0x0008, + // Block 0x28, offset 0xa00 + 0xa00: 0x0008, 0xa01: 0x0008, 0xa02: 0x0008, 0xa03: 0x0008, 0xa04: 0x0008, 0xa05: 0x0008, + 0xa06: 0x0008, 0xa07: 0x0008, 0xa08: 0x0008, 0xa09: 0x0008, 0xa0a: 0x0008, 0xa0b: 0x0008, + 0xa0c: 0x0008, 0xa0d: 0x0008, 0xa0e: 0x0008, 0xa0f: 0x0008, 0xa10: 0x0008, 0xa11: 0x0008, + 0xa12: 0x0008, 0xa13: 0x0008, 0xa14: 0x0008, 0xa15: 0x0008, 0xa16: 0x0008, 0xa17: 0x0008, + 0xa18: 0x0008, 0xa19: 0x0008, 0xa1a: 0x0008, 0xa1b: 0x1141, 0xa1c: 0x1159, 0xa1d: 0x1169, + 0xa1e: 0x1181, 0xa1f: 0x1029, 0xa20: 0x1199, 0xa21: 0x11a9, 0xa22: 0x11c1, 0xa23: 0x11d9, + 0xa24: 0x11f1, 0xa25: 0x1209, 0xa26: 0x1221, 0xa27: 0x05e5, 0xa28: 0x1239, 0xa29: 0x1251, + 0xa2a: 0xe17d, 0xa2b: 0x1269, 0xa2c: 0x1281, 0xa2d: 0x1299, 0xa2e: 0x12b1, 0xa2f: 0x12c9, + 0xa30: 0x12e1, 0xa31: 0x12f9, 0xa32: 0x1311, 0xa33: 0x1329, 0xa34: 0x1341, 0xa35: 0x1359, + 0xa36: 0x1371, 0xa37: 0x1389, 0xa38: 0x05fd, 0xa39: 0x13a1, 0xa3a: 0x13b9, 0xa3b: 0x13d1, + 0xa3c: 0x13e1, 0xa3d: 0x13f9, 0xa3e: 0x1411, 0xa3f: 0x1429, + // Block 0x29, offset 0xa40 + 0xa40: 0xe00d, 0xa41: 0x0008, 0xa42: 0xe00d, 0xa43: 0x0008, 0xa44: 0xe00d, 0xa45: 0x0008, + 0xa46: 0xe00d, 0xa47: 0x0008, 0xa48: 0xe00d, 0xa49: 0x0008, 0xa4a: 0xe00d, 0xa4b: 0x0008, + 0xa4c: 0xe00d, 0xa4d: 0x0008, 0xa4e: 0xe00d, 0xa4f: 0x0008, 0xa50: 0xe00d, 0xa51: 0x0008, + 0xa52: 0xe00d, 0xa53: 0x0008, 0xa54: 0xe00d, 0xa55: 0x0008, 0xa56: 0xe00d, 0xa57: 0x0008, + 0xa58: 0xe00d, 0xa59: 0x0008, 0xa5a: 0xe00d, 0xa5b: 0x0008, 0xa5c: 0xe00d, 0xa5d: 0x0008, + 0xa5e: 0xe00d, 0xa5f: 0x0008, 0xa60: 0xe00d, 0xa61: 0x0008, 0xa62: 0xe00d, 0xa63: 0x0008, + 0xa64: 0xe00d, 0xa65: 0x0008, 0xa66: 0xe00d, 0xa67: 0x0008, 0xa68: 0xe00d, 0xa69: 0x0008, + 0xa6a: 0xe00d, 0xa6b: 0x0008, 0xa6c: 0xe00d, 0xa6d: 0x0008, 0xa6e: 0xe00d, 0xa6f: 0x0008, + 0xa70: 0xe00d, 0xa71: 0x0008, 0xa72: 0xe00d, 0xa73: 0x0008, 0xa74: 0xe00d, 0xa75: 0x0008, + 0xa76: 0xe00d, 0xa77: 0x0008, 0xa78: 0xe00d, 0xa79: 0x0008, 0xa7a: 0xe00d, 0xa7b: 0x0008, + 0xa7c: 0xe00d, 0xa7d: 0x0008, 0xa7e: 0xe00d, 0xa7f: 0x0008, + // Block 0x2a, offset 0xa80 + 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, + 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, + 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, + 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0x0008, 0xa97: 0x0008, + 0xa98: 0x0008, 0xa99: 0x0008, 0xa9a: 0x0615, 0xa9b: 0x0635, 0xa9c: 0x0008, 0xa9d: 0x0008, + 0xa9e: 0x1441, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, + 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, + 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, + 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, + 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, + 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, + // Block 0x2b, offset 0xac0 + 0xac0: 0x0008, 0xac1: 0x0008, 0xac2: 0x0008, 0xac3: 0x0008, 0xac4: 0x0008, 0xac5: 0x0008, + 0xac6: 0x0040, 0xac7: 0x0040, 0xac8: 0xe045, 0xac9: 0xe045, 0xaca: 0xe045, 0xacb: 0xe045, + 0xacc: 0xe045, 0xacd: 0xe045, 0xace: 0x0040, 0xacf: 0x0040, 0xad0: 0x0008, 0xad1: 0x0008, + 0xad2: 0x0008, 0xad3: 0x0008, 0xad4: 0x0008, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, + 0xad8: 0x0040, 0xad9: 0xe045, 0xada: 0x0040, 0xadb: 0xe045, 0xadc: 0x0040, 0xadd: 0xe045, + 0xade: 0x0040, 0xadf: 0xe045, 0xae0: 0x0008, 0xae1: 0x0008, 0xae2: 0x0008, 0xae3: 0x0008, + 0xae4: 0x0008, 0xae5: 0x0008, 0xae6: 0x0008, 0xae7: 0x0008, 0xae8: 0xe045, 0xae9: 0xe045, + 0xaea: 0xe045, 0xaeb: 0xe045, 0xaec: 0xe045, 0xaed: 0xe045, 0xaee: 0xe045, 0xaef: 0xe045, + 0xaf0: 0x0008, 0xaf1: 0x1459, 0xaf2: 0x0008, 0xaf3: 0x1471, 0xaf4: 0x0008, 0xaf5: 0x1489, + 0xaf6: 0x0008, 0xaf7: 0x14a1, 0xaf8: 0x0008, 0xaf9: 0x14b9, 0xafa: 0x0008, 0xafb: 0x14d1, + 0xafc: 0x0008, 0xafd: 0x14e9, 0xafe: 0x0040, 0xaff: 0x0040, + // Block 0x2c, offset 0xb00 + 0xb00: 0x1501, 0xb01: 0x1531, 0xb02: 0x1561, 0xb03: 0x1591, 0xb04: 0x15c1, 0xb05: 0x15f1, + 0xb06: 0x1621, 0xb07: 0x1651, 0xb08: 0x1501, 0xb09: 0x1531, 0xb0a: 0x1561, 0xb0b: 0x1591, + 0xb0c: 0x15c1, 0xb0d: 0x15f1, 0xb0e: 0x1621, 0xb0f: 0x1651, 0xb10: 0x1681, 0xb11: 0x16b1, + 0xb12: 0x16e1, 0xb13: 0x1711, 0xb14: 0x1741, 0xb15: 0x1771, 0xb16: 0x17a1, 0xb17: 0x17d1, + 0xb18: 0x1681, 0xb19: 0x16b1, 0xb1a: 0x16e1, 0xb1b: 0x1711, 0xb1c: 0x1741, 0xb1d: 0x1771, + 0xb1e: 0x17a1, 0xb1f: 0x17d1, 0xb20: 0x1801, 0xb21: 0x1831, 0xb22: 0x1861, 0xb23: 0x1891, + 0xb24: 0x18c1, 0xb25: 0x18f1, 0xb26: 0x1921, 0xb27: 0x1951, 0xb28: 0x1801, 0xb29: 0x1831, + 0xb2a: 0x1861, 0xb2b: 0x1891, 0xb2c: 0x18c1, 0xb2d: 0x18f1, 0xb2e: 0x1921, 0xb2f: 0x1951, + 0xb30: 0x0008, 0xb31: 0x0008, 0xb32: 0x1981, 0xb33: 0x19b1, 0xb34: 0x19d9, 0xb35: 0x0040, + 0xb36: 0x0008, 0xb37: 0x1a01, 0xb38: 0xe045, 0xb39: 0xe045, 0xb3a: 0x064d, 0xb3b: 0x1459, + 0xb3c: 0x19b1, 0xb3d: 0x0666, 0xb3e: 0x1a31, 0xb3f: 0x0686, + // Block 0x2d, offset 0xb40 + 0xb40: 0x06a6, 0xb41: 0x1a4a, 0xb42: 0x1a79, 0xb43: 0x1aa9, 0xb44: 0x1ad1, 0xb45: 0x0040, + 0xb46: 0x0008, 0xb47: 0x1af9, 0xb48: 0x06c5, 0xb49: 0x1471, 0xb4a: 0x06dd, 0xb4b: 0x1489, + 0xb4c: 0x1aa9, 0xb4d: 0x1b2a, 0xb4e: 0x1b5a, 0xb4f: 0x1b8a, 0xb50: 0x0008, 0xb51: 0x0008, + 0xb52: 0x0008, 0xb53: 0x1bb9, 0xb54: 0x0040, 0xb55: 0x0040, 0xb56: 0x0008, 0xb57: 0x0008, + 0xb58: 0xe045, 0xb59: 0xe045, 0xb5a: 0x06f5, 0xb5b: 0x14a1, 0xb5c: 0x0040, 0xb5d: 0x1bd2, + 0xb5e: 0x1c02, 0xb5f: 0x1c32, 0xb60: 0x0008, 0xb61: 0x0008, 0xb62: 0x0008, 0xb63: 0x1c61, + 0xb64: 0x0008, 0xb65: 0x0008, 0xb66: 0x0008, 0xb67: 0x0008, 0xb68: 0xe045, 0xb69: 0xe045, + 0xb6a: 0x070d, 0xb6b: 0x14d1, 0xb6c: 0xe04d, 0xb6d: 0x1c7a, 0xb6e: 0x03d2, 0xb6f: 0x1caa, + 0xb70: 0x0040, 0xb71: 0x0040, 0xb72: 0x1cb9, 0xb73: 0x1ce9, 0xb74: 0x1d11, 0xb75: 0x0040, + 0xb76: 0x0008, 0xb77: 0x1d39, 0xb78: 0x0725, 0xb79: 0x14b9, 0xb7a: 0x0515, 0xb7b: 0x14e9, + 0xb7c: 0x1ce9, 0xb7d: 0x073e, 0xb7e: 0x075e, 0xb7f: 0x0040, + // Block 0x2e, offset 0xb80 + 0xb80: 0x000a, 0xb81: 0x000a, 0xb82: 0x000a, 0xb83: 0x000a, 0xb84: 0x000a, 0xb85: 0x000a, + 0xb86: 0x000a, 0xb87: 0x000a, 0xb88: 0x000a, 0xb89: 0x000a, 0xb8a: 0x000a, 0xb8b: 0x03c0, + 0xb8c: 0x0003, 0xb8d: 0x0003, 0xb8e: 0x0340, 0xb8f: 0x0b40, 0xb90: 0x0018, 0xb91: 0xe00d, + 0xb92: 0x0018, 0xb93: 0x0018, 0xb94: 0x0018, 0xb95: 0x0018, 0xb96: 0x0018, 0xb97: 0x077e, + 0xb98: 0x0018, 0xb99: 0x0018, 0xb9a: 0x0018, 0xb9b: 0x0018, 0xb9c: 0x0018, 0xb9d: 0x0018, + 0xb9e: 0x0018, 0xb9f: 0x0018, 0xba0: 0x0018, 0xba1: 0x0018, 0xba2: 0x0018, 0xba3: 0x0018, + 0xba4: 0x0040, 0xba5: 0x0040, 0xba6: 0x0040, 0xba7: 0x0018, 0xba8: 0x0040, 0xba9: 0x0040, + 0xbaa: 0x0340, 0xbab: 0x0340, 0xbac: 0x0340, 0xbad: 0x0340, 0xbae: 0x0340, 0xbaf: 0x000a, + 0xbb0: 0x0018, 0xbb1: 0x0018, 0xbb2: 0x0018, 0xbb3: 0x1d69, 0xbb4: 0x1da1, 0xbb5: 0x0018, + 0xbb6: 0x1df1, 0xbb7: 0x1e29, 0xbb8: 0x0018, 0xbb9: 0x0018, 0xbba: 0x0018, 0xbbb: 0x0018, + 0xbbc: 0x1e7a, 0xbbd: 0x0018, 0xbbe: 0x079e, 0xbbf: 0x0018, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x0018, 0xbc1: 0x0018, 0xbc2: 0x0018, 0xbc3: 0x0018, 0xbc4: 0x0018, 0xbc5: 0x0018, + 0xbc6: 0x0018, 0xbc7: 0x1e92, 0xbc8: 0x1eaa, 0xbc9: 0x1ec2, 0xbca: 0x0018, 0xbcb: 0x0018, + 0xbcc: 0x0018, 0xbcd: 0x0018, 0xbce: 0x0018, 0xbcf: 0x0018, 0xbd0: 0x0018, 0xbd1: 0x0018, + 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x1ed9, + 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, + 0xbde: 0x0018, 0xbdf: 0x000a, 0xbe0: 0x03c0, 0xbe1: 0x0340, 0xbe2: 0x0340, 0xbe3: 0x0340, + 0xbe4: 0x03c0, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0040, 0xbe8: 0x0040, 0xbe9: 0x0040, + 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x0340, + 0xbf0: 0x1f41, 0xbf1: 0x0f41, 0xbf2: 0x0040, 0xbf3: 0x0040, 0xbf4: 0x1f51, 0xbf5: 0x1f61, + 0xbf6: 0x1f71, 0xbf7: 0x1f81, 0xbf8: 0x1f91, 0xbf9: 0x1fa1, 0xbfa: 0x1fb2, 0xbfb: 0x07bd, + 0xbfc: 0x1fc2, 0xbfd: 0x1fd2, 0xbfe: 0x1fe2, 0xbff: 0x0f71, + // Block 0x30, offset 0xc00 + 0xc00: 0x1f41, 0xc01: 0x00c9, 0xc02: 0x0069, 0xc03: 0x0079, 0xc04: 0x1f51, 0xc05: 0x1f61, + 0xc06: 0x1f71, 0xc07: 0x1f81, 0xc08: 0x1f91, 0xc09: 0x1fa1, 0xc0a: 0x1fb2, 0xc0b: 0x07d5, + 0xc0c: 0x1fc2, 0xc0d: 0x1fd2, 0xc0e: 0x1fe2, 0xc0f: 0x0040, 0xc10: 0x0039, 0xc11: 0x0f09, + 0xc12: 0x00d9, 0xc13: 0x0369, 0xc14: 0x0ff9, 0xc15: 0x0249, 0xc16: 0x0f51, 0xc17: 0x0359, + 0xc18: 0x0f61, 0xc19: 0x0f71, 0xc1a: 0x0f99, 0xc1b: 0x01d9, 0xc1c: 0x0fa9, 0xc1d: 0x0040, + 0xc1e: 0x0040, 0xc1f: 0x0040, 0xc20: 0x0018, 0xc21: 0x0018, 0xc22: 0x0018, 0xc23: 0x0018, + 0xc24: 0x0018, 0xc25: 0x0018, 0xc26: 0x0018, 0xc27: 0x0018, 0xc28: 0x1ff1, 0xc29: 0x0018, + 0xc2a: 0x0018, 0xc2b: 0x0018, 0xc2c: 0x0018, 0xc2d: 0x0018, 0xc2e: 0x0018, 0xc2f: 0x0018, + 0xc30: 0x0018, 0xc31: 0x0018, 0xc32: 0x0018, 0xc33: 0x0018, 0xc34: 0x0018, 0xc35: 0x0018, + 0xc36: 0x0018, 0xc37: 0x0018, 0xc38: 0x0018, 0xc39: 0x0018, 0xc3a: 0x0018, 0xc3b: 0x0018, + 0xc3c: 0x0018, 0xc3d: 0x0018, 0xc3e: 0x0018, 0xc3f: 0x0040, + // Block 0x31, offset 0xc40 + 0xc40: 0x07ee, 0xc41: 0x080e, 0xc42: 0x1159, 0xc43: 0x082d, 0xc44: 0x0018, 0xc45: 0x084e, + 0xc46: 0x086e, 0xc47: 0x1011, 0xc48: 0x0018, 0xc49: 0x088d, 0xc4a: 0x0f31, 0xc4b: 0x0249, + 0xc4c: 0x0249, 0xc4d: 0x0249, 0xc4e: 0x0249, 0xc4f: 0x2009, 0xc50: 0x0f41, 0xc51: 0x0f41, + 0xc52: 0x0359, 0xc53: 0x0359, 0xc54: 0x0018, 0xc55: 0x0f71, 0xc56: 0x2021, 0xc57: 0x0018, + 0xc58: 0x0018, 0xc59: 0x0f99, 0xc5a: 0x2039, 0xc5b: 0x0269, 0xc5c: 0x0269, 0xc5d: 0x0269, + 0xc5e: 0x0018, 0xc5f: 0x0018, 0xc60: 0x2049, 0xc61: 0x08ad, 0xc62: 0x2061, 0xc63: 0x0018, + 0xc64: 0x13d1, 0xc65: 0x0018, 0xc66: 0x2079, 0xc67: 0x0018, 0xc68: 0x13d1, 0xc69: 0x0018, + 0xc6a: 0x0f51, 0xc6b: 0x2091, 0xc6c: 0x0ee9, 0xc6d: 0x1159, 0xc6e: 0x0018, 0xc6f: 0x0f09, + 0xc70: 0x0f09, 0xc71: 0x1199, 0xc72: 0x0040, 0xc73: 0x0f61, 0xc74: 0x00d9, 0xc75: 0x20a9, + 0xc76: 0x20c1, 0xc77: 0x20d9, 0xc78: 0x20f1, 0xc79: 0x0f41, 0xc7a: 0x0018, 0xc7b: 0x08cd, + 0xc7c: 0x2109, 0xc7d: 0x10b1, 0xc7e: 0x10b1, 0xc7f: 0x2109, + // Block 0x32, offset 0xc80 + 0xc80: 0x08ed, 0xc81: 0x0018, 0xc82: 0x0018, 0xc83: 0x0018, 0xc84: 0x0018, 0xc85: 0x0ef9, + 0xc86: 0x0ef9, 0xc87: 0x0f09, 0xc88: 0x0f41, 0xc89: 0x0259, 0xc8a: 0x0018, 0xc8b: 0x0018, + 0xc8c: 0x0018, 0xc8d: 0x0018, 0xc8e: 0x0008, 0xc8f: 0x0018, 0xc90: 0x2121, 0xc91: 0x2151, + 0xc92: 0x2181, 0xc93: 0x21b9, 0xc94: 0x21e9, 0xc95: 0x2219, 0xc96: 0x2249, 0xc97: 0x2279, + 0xc98: 0x22a9, 0xc99: 0x22d9, 0xc9a: 0x2309, 0xc9b: 0x2339, 0xc9c: 0x2369, 0xc9d: 0x2399, + 0xc9e: 0x23c9, 0xc9f: 0x23f9, 0xca0: 0x0f41, 0xca1: 0x2421, 0xca2: 0x0905, 0xca3: 0x2439, + 0xca4: 0x1089, 0xca5: 0x2451, 0xca6: 0x0925, 0xca7: 0x2469, 0xca8: 0x2491, 0xca9: 0x0369, + 0xcaa: 0x24a9, 0xcab: 0x0945, 0xcac: 0x0359, 0xcad: 0x1159, 0xcae: 0x0ef9, 0xcaf: 0x0f61, + 0xcb0: 0x0f41, 0xcb1: 0x2421, 0xcb2: 0x0965, 0xcb3: 0x2439, 0xcb4: 0x1089, 0xcb5: 0x2451, + 0xcb6: 0x0985, 0xcb7: 0x2469, 0xcb8: 0x2491, 0xcb9: 0x0369, 0xcba: 0x24a9, 0xcbb: 0x09a5, + 0xcbc: 0x0359, 0xcbd: 0x1159, 0xcbe: 0x0ef9, 0xcbf: 0x0f61, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x0018, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0018, + 0xcc6: 0x0018, 0xcc7: 0x0018, 0xcc8: 0x0018, 0xcc9: 0x0018, 0xcca: 0x0018, 0xccb: 0x0040, + 0xccc: 0x0040, 0xccd: 0x0040, 0xcce: 0x0040, 0xccf: 0x0040, 0xcd0: 0x0040, 0xcd1: 0x0040, + 0xcd2: 0x0040, 0xcd3: 0x0040, 0xcd4: 0x0040, 0xcd5: 0x0040, 0xcd6: 0x0040, 0xcd7: 0x0040, + 0xcd8: 0x0040, 0xcd9: 0x0040, 0xcda: 0x0040, 0xcdb: 0x0040, 0xcdc: 0x0040, 0xcdd: 0x0040, + 0xcde: 0x0040, 0xcdf: 0x0040, 0xce0: 0x00c9, 0xce1: 0x0069, 0xce2: 0x0079, 0xce3: 0x1f51, + 0xce4: 0x1f61, 0xce5: 0x1f71, 0xce6: 0x1f81, 0xce7: 0x1f91, 0xce8: 0x1fa1, 0xce9: 0x2601, + 0xcea: 0x2619, 0xceb: 0x2631, 0xcec: 0x2649, 0xced: 0x2661, 0xcee: 0x2679, 0xcef: 0x2691, + 0xcf0: 0x26a9, 0xcf1: 0x26c1, 0xcf2: 0x26d9, 0xcf3: 0x26f1, 0xcf4: 0x0a06, 0xcf5: 0x0a26, + 0xcf6: 0x0a46, 0xcf7: 0x0a66, 0xcf8: 0x0a86, 0xcf9: 0x0aa6, 0xcfa: 0x0ac6, 0xcfb: 0x0ae6, + 0xcfc: 0x0b06, 0xcfd: 0x270a, 0xcfe: 0x2732, 0xcff: 0x275a, + // Block 0x34, offset 0xd00 + 0xd00: 0x2782, 0xd01: 0x27aa, 0xd02: 0x27d2, 0xd03: 0x27fa, 0xd04: 0x2822, 0xd05: 0x284a, + 0xd06: 0x2872, 0xd07: 0x289a, 0xd08: 0x0040, 0xd09: 0x0040, 0xd0a: 0x0040, 0xd0b: 0x0040, + 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, + 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, + 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0b26, 0xd1d: 0x0b46, + 0xd1e: 0x0b66, 0xd1f: 0x0b86, 0xd20: 0x0ba6, 0xd21: 0x0bc6, 0xd22: 0x0be6, 0xd23: 0x0c06, + 0xd24: 0x0c26, 0xd25: 0x0c46, 0xd26: 0x0c66, 0xd27: 0x0c86, 0xd28: 0x0ca6, 0xd29: 0x0cc6, + 0xd2a: 0x0ce6, 0xd2b: 0x0d06, 0xd2c: 0x0d26, 0xd2d: 0x0d46, 0xd2e: 0x0d66, 0xd2f: 0x0d86, + 0xd30: 0x0da6, 0xd31: 0x0dc6, 0xd32: 0x0de6, 0xd33: 0x0e06, 0xd34: 0x0e26, 0xd35: 0x0e46, + 0xd36: 0x0039, 0xd37: 0x0ee9, 0xd38: 0x1159, 0xd39: 0x0ef9, 0xd3a: 0x0f09, 0xd3b: 0x1199, + 0xd3c: 0x0f31, 0xd3d: 0x0249, 0xd3e: 0x0f41, 0xd3f: 0x0259, + // Block 0x35, offset 0xd40 + 0xd40: 0x0f51, 0xd41: 0x0359, 0xd42: 0x0f61, 0xd43: 0x0f71, 0xd44: 0x00d9, 0xd45: 0x0f99, + 0xd46: 0x2039, 0xd47: 0x0269, 0xd48: 0x01d9, 0xd49: 0x0fa9, 0xd4a: 0x0fb9, 0xd4b: 0x1089, + 0xd4c: 0x0279, 0xd4d: 0x0369, 0xd4e: 0x0289, 0xd4f: 0x13d1, 0xd50: 0x0039, 0xd51: 0x0ee9, + 0xd52: 0x1159, 0xd53: 0x0ef9, 0xd54: 0x0f09, 0xd55: 0x1199, 0xd56: 0x0f31, 0xd57: 0x0249, + 0xd58: 0x0f41, 0xd59: 0x0259, 0xd5a: 0x0f51, 0xd5b: 0x0359, 0xd5c: 0x0f61, 0xd5d: 0x0f71, + 0xd5e: 0x00d9, 0xd5f: 0x0f99, 0xd60: 0x2039, 0xd61: 0x0269, 0xd62: 0x01d9, 0xd63: 0x0fa9, + 0xd64: 0x0fb9, 0xd65: 0x1089, 0xd66: 0x0279, 0xd67: 0x0369, 0xd68: 0x0289, 0xd69: 0x13d1, + 0xd6a: 0x1f41, 0xd6b: 0x0018, 0xd6c: 0x0018, 0xd6d: 0x0018, 0xd6e: 0x0018, 0xd6f: 0x0018, + 0xd70: 0x0018, 0xd71: 0x0018, 0xd72: 0x0018, 0xd73: 0x0018, 0xd74: 0x0018, 0xd75: 0x0018, + 0xd76: 0x0018, 0xd77: 0x0018, 0xd78: 0x0018, 0xd79: 0x0018, 0xd7a: 0x0018, 0xd7b: 0x0018, + 0xd7c: 0x0018, 0xd7d: 0x0018, 0xd7e: 0x0018, 0xd7f: 0x0018, + // Block 0x36, offset 0xd80 + 0xd80: 0x0008, 0xd81: 0x0008, 0xd82: 0x0008, 0xd83: 0x0008, 0xd84: 0x0008, 0xd85: 0x0008, + 0xd86: 0x0008, 0xd87: 0x0008, 0xd88: 0x0008, 0xd89: 0x0008, 0xd8a: 0x0008, 0xd8b: 0x0008, + 0xd8c: 0x0008, 0xd8d: 0x0008, 0xd8e: 0x0008, 0xd8f: 0x0008, 0xd90: 0x0008, 0xd91: 0x0008, + 0xd92: 0x0008, 0xd93: 0x0008, 0xd94: 0x0008, 0xd95: 0x0008, 0xd96: 0x0008, 0xd97: 0x0008, + 0xd98: 0x0008, 0xd99: 0x0008, 0xd9a: 0x0008, 0xd9b: 0x0008, 0xd9c: 0x0008, 0xd9d: 0x0008, + 0xd9e: 0x0008, 0xd9f: 0x0040, 0xda0: 0xe00d, 0xda1: 0x0008, 0xda2: 0x2971, 0xda3: 0x0ebd, + 0xda4: 0x2989, 0xda5: 0x0008, 0xda6: 0x0008, 0xda7: 0xe07d, 0xda8: 0x0008, 0xda9: 0xe01d, + 0xdaa: 0x0008, 0xdab: 0xe03d, 0xdac: 0x0008, 0xdad: 0x0fe1, 0xdae: 0x1281, 0xdaf: 0x0fc9, + 0xdb0: 0x1141, 0xdb1: 0x0008, 0xdb2: 0xe00d, 0xdb3: 0x0008, 0xdb4: 0x0008, 0xdb5: 0xe01d, + 0xdb6: 0x0008, 0xdb7: 0x0008, 0xdb8: 0x0008, 0xdb9: 0x0008, 0xdba: 0x0008, 0xdbb: 0x0008, + 0xdbc: 0x0259, 0xdbd: 0x1089, 0xdbe: 0x29a1, 0xdbf: 0x29b9, + // Block 0x37, offset 0xdc0 + 0xdc0: 0xe00d, 0xdc1: 0x0008, 0xdc2: 0xe00d, 0xdc3: 0x0008, 0xdc4: 0xe00d, 0xdc5: 0x0008, + 0xdc6: 0xe00d, 0xdc7: 0x0008, 0xdc8: 0xe00d, 0xdc9: 0x0008, 0xdca: 0xe00d, 0xdcb: 0x0008, + 0xdcc: 0xe00d, 0xdcd: 0x0008, 0xdce: 0xe00d, 0xdcf: 0x0008, 0xdd0: 0xe00d, 0xdd1: 0x0008, + 0xdd2: 0xe00d, 0xdd3: 0x0008, 0xdd4: 0xe00d, 0xdd5: 0x0008, 0xdd6: 0xe00d, 0xdd7: 0x0008, + 0xdd8: 0xe00d, 0xdd9: 0x0008, 0xdda: 0xe00d, 0xddb: 0x0008, 0xddc: 0xe00d, 0xddd: 0x0008, + 0xdde: 0xe00d, 0xddf: 0x0008, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0xe00d, 0xde3: 0x0008, + 0xde4: 0x0008, 0xde5: 0x0018, 0xde6: 0x0018, 0xde7: 0x0018, 0xde8: 0x0018, 0xde9: 0x0018, + 0xdea: 0x0018, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0xe01d, 0xdee: 0x0008, 0xdef: 0x3308, + 0xdf0: 0x3308, 0xdf1: 0x3308, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0040, 0xdf5: 0x0040, + 0xdf6: 0x0040, 0xdf7: 0x0040, 0xdf8: 0x0040, 0xdf9: 0x0018, 0xdfa: 0x0018, 0xdfb: 0x0018, + 0xdfc: 0x0018, 0xdfd: 0x0018, 0xdfe: 0x0018, 0xdff: 0x0018, + // Block 0x38, offset 0xe00 + 0xe00: 0x26fd, 0xe01: 0x271d, 0xe02: 0x273d, 0xe03: 0x275d, 0xe04: 0x277d, 0xe05: 0x279d, + 0xe06: 0x27bd, 0xe07: 0x27dd, 0xe08: 0x27fd, 0xe09: 0x281d, 0xe0a: 0x283d, 0xe0b: 0x285d, + 0xe0c: 0x287d, 0xe0d: 0x289d, 0xe0e: 0x28bd, 0xe0f: 0x28dd, 0xe10: 0x28fd, 0xe11: 0x291d, + 0xe12: 0x293d, 0xe13: 0x295d, 0xe14: 0x297d, 0xe15: 0x299d, 0xe16: 0x0040, 0xe17: 0x0040, + 0xe18: 0x0040, 0xe19: 0x0040, 0xe1a: 0x0040, 0xe1b: 0x0040, 0xe1c: 0x0040, 0xe1d: 0x0040, + 0xe1e: 0x0040, 0xe1f: 0x0040, 0xe20: 0x0040, 0xe21: 0x0040, 0xe22: 0x0040, 0xe23: 0x0040, + 0xe24: 0x0040, 0xe25: 0x0040, 0xe26: 0x0040, 0xe27: 0x0040, 0xe28: 0x0040, 0xe29: 0x0040, + 0xe2a: 0x0040, 0xe2b: 0x0040, 0xe2c: 0x0040, 0xe2d: 0x0040, 0xe2e: 0x0040, 0xe2f: 0x0040, + 0xe30: 0x0040, 0xe31: 0x0040, 0xe32: 0x0040, 0xe33: 0x0040, 0xe34: 0x0040, 0xe35: 0x0040, + 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0040, 0xe3a: 0x0040, 0xe3b: 0x0040, + 0xe3c: 0x0040, 0xe3d: 0x0040, 0xe3e: 0x0040, 0xe3f: 0x0040, + // Block 0x39, offset 0xe40 + 0xe40: 0x000a, 0xe41: 0x0018, 0xe42: 0x29d1, 0xe43: 0x0018, 0xe44: 0x0018, 0xe45: 0x0008, + 0xe46: 0x0008, 0xe47: 0x0008, 0xe48: 0x0018, 0xe49: 0x0018, 0xe4a: 0x0018, 0xe4b: 0x0018, + 0xe4c: 0x0018, 0xe4d: 0x0018, 0xe4e: 0x0018, 0xe4f: 0x0018, 0xe50: 0x0018, 0xe51: 0x0018, + 0xe52: 0x0018, 0xe53: 0x0018, 0xe54: 0x0018, 0xe55: 0x0018, 0xe56: 0x0018, 0xe57: 0x0018, + 0xe58: 0x0018, 0xe59: 0x0018, 0xe5a: 0x0018, 0xe5b: 0x0018, 0xe5c: 0x0018, 0xe5d: 0x0018, + 0xe5e: 0x0018, 0xe5f: 0x0018, 0xe60: 0x0018, 0xe61: 0x0018, 0xe62: 0x0018, 0xe63: 0x0018, + 0xe64: 0x0018, 0xe65: 0x0018, 0xe66: 0x0018, 0xe67: 0x0018, 0xe68: 0x0018, 0xe69: 0x0018, + 0xe6a: 0x3308, 0xe6b: 0x3308, 0xe6c: 0x3308, 0xe6d: 0x3308, 0xe6e: 0x3018, 0xe6f: 0x3018, + 0xe70: 0x0018, 0xe71: 0x0018, 0xe72: 0x0018, 0xe73: 0x0018, 0xe74: 0x0018, 0xe75: 0x0018, + 0xe76: 0xe125, 0xe77: 0x0018, 0xe78: 0x29bd, 0xe79: 0x29dd, 0xe7a: 0x29fd, 0xe7b: 0x0018, + 0xe7c: 0x0008, 0xe7d: 0x0018, 0xe7e: 0x0018, 0xe7f: 0x0018, + // Block 0x3a, offset 0xe80 + 0xe80: 0x2b3d, 0xe81: 0x2b5d, 0xe82: 0x2b7d, 0xe83: 0x2b9d, 0xe84: 0x2bbd, 0xe85: 0x2bdd, + 0xe86: 0x2bdd, 0xe87: 0x2bdd, 0xe88: 0x2bfd, 0xe89: 0x2bfd, 0xe8a: 0x2bfd, 0xe8b: 0x2bfd, + 0xe8c: 0x2c1d, 0xe8d: 0x2c1d, 0xe8e: 0x2c1d, 0xe8f: 0x2c3d, 0xe90: 0x2c5d, 0xe91: 0x2c5d, + 0xe92: 0x2a7d, 0xe93: 0x2a7d, 0xe94: 0x2c5d, 0xe95: 0x2c5d, 0xe96: 0x2c7d, 0xe97: 0x2c7d, + 0xe98: 0x2c5d, 0xe99: 0x2c5d, 0xe9a: 0x2a7d, 0xe9b: 0x2a7d, 0xe9c: 0x2c5d, 0xe9d: 0x2c5d, + 0xe9e: 0x2c3d, 0xe9f: 0x2c3d, 0xea0: 0x2c9d, 0xea1: 0x2c9d, 0xea2: 0x2cbd, 0xea3: 0x2cbd, + 0xea4: 0x0040, 0xea5: 0x2cdd, 0xea6: 0x2cfd, 0xea7: 0x2d1d, 0xea8: 0x2d1d, 0xea9: 0x2d3d, + 0xeaa: 0x2d5d, 0xeab: 0x2d7d, 0xeac: 0x2d9d, 0xead: 0x2dbd, 0xeae: 0x2ddd, 0xeaf: 0x2dfd, + 0xeb0: 0x2e1d, 0xeb1: 0x2e3d, 0xeb2: 0x2e3d, 0xeb3: 0x2e5d, 0xeb4: 0x2e7d, 0xeb5: 0x2e7d, + 0xeb6: 0x2e9d, 0xeb7: 0x2ebd, 0xeb8: 0x2e5d, 0xeb9: 0x2edd, 0xeba: 0x2efd, 0xebb: 0x2edd, + 0xebc: 0x2e5d, 0xebd: 0x2f1d, 0xebe: 0x2f3d, 0xebf: 0x2f5d, + // Block 0x3b, offset 0xec0 + 0xec0: 0x2f7d, 0xec1: 0x2f9d, 0xec2: 0x2cfd, 0xec3: 0x2cdd, 0xec4: 0x2fbd, 0xec5: 0x2fdd, + 0xec6: 0x2ffd, 0xec7: 0x301d, 0xec8: 0x303d, 0xec9: 0x305d, 0xeca: 0x307d, 0xecb: 0x309d, + 0xecc: 0x30bd, 0xecd: 0x30dd, 0xece: 0x30fd, 0xecf: 0x0040, 0xed0: 0x0018, 0xed1: 0x0018, + 0xed2: 0x311d, 0xed3: 0x313d, 0xed4: 0x315d, 0xed5: 0x317d, 0xed6: 0x319d, 0xed7: 0x31bd, + 0xed8: 0x31dd, 0xed9: 0x31fd, 0xeda: 0x321d, 0xedb: 0x323d, 0xedc: 0x315d, 0xedd: 0x325d, + 0xede: 0x327d, 0xedf: 0x329d, 0xee0: 0x0008, 0xee1: 0x0008, 0xee2: 0x0008, 0xee3: 0x0008, + 0xee4: 0x0008, 0xee5: 0x0008, 0xee6: 0x0008, 0xee7: 0x0008, 0xee8: 0x0008, 0xee9: 0x0008, + 0xeea: 0x0008, 0xeeb: 0x0008, 0xeec: 0x0008, 0xeed: 0x0008, 0xeee: 0x0008, 0xeef: 0x0008, + 0xef0: 0x0008, 0xef1: 0x0008, 0xef2: 0x0008, 0xef3: 0x0008, 0xef4: 0x0008, 0xef5: 0x0008, + 0xef6: 0x0008, 0xef7: 0x0008, 0xef8: 0x0008, 0xef9: 0x0008, 0xefa: 0x0008, 0xefb: 0x0040, + 0xefc: 0x0040, 0xefd: 0x0040, 0xefe: 0x0040, 0xeff: 0x0040, + // Block 0x3c, offset 0xf00 + 0xf00: 0x36a2, 0xf01: 0x36d2, 0xf02: 0x3702, 0xf03: 0x3732, 0xf04: 0x32bd, 0xf05: 0x32dd, + 0xf06: 0x32fd, 0xf07: 0x331d, 0xf08: 0x0018, 0xf09: 0x0018, 0xf0a: 0x0018, 0xf0b: 0x0018, + 0xf0c: 0x0018, 0xf0d: 0x0018, 0xf0e: 0x0018, 0xf0f: 0x0018, 0xf10: 0x333d, 0xf11: 0x3761, + 0xf12: 0x3779, 0xf13: 0x3791, 0xf14: 0x37a9, 0xf15: 0x37c1, 0xf16: 0x37d9, 0xf17: 0x37f1, + 0xf18: 0x3809, 0xf19: 0x3821, 0xf1a: 0x3839, 0xf1b: 0x3851, 0xf1c: 0x3869, 0xf1d: 0x3881, + 0xf1e: 0x3899, 0xf1f: 0x38b1, 0xf20: 0x335d, 0xf21: 0x337d, 0xf22: 0x339d, 0xf23: 0x33bd, + 0xf24: 0x33dd, 0xf25: 0x33dd, 0xf26: 0x33fd, 0xf27: 0x341d, 0xf28: 0x343d, 0xf29: 0x345d, + 0xf2a: 0x347d, 0xf2b: 0x349d, 0xf2c: 0x34bd, 0xf2d: 0x34dd, 0xf2e: 0x34fd, 0xf2f: 0x351d, + 0xf30: 0x353d, 0xf31: 0x355d, 0xf32: 0x357d, 0xf33: 0x359d, 0xf34: 0x35bd, 0xf35: 0x35dd, + 0xf36: 0x35fd, 0xf37: 0x361d, 0xf38: 0x363d, 0xf39: 0x365d, 0xf3a: 0x367d, 0xf3b: 0x369d, + 0xf3c: 0x38c9, 0xf3d: 0x3901, 0xf3e: 0x36bd, 0xf3f: 0x0018, + // Block 0x3d, offset 0xf40 + 0xf40: 0x36dd, 0xf41: 0x36fd, 0xf42: 0x371d, 0xf43: 0x373d, 0xf44: 0x375d, 0xf45: 0x377d, + 0xf46: 0x379d, 0xf47: 0x37bd, 0xf48: 0x37dd, 0xf49: 0x37fd, 0xf4a: 0x381d, 0xf4b: 0x383d, + 0xf4c: 0x385d, 0xf4d: 0x387d, 0xf4e: 0x389d, 0xf4f: 0x38bd, 0xf50: 0x38dd, 0xf51: 0x38fd, + 0xf52: 0x391d, 0xf53: 0x393d, 0xf54: 0x395d, 0xf55: 0x397d, 0xf56: 0x399d, 0xf57: 0x39bd, + 0xf58: 0x39dd, 0xf59: 0x39fd, 0xf5a: 0x3a1d, 0xf5b: 0x3a3d, 0xf5c: 0x3a5d, 0xf5d: 0x3a7d, + 0xf5e: 0x3a9d, 0xf5f: 0x3abd, 0xf60: 0x3add, 0xf61: 0x3afd, 0xf62: 0x3b1d, 0xf63: 0x3b3d, + 0xf64: 0x3b5d, 0xf65: 0x3b7d, 0xf66: 0x127d, 0xf67: 0x3b9d, 0xf68: 0x3bbd, 0xf69: 0x3bdd, + 0xf6a: 0x3bfd, 0xf6b: 0x3c1d, 0xf6c: 0x3c3d, 0xf6d: 0x3c5d, 0xf6e: 0x239d, 0xf6f: 0x3c7d, + 0xf70: 0x3c9d, 0xf71: 0x3939, 0xf72: 0x3951, 0xf73: 0x3969, 0xf74: 0x3981, 0xf75: 0x3999, + 0xf76: 0x39b1, 0xf77: 0x39c9, 0xf78: 0x39e1, 0xf79: 0x39f9, 0xf7a: 0x3a11, 0xf7b: 0x3a29, + 0xf7c: 0x3a41, 0xf7d: 0x3a59, 0xf7e: 0x3a71, 0xf7f: 0x3a89, + // Block 0x3e, offset 0xf80 + 0xf80: 0x3aa1, 0xf81: 0x3ac9, 0xf82: 0x3af1, 0xf83: 0x3b19, 0xf84: 0x3b41, 0xf85: 0x3b69, + 0xf86: 0x3b91, 0xf87: 0x3bb9, 0xf88: 0x3be1, 0xf89: 0x3c09, 0xf8a: 0x3c39, 0xf8b: 0x3c69, + 0xf8c: 0x3c99, 0xf8d: 0x3cbd, 0xf8e: 0x3cb1, 0xf8f: 0x3cdd, 0xf90: 0x3cfd, 0xf91: 0x3d15, + 0xf92: 0x3d2d, 0xf93: 0x3d45, 0xf94: 0x3d5d, 0xf95: 0x3d5d, 0xf96: 0x3d45, 0xf97: 0x3d75, + 0xf98: 0x07bd, 0xf99: 0x3d8d, 0xf9a: 0x3da5, 0xf9b: 0x3dbd, 0xf9c: 0x3dd5, 0xf9d: 0x3ded, + 0xf9e: 0x3e05, 0xf9f: 0x3e1d, 0xfa0: 0x3e35, 0xfa1: 0x3e4d, 0xfa2: 0x3e65, 0xfa3: 0x3e7d, + 0xfa4: 0x3e95, 0xfa5: 0x3e95, 0xfa6: 0x3ead, 0xfa7: 0x3ead, 0xfa8: 0x3ec5, 0xfa9: 0x3ec5, + 0xfaa: 0x3edd, 0xfab: 0x3ef5, 0xfac: 0x3f0d, 0xfad: 0x3f25, 0xfae: 0x3f3d, 0xfaf: 0x3f3d, + 0xfb0: 0x3f55, 0xfb1: 0x3f55, 0xfb2: 0x3f55, 0xfb3: 0x3f6d, 0xfb4: 0x3f85, 0xfb5: 0x3f9d, + 0xfb6: 0x3fb5, 0xfb7: 0x3f9d, 0xfb8: 0x3fcd, 0xfb9: 0x3fe5, 0xfba: 0x3f6d, 0xfbb: 0x3ffd, + 0xfbc: 0x4015, 0xfbd: 0x4015, 0xfbe: 0x4015, 0xfbf: 0x0040, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x3cc9, 0xfc1: 0x3d31, 0xfc2: 0x3d99, 0xfc3: 0x3e01, 0xfc4: 0x3e51, 0xfc5: 0x3eb9, + 0xfc6: 0x3f09, 0xfc7: 0x3f59, 0xfc8: 0x3fd9, 0xfc9: 0x4041, 0xfca: 0x4091, 0xfcb: 0x40e1, + 0xfcc: 0x4131, 0xfcd: 0x4199, 0xfce: 0x4201, 0xfcf: 0x4251, 0xfd0: 0x42a1, 0xfd1: 0x42d9, + 0xfd2: 0x4329, 0xfd3: 0x4391, 0xfd4: 0x43f9, 0xfd5: 0x4431, 0xfd6: 0x44b1, 0xfd7: 0x4549, + 0xfd8: 0x45c9, 0xfd9: 0x4619, 0xfda: 0x4699, 0xfdb: 0x4719, 0xfdc: 0x4781, 0xfdd: 0x47d1, + 0xfde: 0x4821, 0xfdf: 0x4871, 0xfe0: 0x48d9, 0xfe1: 0x4959, 0xfe2: 0x49c1, 0xfe3: 0x4a11, + 0xfe4: 0x4a61, 0xfe5: 0x4ab1, 0xfe6: 0x4ae9, 0xfe7: 0x4b21, 0xfe8: 0x4b59, 0xfe9: 0x4b91, + 0xfea: 0x4be1, 0xfeb: 0x4c31, 0xfec: 0x4cb1, 0xfed: 0x4d01, 0xfee: 0x4d69, 0xfef: 0x4de9, + 0xff0: 0x4e39, 0xff1: 0x4e71, 0xff2: 0x4ea9, 0xff3: 0x4f29, 0xff4: 0x4f91, 0xff5: 0x5011, + 0xff6: 0x5061, 0xff7: 0x50e1, 0xff8: 0x5119, 0xff9: 0x5169, 0xffa: 0x51b9, 0xffb: 0x5209, + 0xffc: 0x5259, 0xffd: 0x52a9, 0xffe: 0x5311, 0xfff: 0x5361, + // Block 0x40, offset 0x1000 + 0x1000: 0x5399, 0x1001: 0x53e9, 0x1002: 0x5439, 0x1003: 0x5489, 0x1004: 0x54f1, 0x1005: 0x5541, + 0x1006: 0x5591, 0x1007: 0x55e1, 0x1008: 0x5661, 0x1009: 0x56c9, 0x100a: 0x5701, 0x100b: 0x5781, + 0x100c: 0x57b9, 0x100d: 0x5821, 0x100e: 0x5889, 0x100f: 0x58d9, 0x1010: 0x5929, 0x1011: 0x5979, + 0x1012: 0x59e1, 0x1013: 0x5a19, 0x1014: 0x5a69, 0x1015: 0x5ad1, 0x1016: 0x5b09, 0x1017: 0x5b89, + 0x1018: 0x5bd9, 0x1019: 0x5c01, 0x101a: 0x5c29, 0x101b: 0x5c51, 0x101c: 0x5c79, 0x101d: 0x5ca1, + 0x101e: 0x5cc9, 0x101f: 0x5cf1, 0x1020: 0x5d19, 0x1021: 0x5d41, 0x1022: 0x5d69, 0x1023: 0x5d99, + 0x1024: 0x5dc9, 0x1025: 0x5df9, 0x1026: 0x5e29, 0x1027: 0x5e59, 0x1028: 0x5e89, 0x1029: 0x5eb9, + 0x102a: 0x5ee9, 0x102b: 0x5f19, 0x102c: 0x5f49, 0x102d: 0x5f79, 0x102e: 0x5fa9, 0x102f: 0x5fd9, + 0x1030: 0x6009, 0x1031: 0x402d, 0x1032: 0x6039, 0x1033: 0x6051, 0x1034: 0x404d, 0x1035: 0x6069, + 0x1036: 0x6081, 0x1037: 0x6099, 0x1038: 0x406d, 0x1039: 0x406d, 0x103a: 0x60b1, 0x103b: 0x60c9, + 0x103c: 0x6101, 0x103d: 0x6139, 0x103e: 0x6171, 0x103f: 0x61a9, + // Block 0x41, offset 0x1040 + 0x1040: 0x6211, 0x1041: 0x6229, 0x1042: 0x408d, 0x1043: 0x6241, 0x1044: 0x6259, 0x1045: 0x6271, + 0x1046: 0x6289, 0x1047: 0x62a1, 0x1048: 0x40ad, 0x1049: 0x62b9, 0x104a: 0x62e1, 0x104b: 0x62f9, + 0x104c: 0x40cd, 0x104d: 0x40cd, 0x104e: 0x6311, 0x104f: 0x6329, 0x1050: 0x6341, 0x1051: 0x40ed, + 0x1052: 0x410d, 0x1053: 0x412d, 0x1054: 0x414d, 0x1055: 0x416d, 0x1056: 0x6359, 0x1057: 0x6371, + 0x1058: 0x6389, 0x1059: 0x63a1, 0x105a: 0x63b9, 0x105b: 0x418d, 0x105c: 0x63d1, 0x105d: 0x63e9, + 0x105e: 0x6401, 0x105f: 0x41ad, 0x1060: 0x41cd, 0x1061: 0x6419, 0x1062: 0x41ed, 0x1063: 0x420d, + 0x1064: 0x422d, 0x1065: 0x6431, 0x1066: 0x424d, 0x1067: 0x6449, 0x1068: 0x6479, 0x1069: 0x6211, + 0x106a: 0x426d, 0x106b: 0x428d, 0x106c: 0x42ad, 0x106d: 0x42cd, 0x106e: 0x64b1, 0x106f: 0x64f1, + 0x1070: 0x6539, 0x1071: 0x6551, 0x1072: 0x42ed, 0x1073: 0x6569, 0x1074: 0x6581, 0x1075: 0x6599, + 0x1076: 0x430d, 0x1077: 0x65b1, 0x1078: 0x65c9, 0x1079: 0x65b1, 0x107a: 0x65e1, 0x107b: 0x65f9, + 0x107c: 0x432d, 0x107d: 0x6611, 0x107e: 0x6629, 0x107f: 0x6611, + // Block 0x42, offset 0x1080 + 0x1080: 0x434d, 0x1081: 0x436d, 0x1082: 0x0040, 0x1083: 0x6641, 0x1084: 0x6659, 0x1085: 0x6671, + 0x1086: 0x6689, 0x1087: 0x0040, 0x1088: 0x66c1, 0x1089: 0x66d9, 0x108a: 0x66f1, 0x108b: 0x6709, + 0x108c: 0x6721, 0x108d: 0x6739, 0x108e: 0x6401, 0x108f: 0x6751, 0x1090: 0x6769, 0x1091: 0x6781, + 0x1092: 0x438d, 0x1093: 0x6799, 0x1094: 0x6289, 0x1095: 0x43ad, 0x1096: 0x43cd, 0x1097: 0x67b1, + 0x1098: 0x0040, 0x1099: 0x43ed, 0x109a: 0x67c9, 0x109b: 0x67e1, 0x109c: 0x67f9, 0x109d: 0x6811, + 0x109e: 0x6829, 0x109f: 0x6859, 0x10a0: 0x6889, 0x10a1: 0x68b1, 0x10a2: 0x68d9, 0x10a3: 0x6901, + 0x10a4: 0x6929, 0x10a5: 0x6951, 0x10a6: 0x6979, 0x10a7: 0x69a1, 0x10a8: 0x69c9, 0x10a9: 0x69f1, + 0x10aa: 0x6a21, 0x10ab: 0x6a51, 0x10ac: 0x6a81, 0x10ad: 0x6ab1, 0x10ae: 0x6ae1, 0x10af: 0x6b11, + 0x10b0: 0x6b41, 0x10b1: 0x6b71, 0x10b2: 0x6ba1, 0x10b3: 0x6bd1, 0x10b4: 0x6c01, 0x10b5: 0x6c31, + 0x10b6: 0x6c61, 0x10b7: 0x6c91, 0x10b8: 0x6cc1, 0x10b9: 0x6cf1, 0x10ba: 0x6d21, 0x10bb: 0x6d51, + 0x10bc: 0x6d81, 0x10bd: 0x6db1, 0x10be: 0x6de1, 0x10bf: 0x440d, + // Block 0x43, offset 0x10c0 + 0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008, + 0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008, + 0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008, + 0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008, + 0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0xe00d, 0x10dd: 0x0008, + 0x10de: 0xe00d, 0x10df: 0x0008, 0x10e0: 0xe00d, 0x10e1: 0x0008, 0x10e2: 0xe00d, 0x10e3: 0x0008, + 0x10e4: 0xe00d, 0x10e5: 0x0008, 0x10e6: 0xe00d, 0x10e7: 0x0008, 0x10e8: 0xe00d, 0x10e9: 0x0008, + 0x10ea: 0xe00d, 0x10eb: 0x0008, 0x10ec: 0xe00d, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x3308, + 0x10f0: 0x3318, 0x10f1: 0x3318, 0x10f2: 0x3318, 0x10f3: 0x0018, 0x10f4: 0x3308, 0x10f5: 0x3308, + 0x10f6: 0x3308, 0x10f7: 0x3308, 0x10f8: 0x3308, 0x10f9: 0x3308, 0x10fa: 0x3308, 0x10fb: 0x3308, + 0x10fc: 0x3308, 0x10fd: 0x3308, 0x10fe: 0x0018, 0x10ff: 0x0008, + // Block 0x44, offset 0x1100 + 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, + 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, + 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, + 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, + 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0x0ea1, 0x111d: 0x6e11, + 0x111e: 0x3308, 0x111f: 0x3308, 0x1120: 0x0008, 0x1121: 0x0008, 0x1122: 0x0008, 0x1123: 0x0008, + 0x1124: 0x0008, 0x1125: 0x0008, 0x1126: 0x0008, 0x1127: 0x0008, 0x1128: 0x0008, 0x1129: 0x0008, + 0x112a: 0x0008, 0x112b: 0x0008, 0x112c: 0x0008, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x0008, + 0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0x0008, 0x1133: 0x0008, 0x1134: 0x0008, 0x1135: 0x0008, + 0x1136: 0x0008, 0x1137: 0x0008, 0x1138: 0x0008, 0x1139: 0x0008, 0x113a: 0x0008, 0x113b: 0x0008, + 0x113c: 0x0008, 0x113d: 0x0008, 0x113e: 0x0008, 0x113f: 0x0008, + // Block 0x45, offset 0x1140 + 0x1140: 0x0018, 0x1141: 0x0018, 0x1142: 0x0018, 0x1143: 0x0018, 0x1144: 0x0018, 0x1145: 0x0018, + 0x1146: 0x0018, 0x1147: 0x0018, 0x1148: 0x0018, 0x1149: 0x0018, 0x114a: 0x0018, 0x114b: 0x0018, + 0x114c: 0x0018, 0x114d: 0x0018, 0x114e: 0x0018, 0x114f: 0x0018, 0x1150: 0x0018, 0x1151: 0x0018, + 0x1152: 0x0018, 0x1153: 0x0018, 0x1154: 0x0018, 0x1155: 0x0018, 0x1156: 0x0018, 0x1157: 0x0008, + 0x1158: 0x0008, 0x1159: 0x0008, 0x115a: 0x0008, 0x115b: 0x0008, 0x115c: 0x0008, 0x115d: 0x0008, + 0x115e: 0x0008, 0x115f: 0x0008, 0x1160: 0x0018, 0x1161: 0x0018, 0x1162: 0xe00d, 0x1163: 0x0008, + 0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008, + 0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008, + 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0xe00d, 0x1173: 0x0008, 0x1174: 0xe00d, 0x1175: 0x0008, + 0x1176: 0xe00d, 0x1177: 0x0008, 0x1178: 0xe00d, 0x1179: 0x0008, 0x117a: 0xe00d, 0x117b: 0x0008, + 0x117c: 0xe00d, 0x117d: 0x0008, 0x117e: 0xe00d, 0x117f: 0x0008, + // Block 0x46, offset 0x1180 + 0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008, + 0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0xe00d, 0x1189: 0x0008, 0x118a: 0xe00d, 0x118b: 0x0008, + 0x118c: 0xe00d, 0x118d: 0x0008, 0x118e: 0xe00d, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008, + 0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0xe00d, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008, + 0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008, + 0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008, + 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, + 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, + 0x11b0: 0xe0fd, 0x11b1: 0x0008, 0x11b2: 0x0008, 0x11b3: 0x0008, 0x11b4: 0x0008, 0x11b5: 0x0008, + 0x11b6: 0x0008, 0x11b7: 0x0008, 0x11b8: 0x0008, 0x11b9: 0xe01d, 0x11ba: 0x0008, 0x11bb: 0xe03d, + 0x11bc: 0x0008, 0x11bd: 0x442d, 0x11be: 0xe00d, 0x11bf: 0x0008, + // Block 0x47, offset 0x11c0 + 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, + 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0x0008, 0x11c9: 0x0018, 0x11ca: 0x0018, 0x11cb: 0xe03d, + 0x11cc: 0x0008, 0x11cd: 0x11d9, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, + 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, + 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, + 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, + 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, + 0x11ea: 0x6e29, 0x11eb: 0x1029, 0x11ec: 0x11c1, 0x11ed: 0x6e41, 0x11ee: 0x1221, 0x11ef: 0x0040, + 0x11f0: 0x6e59, 0x11f1: 0x6e71, 0x11f2: 0x1239, 0x11f3: 0x444d, 0x11f4: 0xe00d, 0x11f5: 0x0008, + 0x11f6: 0xe00d, 0x11f7: 0x0008, 0x11f8: 0x0040, 0x11f9: 0x0040, 0x11fa: 0x0040, 0x11fb: 0x0040, + 0x11fc: 0x0040, 0x11fd: 0x0040, 0x11fe: 0x0040, 0x11ff: 0x0040, + // Block 0x48, offset 0x1200 + 0x1200: 0x64d5, 0x1201: 0x64f5, 0x1202: 0x6515, 0x1203: 0x6535, 0x1204: 0x6555, 0x1205: 0x6575, + 0x1206: 0x6595, 0x1207: 0x65b5, 0x1208: 0x65d5, 0x1209: 0x65f5, 0x120a: 0x6615, 0x120b: 0x6635, + 0x120c: 0x6655, 0x120d: 0x6675, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0x6695, 0x1211: 0x0008, + 0x1212: 0x66b5, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x66d5, 0x1216: 0x66f5, 0x1217: 0x6715, + 0x1218: 0x6735, 0x1219: 0x6755, 0x121a: 0x6775, 0x121b: 0x6795, 0x121c: 0x67b5, 0x121d: 0x67d5, + 0x121e: 0x67f5, 0x121f: 0x0008, 0x1220: 0x6815, 0x1221: 0x0008, 0x1222: 0x6835, 0x1223: 0x0008, + 0x1224: 0x0008, 0x1225: 0x6855, 0x1226: 0x6875, 0x1227: 0x0008, 0x1228: 0x0008, 0x1229: 0x0008, + 0x122a: 0x6895, 0x122b: 0x68b5, 0x122c: 0x68d5, 0x122d: 0x68f5, 0x122e: 0x6915, 0x122f: 0x6935, + 0x1230: 0x6955, 0x1231: 0x6975, 0x1232: 0x6995, 0x1233: 0x69b5, 0x1234: 0x69d5, 0x1235: 0x69f5, + 0x1236: 0x6a15, 0x1237: 0x6a35, 0x1238: 0x6a55, 0x1239: 0x6a75, 0x123a: 0x6a95, 0x123b: 0x6ab5, + 0x123c: 0x6ad5, 0x123d: 0x6af5, 0x123e: 0x6b15, 0x123f: 0x6b35, + // Block 0x49, offset 0x1240 + 0x1240: 0x7a95, 0x1241: 0x7ab5, 0x1242: 0x7ad5, 0x1243: 0x7af5, 0x1244: 0x7b15, 0x1245: 0x7b35, + 0x1246: 0x7b55, 0x1247: 0x7b75, 0x1248: 0x7b95, 0x1249: 0x7bb5, 0x124a: 0x7bd5, 0x124b: 0x7bf5, + 0x124c: 0x7c15, 0x124d: 0x7c35, 0x124e: 0x7c55, 0x124f: 0x6ec9, 0x1250: 0x6ef1, 0x1251: 0x6f19, + 0x1252: 0x7c75, 0x1253: 0x7c95, 0x1254: 0x7cb5, 0x1255: 0x6f41, 0x1256: 0x6f69, 0x1257: 0x6f91, + 0x1258: 0x7cd5, 0x1259: 0x7cf5, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x0040, + 0x125e: 0x0040, 0x125f: 0x0040, 0x1260: 0x0040, 0x1261: 0x0040, 0x1262: 0x0040, 0x1263: 0x0040, + 0x1264: 0x0040, 0x1265: 0x0040, 0x1266: 0x0040, 0x1267: 0x0040, 0x1268: 0x0040, 0x1269: 0x0040, + 0x126a: 0x0040, 0x126b: 0x0040, 0x126c: 0x0040, 0x126d: 0x0040, 0x126e: 0x0040, 0x126f: 0x0040, + 0x1270: 0x0040, 0x1271: 0x0040, 0x1272: 0x0040, 0x1273: 0x0040, 0x1274: 0x0040, 0x1275: 0x0040, + 0x1276: 0x0040, 0x1277: 0x0040, 0x1278: 0x0040, 0x1279: 0x0040, 0x127a: 0x0040, 0x127b: 0x0040, + 0x127c: 0x0040, 0x127d: 0x0040, 0x127e: 0x0040, 0x127f: 0x0040, + // Block 0x4a, offset 0x1280 + 0x1280: 0x6fb9, 0x1281: 0x6fd1, 0x1282: 0x6fe9, 0x1283: 0x7d15, 0x1284: 0x7d35, 0x1285: 0x7001, + 0x1286: 0x7001, 0x1287: 0x0040, 0x1288: 0x0040, 0x1289: 0x0040, 0x128a: 0x0040, 0x128b: 0x0040, + 0x128c: 0x0040, 0x128d: 0x0040, 0x128e: 0x0040, 0x128f: 0x0040, 0x1290: 0x0040, 0x1291: 0x0040, + 0x1292: 0x0040, 0x1293: 0x7019, 0x1294: 0x7041, 0x1295: 0x7069, 0x1296: 0x7091, 0x1297: 0x70b9, + 0x1298: 0x0040, 0x1299: 0x0040, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x70e1, + 0x129e: 0x3308, 0x129f: 0x7109, 0x12a0: 0x7131, 0x12a1: 0x20a9, 0x12a2: 0x20f1, 0x12a3: 0x7149, + 0x12a4: 0x7161, 0x12a5: 0x7179, 0x12a6: 0x7191, 0x12a7: 0x71a9, 0x12a8: 0x71c1, 0x12a9: 0x1fb2, + 0x12aa: 0x71d9, 0x12ab: 0x7201, 0x12ac: 0x7229, 0x12ad: 0x7261, 0x12ae: 0x7299, 0x12af: 0x72c1, + 0x12b0: 0x72e9, 0x12b1: 0x7311, 0x12b2: 0x7339, 0x12b3: 0x7361, 0x12b4: 0x7389, 0x12b5: 0x73b1, + 0x12b6: 0x73d9, 0x12b7: 0x0040, 0x12b8: 0x7401, 0x12b9: 0x7429, 0x12ba: 0x7451, 0x12bb: 0x7479, + 0x12bc: 0x74a1, 0x12bd: 0x0040, 0x12be: 0x74c9, 0x12bf: 0x0040, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x74f1, 0x12c1: 0x7519, 0x12c2: 0x0040, 0x12c3: 0x7541, 0x12c4: 0x7569, 0x12c5: 0x0040, + 0x12c6: 0x7591, 0x12c7: 0x75b9, 0x12c8: 0x75e1, 0x12c9: 0x7609, 0x12ca: 0x7631, 0x12cb: 0x7659, + 0x12cc: 0x7681, 0x12cd: 0x76a9, 0x12ce: 0x76d1, 0x12cf: 0x76f9, 0x12d0: 0x7721, 0x12d1: 0x7721, + 0x12d2: 0x7739, 0x12d3: 0x7739, 0x12d4: 0x7739, 0x12d5: 0x7739, 0x12d6: 0x7751, 0x12d7: 0x7751, + 0x12d8: 0x7751, 0x12d9: 0x7751, 0x12da: 0x7769, 0x12db: 0x7769, 0x12dc: 0x7769, 0x12dd: 0x7769, + 0x12de: 0x7781, 0x12df: 0x7781, 0x12e0: 0x7781, 0x12e1: 0x7781, 0x12e2: 0x7799, 0x12e3: 0x7799, + 0x12e4: 0x7799, 0x12e5: 0x7799, 0x12e6: 0x77b1, 0x12e7: 0x77b1, 0x12e8: 0x77b1, 0x12e9: 0x77b1, + 0x12ea: 0x77c9, 0x12eb: 0x77c9, 0x12ec: 0x77c9, 0x12ed: 0x77c9, 0x12ee: 0x77e1, 0x12ef: 0x77e1, + 0x12f0: 0x77e1, 0x12f1: 0x77e1, 0x12f2: 0x77f9, 0x12f3: 0x77f9, 0x12f4: 0x77f9, 0x12f5: 0x77f9, + 0x12f6: 0x7811, 0x12f7: 0x7811, 0x12f8: 0x7811, 0x12f9: 0x7811, 0x12fa: 0x7829, 0x12fb: 0x7829, + 0x12fc: 0x7829, 0x12fd: 0x7829, 0x12fe: 0x7841, 0x12ff: 0x7841, + // Block 0x4c, offset 0x1300 + 0x1300: 0x7841, 0x1301: 0x7841, 0x1302: 0x7859, 0x1303: 0x7859, 0x1304: 0x7871, 0x1305: 0x7871, + 0x1306: 0x7889, 0x1307: 0x7889, 0x1308: 0x78a1, 0x1309: 0x78a1, 0x130a: 0x78b9, 0x130b: 0x78b9, + 0x130c: 0x78d1, 0x130d: 0x78d1, 0x130e: 0x78e9, 0x130f: 0x78e9, 0x1310: 0x78e9, 0x1311: 0x78e9, + 0x1312: 0x7901, 0x1313: 0x7901, 0x1314: 0x7901, 0x1315: 0x7901, 0x1316: 0x7919, 0x1317: 0x7919, + 0x1318: 0x7919, 0x1319: 0x7919, 0x131a: 0x7931, 0x131b: 0x7931, 0x131c: 0x7931, 0x131d: 0x7931, + 0x131e: 0x7949, 0x131f: 0x7949, 0x1320: 0x7961, 0x1321: 0x7961, 0x1322: 0x7961, 0x1323: 0x7961, + 0x1324: 0x7979, 0x1325: 0x7979, 0x1326: 0x7991, 0x1327: 0x7991, 0x1328: 0x7991, 0x1329: 0x7991, + 0x132a: 0x79a9, 0x132b: 0x79a9, 0x132c: 0x79a9, 0x132d: 0x79a9, 0x132e: 0x79c1, 0x132f: 0x79c1, + 0x1330: 0x79d9, 0x1331: 0x79d9, 0x1332: 0x0818, 0x1333: 0x0818, 0x1334: 0x0818, 0x1335: 0x0818, + 0x1336: 0x0818, 0x1337: 0x0818, 0x1338: 0x0818, 0x1339: 0x0818, 0x133a: 0x0818, 0x133b: 0x0818, + 0x133c: 0x0818, 0x133d: 0x0818, 0x133e: 0x0818, 0x133f: 0x0818, + // Block 0x4d, offset 0x1340 + 0x1340: 0x0818, 0x1341: 0x0818, 0x1342: 0x0040, 0x1343: 0x0040, 0x1344: 0x0040, 0x1345: 0x0040, + 0x1346: 0x0040, 0x1347: 0x0040, 0x1348: 0x0040, 0x1349: 0x0040, 0x134a: 0x0040, 0x134b: 0x0040, + 0x134c: 0x0040, 0x134d: 0x0040, 0x134e: 0x0040, 0x134f: 0x0040, 0x1350: 0x0040, 0x1351: 0x0040, + 0x1352: 0x0040, 0x1353: 0x79f1, 0x1354: 0x79f1, 0x1355: 0x79f1, 0x1356: 0x79f1, 0x1357: 0x7a09, + 0x1358: 0x7a09, 0x1359: 0x7a21, 0x135a: 0x7a21, 0x135b: 0x7a39, 0x135c: 0x7a39, 0x135d: 0x0479, + 0x135e: 0x7a51, 0x135f: 0x7a51, 0x1360: 0x7a69, 0x1361: 0x7a69, 0x1362: 0x7a81, 0x1363: 0x7a81, + 0x1364: 0x7a99, 0x1365: 0x7a99, 0x1366: 0x7a99, 0x1367: 0x7a99, 0x1368: 0x7ab1, 0x1369: 0x7ab1, + 0x136a: 0x7ac9, 0x136b: 0x7ac9, 0x136c: 0x7af1, 0x136d: 0x7af1, 0x136e: 0x7b19, 0x136f: 0x7b19, + 0x1370: 0x7b41, 0x1371: 0x7b41, 0x1372: 0x7b69, 0x1373: 0x7b69, 0x1374: 0x7b91, 0x1375: 0x7b91, + 0x1376: 0x7bb9, 0x1377: 0x7bb9, 0x1378: 0x7bb9, 0x1379: 0x7be1, 0x137a: 0x7be1, 0x137b: 0x7be1, + 0x137c: 0x7c09, 0x137d: 0x7c09, 0x137e: 0x7c09, 0x137f: 0x7c09, + // Block 0x4e, offset 0x1380 + 0x1380: 0x85f9, 0x1381: 0x8621, 0x1382: 0x8649, 0x1383: 0x8671, 0x1384: 0x8699, 0x1385: 0x86c1, + 0x1386: 0x86e9, 0x1387: 0x8711, 0x1388: 0x8739, 0x1389: 0x8761, 0x138a: 0x8789, 0x138b: 0x87b1, + 0x138c: 0x87d9, 0x138d: 0x8801, 0x138e: 0x8829, 0x138f: 0x8851, 0x1390: 0x8879, 0x1391: 0x88a1, + 0x1392: 0x88c9, 0x1393: 0x88f1, 0x1394: 0x8919, 0x1395: 0x8941, 0x1396: 0x8969, 0x1397: 0x8991, + 0x1398: 0x89b9, 0x1399: 0x89e1, 0x139a: 0x8a09, 0x139b: 0x8a31, 0x139c: 0x8a59, 0x139d: 0x8a81, + 0x139e: 0x8aaa, 0x139f: 0x8ada, 0x13a0: 0x8b0a, 0x13a1: 0x8b3a, 0x13a2: 0x8b6a, 0x13a3: 0x8b9a, + 0x13a4: 0x8bc9, 0x13a5: 0x8bf1, 0x13a6: 0x7c71, 0x13a7: 0x8c19, 0x13a8: 0x7be1, 0x13a9: 0x7c99, + 0x13aa: 0x8c41, 0x13ab: 0x8c69, 0x13ac: 0x7d39, 0x13ad: 0x8c91, 0x13ae: 0x7d61, 0x13af: 0x7d89, + 0x13b0: 0x8cb9, 0x13b1: 0x8ce1, 0x13b2: 0x7e29, 0x13b3: 0x8d09, 0x13b4: 0x7e51, 0x13b5: 0x7e79, + 0x13b6: 0x8d31, 0x13b7: 0x8d59, 0x13b8: 0x7ec9, 0x13b9: 0x8d81, 0x13ba: 0x7ef1, 0x13bb: 0x7f19, + 0x13bc: 0x83a1, 0x13bd: 0x83c9, 0x13be: 0x8441, 0x13bf: 0x8469, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x8491, 0x13c1: 0x8531, 0x13c2: 0x8559, 0x13c3: 0x8581, 0x13c4: 0x85a9, 0x13c5: 0x8649, + 0x13c6: 0x8671, 0x13c7: 0x8699, 0x13c8: 0x8da9, 0x13c9: 0x8739, 0x13ca: 0x8dd1, 0x13cb: 0x8df9, + 0x13cc: 0x8829, 0x13cd: 0x8e21, 0x13ce: 0x8851, 0x13cf: 0x8879, 0x13d0: 0x8a81, 0x13d1: 0x8e49, + 0x13d2: 0x8e71, 0x13d3: 0x89b9, 0x13d4: 0x8e99, 0x13d5: 0x89e1, 0x13d6: 0x8a09, 0x13d7: 0x7c21, + 0x13d8: 0x7c49, 0x13d9: 0x8ec1, 0x13da: 0x7c71, 0x13db: 0x8ee9, 0x13dc: 0x7cc1, 0x13dd: 0x7ce9, + 0x13de: 0x7d11, 0x13df: 0x7d39, 0x13e0: 0x8f11, 0x13e1: 0x7db1, 0x13e2: 0x7dd9, 0x13e3: 0x7e01, + 0x13e4: 0x7e29, 0x13e5: 0x8f39, 0x13e6: 0x7ec9, 0x13e7: 0x7f41, 0x13e8: 0x7f69, 0x13e9: 0x7f91, + 0x13ea: 0x7fb9, 0x13eb: 0x7fe1, 0x13ec: 0x8031, 0x13ed: 0x8059, 0x13ee: 0x8081, 0x13ef: 0x80a9, + 0x13f0: 0x80d1, 0x13f1: 0x80f9, 0x13f2: 0x8f61, 0x13f3: 0x8121, 0x13f4: 0x8149, 0x13f5: 0x8171, + 0x13f6: 0x8199, 0x13f7: 0x81c1, 0x13f8: 0x81e9, 0x13f9: 0x8239, 0x13fa: 0x8261, 0x13fb: 0x8289, + 0x13fc: 0x82b1, 0x13fd: 0x82d9, 0x13fe: 0x8301, 0x13ff: 0x8329, + // Block 0x50, offset 0x1400 + 0x1400: 0x8351, 0x1401: 0x8379, 0x1402: 0x83f1, 0x1403: 0x8419, 0x1404: 0x84b9, 0x1405: 0x84e1, + 0x1406: 0x8509, 0x1407: 0x8531, 0x1408: 0x8559, 0x1409: 0x85d1, 0x140a: 0x85f9, 0x140b: 0x8621, + 0x140c: 0x8649, 0x140d: 0x8f89, 0x140e: 0x86c1, 0x140f: 0x86e9, 0x1410: 0x8711, 0x1411: 0x8739, + 0x1412: 0x87b1, 0x1413: 0x87d9, 0x1414: 0x8801, 0x1415: 0x8829, 0x1416: 0x8fb1, 0x1417: 0x88a1, + 0x1418: 0x88c9, 0x1419: 0x8fd9, 0x141a: 0x8941, 0x141b: 0x8969, 0x141c: 0x8991, 0x141d: 0x89b9, + 0x141e: 0x9001, 0x141f: 0x7c71, 0x1420: 0x8ee9, 0x1421: 0x7d39, 0x1422: 0x8f11, 0x1423: 0x7e29, + 0x1424: 0x8f39, 0x1425: 0x7ec9, 0x1426: 0x9029, 0x1427: 0x80d1, 0x1428: 0x9051, 0x1429: 0x9079, + 0x142a: 0x90a1, 0x142b: 0x8531, 0x142c: 0x8559, 0x142d: 0x8649, 0x142e: 0x8829, 0x142f: 0x8fb1, + 0x1430: 0x89b9, 0x1431: 0x9001, 0x1432: 0x90c9, 0x1433: 0x9101, 0x1434: 0x9139, 0x1435: 0x9171, + 0x1436: 0x9199, 0x1437: 0x91c1, 0x1438: 0x91e9, 0x1439: 0x9211, 0x143a: 0x9239, 0x143b: 0x9261, + 0x143c: 0x9289, 0x143d: 0x92b1, 0x143e: 0x92d9, 0x143f: 0x9301, + // Block 0x51, offset 0x1440 + 0x1440: 0x9329, 0x1441: 0x9351, 0x1442: 0x9379, 0x1443: 0x93a1, 0x1444: 0x93c9, 0x1445: 0x93f1, + 0x1446: 0x9419, 0x1447: 0x9441, 0x1448: 0x9469, 0x1449: 0x9491, 0x144a: 0x94b9, 0x144b: 0x94e1, + 0x144c: 0x9079, 0x144d: 0x9509, 0x144e: 0x9531, 0x144f: 0x9559, 0x1450: 0x9581, 0x1451: 0x9171, + 0x1452: 0x9199, 0x1453: 0x91c1, 0x1454: 0x91e9, 0x1455: 0x9211, 0x1456: 0x9239, 0x1457: 0x9261, + 0x1458: 0x9289, 0x1459: 0x92b1, 0x145a: 0x92d9, 0x145b: 0x9301, 0x145c: 0x9329, 0x145d: 0x9351, + 0x145e: 0x9379, 0x145f: 0x93a1, 0x1460: 0x93c9, 0x1461: 0x93f1, 0x1462: 0x9419, 0x1463: 0x9441, + 0x1464: 0x9469, 0x1465: 0x9491, 0x1466: 0x94b9, 0x1467: 0x94e1, 0x1468: 0x9079, 0x1469: 0x9509, + 0x146a: 0x9531, 0x146b: 0x9559, 0x146c: 0x9581, 0x146d: 0x9491, 0x146e: 0x94b9, 0x146f: 0x94e1, + 0x1470: 0x9079, 0x1471: 0x9051, 0x1472: 0x90a1, 0x1473: 0x8211, 0x1474: 0x8059, 0x1475: 0x8081, + 0x1476: 0x80a9, 0x1477: 0x9491, 0x1478: 0x94b9, 0x1479: 0x94e1, 0x147a: 0x8211, 0x147b: 0x8239, + 0x147c: 0x95a9, 0x147d: 0x95a9, 0x147e: 0x0018, 0x147f: 0x0018, + // Block 0x52, offset 0x1480 + 0x1480: 0x0040, 0x1481: 0x0040, 0x1482: 0x0040, 0x1483: 0x0040, 0x1484: 0x0040, 0x1485: 0x0040, + 0x1486: 0x0040, 0x1487: 0x0040, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040, + 0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x95d1, 0x1491: 0x9609, + 0x1492: 0x9609, 0x1493: 0x9641, 0x1494: 0x9679, 0x1495: 0x96b1, 0x1496: 0x96e9, 0x1497: 0x9721, + 0x1498: 0x9759, 0x1499: 0x9759, 0x149a: 0x9791, 0x149b: 0x97c9, 0x149c: 0x9801, 0x149d: 0x9839, + 0x149e: 0x9871, 0x149f: 0x98a9, 0x14a0: 0x98a9, 0x14a1: 0x98e1, 0x14a2: 0x9919, 0x14a3: 0x9919, + 0x14a4: 0x9951, 0x14a5: 0x9951, 0x14a6: 0x9989, 0x14a7: 0x99c1, 0x14a8: 0x99c1, 0x14a9: 0x99f9, + 0x14aa: 0x9a31, 0x14ab: 0x9a31, 0x14ac: 0x9a69, 0x14ad: 0x9a69, 0x14ae: 0x9aa1, 0x14af: 0x9ad9, + 0x14b0: 0x9ad9, 0x14b1: 0x9b11, 0x14b2: 0x9b11, 0x14b3: 0x9b49, 0x14b4: 0x9b81, 0x14b5: 0x9bb9, + 0x14b6: 0x9bf1, 0x14b7: 0x9bf1, 0x14b8: 0x9c29, 0x14b9: 0x9c61, 0x14ba: 0x9c99, 0x14bb: 0x9cd1, + 0x14bc: 0x9d09, 0x14bd: 0x9d09, 0x14be: 0x9d41, 0x14bf: 0x9d79, + // Block 0x53, offset 0x14c0 + 0x14c0: 0xa949, 0x14c1: 0xa981, 0x14c2: 0xa9b9, 0x14c3: 0xa8a1, 0x14c4: 0x9bb9, 0x14c5: 0x9989, + 0x14c6: 0xa9f1, 0x14c7: 0xaa29, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, + 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x0040, 0x14d1: 0x0040, + 0x14d2: 0x0040, 0x14d3: 0x0040, 0x14d4: 0x0040, 0x14d5: 0x0040, 0x14d6: 0x0040, 0x14d7: 0x0040, + 0x14d8: 0x0040, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040, + 0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x0040, 0x14e1: 0x0040, 0x14e2: 0x0040, 0x14e3: 0x0040, + 0x14e4: 0x0040, 0x14e5: 0x0040, 0x14e6: 0x0040, 0x14e7: 0x0040, 0x14e8: 0x0040, 0x14e9: 0x0040, + 0x14ea: 0x0040, 0x14eb: 0x0040, 0x14ec: 0x0040, 0x14ed: 0x0040, 0x14ee: 0x0040, 0x14ef: 0x0040, + 0x14f0: 0xaa61, 0x14f1: 0xaa99, 0x14f2: 0xaad1, 0x14f3: 0xab19, 0x14f4: 0xab61, 0x14f5: 0xaba9, + 0x14f6: 0xabf1, 0x14f7: 0xac39, 0x14f8: 0xac81, 0x14f9: 0xacc9, 0x14fa: 0xad02, 0x14fb: 0xae12, + 0x14fc: 0xae91, 0x14fd: 0x0018, 0x14fe: 0x0040, 0x14ff: 0x0040, + // Block 0x54, offset 0x1500 + 0x1500: 0x33c0, 0x1501: 0x33c0, 0x1502: 0x33c0, 0x1503: 0x33c0, 0x1504: 0x33c0, 0x1505: 0x33c0, + 0x1506: 0x33c0, 0x1507: 0x33c0, 0x1508: 0x33c0, 0x1509: 0x33c0, 0x150a: 0x33c0, 0x150b: 0x33c0, + 0x150c: 0x33c0, 0x150d: 0x33c0, 0x150e: 0x33c0, 0x150f: 0x33c0, 0x1510: 0xaeda, 0x1511: 0x7d55, + 0x1512: 0x0040, 0x1513: 0xaeea, 0x1514: 0x03c2, 0x1515: 0xaefa, 0x1516: 0xaf0a, 0x1517: 0x7d75, + 0x1518: 0x7d95, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, + 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x3308, 0x1521: 0x3308, 0x1522: 0x3308, 0x1523: 0x3308, + 0x1524: 0x3308, 0x1525: 0x3308, 0x1526: 0x3308, 0x1527: 0x3308, 0x1528: 0x3308, 0x1529: 0x3308, + 0x152a: 0x3308, 0x152b: 0x3308, 0x152c: 0x3308, 0x152d: 0x3308, 0x152e: 0x3308, 0x152f: 0x3308, + 0x1530: 0x0040, 0x1531: 0x7db5, 0x1532: 0x7dd5, 0x1533: 0xaf1a, 0x1534: 0xaf1a, 0x1535: 0x1fd2, + 0x1536: 0x1fe2, 0x1537: 0xaf2a, 0x1538: 0xaf3a, 0x1539: 0x7df5, 0x153a: 0x7e15, 0x153b: 0x7e35, + 0x153c: 0x7df5, 0x153d: 0x7e55, 0x153e: 0x7e75, 0x153f: 0x7e55, + // Block 0x55, offset 0x1540 + 0x1540: 0x7e95, 0x1541: 0x7eb5, 0x1542: 0x7ed5, 0x1543: 0x7eb5, 0x1544: 0x7ef5, 0x1545: 0x0018, + 0x1546: 0x0018, 0x1547: 0xaf4a, 0x1548: 0xaf5a, 0x1549: 0x7f16, 0x154a: 0x7f36, 0x154b: 0x7f56, + 0x154c: 0x7f76, 0x154d: 0xaf1a, 0x154e: 0xaf1a, 0x154f: 0xaf1a, 0x1550: 0xaeda, 0x1551: 0x7f95, + 0x1552: 0x0040, 0x1553: 0x0040, 0x1554: 0x03c2, 0x1555: 0xaeea, 0x1556: 0xaf0a, 0x1557: 0xaefa, + 0x1558: 0x7fb5, 0x1559: 0x1fd2, 0x155a: 0x1fe2, 0x155b: 0xaf2a, 0x155c: 0xaf3a, 0x155d: 0x7e95, + 0x155e: 0x7ef5, 0x155f: 0xaf6a, 0x1560: 0xaf7a, 0x1561: 0xaf8a, 0x1562: 0x1fb2, 0x1563: 0xaf99, + 0x1564: 0xafaa, 0x1565: 0xafba, 0x1566: 0x1fc2, 0x1567: 0x0040, 0x1568: 0xafca, 0x1569: 0xafda, + 0x156a: 0xafea, 0x156b: 0xaffa, 0x156c: 0x0040, 0x156d: 0x0040, 0x156e: 0x0040, 0x156f: 0x0040, + 0x1570: 0x7fd6, 0x1571: 0xb009, 0x1572: 0x7ff6, 0x1573: 0x0808, 0x1574: 0x8016, 0x1575: 0x0040, + 0x1576: 0x8036, 0x1577: 0xb031, 0x1578: 0x8056, 0x1579: 0xb059, 0x157a: 0x8076, 0x157b: 0xb081, + 0x157c: 0x8096, 0x157d: 0xb0a9, 0x157e: 0x80b6, 0x157f: 0xb0d1, + // Block 0x56, offset 0x1580 + 0x1580: 0xb0f9, 0x1581: 0xb111, 0x1582: 0xb111, 0x1583: 0xb129, 0x1584: 0xb129, 0x1585: 0xb141, + 0x1586: 0xb141, 0x1587: 0xb159, 0x1588: 0xb159, 0x1589: 0xb171, 0x158a: 0xb171, 0x158b: 0xb171, + 0x158c: 0xb171, 0x158d: 0xb189, 0x158e: 0xb189, 0x158f: 0xb1a1, 0x1590: 0xb1a1, 0x1591: 0xb1a1, + 0x1592: 0xb1a1, 0x1593: 0xb1b9, 0x1594: 0xb1b9, 0x1595: 0xb1d1, 0x1596: 0xb1d1, 0x1597: 0xb1d1, + 0x1598: 0xb1d1, 0x1599: 0xb1e9, 0x159a: 0xb1e9, 0x159b: 0xb1e9, 0x159c: 0xb1e9, 0x159d: 0xb201, + 0x159e: 0xb201, 0x159f: 0xb201, 0x15a0: 0xb201, 0x15a1: 0xb219, 0x15a2: 0xb219, 0x15a3: 0xb219, + 0x15a4: 0xb219, 0x15a5: 0xb231, 0x15a6: 0xb231, 0x15a7: 0xb231, 0x15a8: 0xb231, 0x15a9: 0xb249, + 0x15aa: 0xb249, 0x15ab: 0xb261, 0x15ac: 0xb261, 0x15ad: 0xb279, 0x15ae: 0xb279, 0x15af: 0xb291, + 0x15b0: 0xb291, 0x15b1: 0xb2a9, 0x15b2: 0xb2a9, 0x15b3: 0xb2a9, 0x15b4: 0xb2a9, 0x15b5: 0xb2c1, + 0x15b6: 0xb2c1, 0x15b7: 0xb2c1, 0x15b8: 0xb2c1, 0x15b9: 0xb2d9, 0x15ba: 0xb2d9, 0x15bb: 0xb2d9, + 0x15bc: 0xb2d9, 0x15bd: 0xb2f1, 0x15be: 0xb2f1, 0x15bf: 0xb2f1, + // Block 0x57, offset 0x15c0 + 0x15c0: 0xb2f1, 0x15c1: 0xb309, 0x15c2: 0xb309, 0x15c3: 0xb309, 0x15c4: 0xb309, 0x15c5: 0xb321, + 0x15c6: 0xb321, 0x15c7: 0xb321, 0x15c8: 0xb321, 0x15c9: 0xb339, 0x15ca: 0xb339, 0x15cb: 0xb339, + 0x15cc: 0xb339, 0x15cd: 0xb351, 0x15ce: 0xb351, 0x15cf: 0xb351, 0x15d0: 0xb351, 0x15d1: 0xb369, + 0x15d2: 0xb369, 0x15d3: 0xb369, 0x15d4: 0xb369, 0x15d5: 0xb381, 0x15d6: 0xb381, 0x15d7: 0xb381, + 0x15d8: 0xb381, 0x15d9: 0xb399, 0x15da: 0xb399, 0x15db: 0xb399, 0x15dc: 0xb399, 0x15dd: 0xb3b1, + 0x15de: 0xb3b1, 0x15df: 0xb3b1, 0x15e0: 0xb3b1, 0x15e1: 0xb3c9, 0x15e2: 0xb3c9, 0x15e3: 0xb3c9, + 0x15e4: 0xb3c9, 0x15e5: 0xb3e1, 0x15e6: 0xb3e1, 0x15e7: 0xb3e1, 0x15e8: 0xb3e1, 0x15e9: 0xb3f9, + 0x15ea: 0xb3f9, 0x15eb: 0xb3f9, 0x15ec: 0xb3f9, 0x15ed: 0xb411, 0x15ee: 0xb411, 0x15ef: 0x7ab1, + 0x15f0: 0x7ab1, 0x15f1: 0xb429, 0x15f2: 0xb429, 0x15f3: 0xb429, 0x15f4: 0xb429, 0x15f5: 0xb441, + 0x15f6: 0xb441, 0x15f7: 0xb469, 0x15f8: 0xb469, 0x15f9: 0xb491, 0x15fa: 0xb491, 0x15fb: 0xb4b9, + 0x15fc: 0xb4b9, 0x15fd: 0x0040, 0x15fe: 0x0040, 0x15ff: 0x03c0, + // Block 0x58, offset 0x1600 + 0x1600: 0x0040, 0x1601: 0xaefa, 0x1602: 0xb4e2, 0x1603: 0xaf6a, 0x1604: 0xafda, 0x1605: 0xafea, + 0x1606: 0xaf7a, 0x1607: 0xb4f2, 0x1608: 0x1fd2, 0x1609: 0x1fe2, 0x160a: 0xaf8a, 0x160b: 0x1fb2, + 0x160c: 0xaeda, 0x160d: 0xaf99, 0x160e: 0x29d1, 0x160f: 0xb502, 0x1610: 0x1f41, 0x1611: 0x00c9, + 0x1612: 0x0069, 0x1613: 0x0079, 0x1614: 0x1f51, 0x1615: 0x1f61, 0x1616: 0x1f71, 0x1617: 0x1f81, + 0x1618: 0x1f91, 0x1619: 0x1fa1, 0x161a: 0xaeea, 0x161b: 0x03c2, 0x161c: 0xafaa, 0x161d: 0x1fc2, + 0x161e: 0xafba, 0x161f: 0xaf0a, 0x1620: 0xaffa, 0x1621: 0x0039, 0x1622: 0x0ee9, 0x1623: 0x1159, + 0x1624: 0x0ef9, 0x1625: 0x0f09, 0x1626: 0x1199, 0x1627: 0x0f31, 0x1628: 0x0249, 0x1629: 0x0f41, + 0x162a: 0x0259, 0x162b: 0x0f51, 0x162c: 0x0359, 0x162d: 0x0f61, 0x162e: 0x0f71, 0x162f: 0x00d9, + 0x1630: 0x0f99, 0x1631: 0x2039, 0x1632: 0x0269, 0x1633: 0x01d9, 0x1634: 0x0fa9, 0x1635: 0x0fb9, + 0x1636: 0x1089, 0x1637: 0x0279, 0x1638: 0x0369, 0x1639: 0x0289, 0x163a: 0x13d1, 0x163b: 0xaf4a, + 0x163c: 0xafca, 0x163d: 0xaf5a, 0x163e: 0xb512, 0x163f: 0xaf1a, + // Block 0x59, offset 0x1640 + 0x1640: 0x1caa, 0x1641: 0x0039, 0x1642: 0x0ee9, 0x1643: 0x1159, 0x1644: 0x0ef9, 0x1645: 0x0f09, + 0x1646: 0x1199, 0x1647: 0x0f31, 0x1648: 0x0249, 0x1649: 0x0f41, 0x164a: 0x0259, 0x164b: 0x0f51, + 0x164c: 0x0359, 0x164d: 0x0f61, 0x164e: 0x0f71, 0x164f: 0x00d9, 0x1650: 0x0f99, 0x1651: 0x2039, + 0x1652: 0x0269, 0x1653: 0x01d9, 0x1654: 0x0fa9, 0x1655: 0x0fb9, 0x1656: 0x1089, 0x1657: 0x0279, + 0x1658: 0x0369, 0x1659: 0x0289, 0x165a: 0x13d1, 0x165b: 0xaf2a, 0x165c: 0xb522, 0x165d: 0xaf3a, + 0x165e: 0xb532, 0x165f: 0x80d5, 0x1660: 0x80f5, 0x1661: 0x29d1, 0x1662: 0x8115, 0x1663: 0x8115, + 0x1664: 0x8135, 0x1665: 0x8155, 0x1666: 0x8175, 0x1667: 0x8195, 0x1668: 0x81b5, 0x1669: 0x81d5, + 0x166a: 0x81f5, 0x166b: 0x8215, 0x166c: 0x8235, 0x166d: 0x8255, 0x166e: 0x8275, 0x166f: 0x8295, + 0x1670: 0x82b5, 0x1671: 0x82d5, 0x1672: 0x82f5, 0x1673: 0x8315, 0x1674: 0x8335, 0x1675: 0x8355, + 0x1676: 0x8375, 0x1677: 0x8395, 0x1678: 0x83b5, 0x1679: 0x83d5, 0x167a: 0x83f5, 0x167b: 0x8415, + 0x167c: 0x81b5, 0x167d: 0x8435, 0x167e: 0x8455, 0x167f: 0x8215, + // Block 0x5a, offset 0x1680 + 0x1680: 0x8475, 0x1681: 0x8495, 0x1682: 0x84b5, 0x1683: 0x84d5, 0x1684: 0x84f5, 0x1685: 0x8515, + 0x1686: 0x8535, 0x1687: 0x8555, 0x1688: 0x84d5, 0x1689: 0x8575, 0x168a: 0x84d5, 0x168b: 0x8595, + 0x168c: 0x8595, 0x168d: 0x85b5, 0x168e: 0x85b5, 0x168f: 0x85d5, 0x1690: 0x8515, 0x1691: 0x85f5, + 0x1692: 0x8615, 0x1693: 0x85f5, 0x1694: 0x8635, 0x1695: 0x8615, 0x1696: 0x8655, 0x1697: 0x8655, + 0x1698: 0x8675, 0x1699: 0x8675, 0x169a: 0x8695, 0x169b: 0x8695, 0x169c: 0x8615, 0x169d: 0x8115, + 0x169e: 0x86b5, 0x169f: 0x86d5, 0x16a0: 0x0040, 0x16a1: 0x86f5, 0x16a2: 0x8715, 0x16a3: 0x8735, + 0x16a4: 0x8755, 0x16a5: 0x8735, 0x16a6: 0x8775, 0x16a7: 0x8795, 0x16a8: 0x87b5, 0x16a9: 0x87b5, + 0x16aa: 0x87d5, 0x16ab: 0x87d5, 0x16ac: 0x87f5, 0x16ad: 0x87f5, 0x16ae: 0x87d5, 0x16af: 0x87d5, + 0x16b0: 0x8815, 0x16b1: 0x8835, 0x16b2: 0x8855, 0x16b3: 0x8875, 0x16b4: 0x8895, 0x16b5: 0x88b5, + 0x16b6: 0x88b5, 0x16b7: 0x88b5, 0x16b8: 0x88d5, 0x16b9: 0x88d5, 0x16ba: 0x88d5, 0x16bb: 0x88d5, + 0x16bc: 0x87b5, 0x16bd: 0x87b5, 0x16be: 0x87b5, 0x16bf: 0x0040, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x0040, 0x16c1: 0x0040, 0x16c2: 0x8715, 0x16c3: 0x86f5, 0x16c4: 0x88f5, 0x16c5: 0x86f5, + 0x16c6: 0x8715, 0x16c7: 0x86f5, 0x16c8: 0x0040, 0x16c9: 0x0040, 0x16ca: 0x8915, 0x16cb: 0x8715, + 0x16cc: 0x8935, 0x16cd: 0x88f5, 0x16ce: 0x8935, 0x16cf: 0x8715, 0x16d0: 0x0040, 0x16d1: 0x0040, + 0x16d2: 0x8955, 0x16d3: 0x8975, 0x16d4: 0x8875, 0x16d5: 0x8935, 0x16d6: 0x88f5, 0x16d7: 0x8935, + 0x16d8: 0x0040, 0x16d9: 0x0040, 0x16da: 0x8995, 0x16db: 0x89b5, 0x16dc: 0x8995, 0x16dd: 0x0040, + 0x16de: 0x0040, 0x16df: 0x0040, 0x16e0: 0xb541, 0x16e1: 0xb559, 0x16e2: 0xb571, 0x16e3: 0x89d6, + 0x16e4: 0xb589, 0x16e5: 0xb5a1, 0x16e6: 0x89f5, 0x16e7: 0x0040, 0x16e8: 0x8a15, 0x16e9: 0x8a35, + 0x16ea: 0x8a55, 0x16eb: 0x8a35, 0x16ec: 0x8a75, 0x16ed: 0x8a95, 0x16ee: 0x8ab5, 0x16ef: 0x0040, + 0x16f0: 0x0040, 0x16f1: 0x0040, 0x16f2: 0x0040, 0x16f3: 0x0040, 0x16f4: 0x0040, 0x16f5: 0x0040, + 0x16f6: 0x0040, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0340, 0x16fa: 0x0340, 0x16fb: 0x0340, + 0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040, + // Block 0x5c, offset 0x1700 + 0x1700: 0x0a08, 0x1701: 0x0a08, 0x1702: 0x0a08, 0x1703: 0x0a08, 0x1704: 0x0a08, 0x1705: 0x0c08, + 0x1706: 0x0808, 0x1707: 0x0c08, 0x1708: 0x0818, 0x1709: 0x0c08, 0x170a: 0x0c08, 0x170b: 0x0808, + 0x170c: 0x0808, 0x170d: 0x0908, 0x170e: 0x0c08, 0x170f: 0x0c08, 0x1710: 0x0c08, 0x1711: 0x0c08, + 0x1712: 0x0c08, 0x1713: 0x0a08, 0x1714: 0x0a08, 0x1715: 0x0a08, 0x1716: 0x0a08, 0x1717: 0x0908, + 0x1718: 0x0a08, 0x1719: 0x0a08, 0x171a: 0x0a08, 0x171b: 0x0a08, 0x171c: 0x0a08, 0x171d: 0x0c08, + 0x171e: 0x0a08, 0x171f: 0x0a08, 0x1720: 0x0a08, 0x1721: 0x0c08, 0x1722: 0x0808, 0x1723: 0x0808, + 0x1724: 0x0c08, 0x1725: 0x3308, 0x1726: 0x3308, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0040, + 0x172a: 0x0040, 0x172b: 0x0a18, 0x172c: 0x0a18, 0x172d: 0x0a18, 0x172e: 0x0a18, 0x172f: 0x0c18, + 0x1730: 0x0818, 0x1731: 0x0818, 0x1732: 0x0818, 0x1733: 0x0818, 0x1734: 0x0818, 0x1735: 0x0818, + 0x1736: 0x0818, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040, + 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, + // Block 0x5d, offset 0x1740 + 0x1740: 0x0a08, 0x1741: 0x0c08, 0x1742: 0x0a08, 0x1743: 0x0c08, 0x1744: 0x0c08, 0x1745: 0x0c08, + 0x1746: 0x0a08, 0x1747: 0x0a08, 0x1748: 0x0a08, 0x1749: 0x0c08, 0x174a: 0x0a08, 0x174b: 0x0a08, + 0x174c: 0x0c08, 0x174d: 0x0a08, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0a08, 0x1751: 0x0c08, + 0x1752: 0x0040, 0x1753: 0x0040, 0x1754: 0x0040, 0x1755: 0x0040, 0x1756: 0x0040, 0x1757: 0x0040, + 0x1758: 0x0040, 0x1759: 0x0818, 0x175a: 0x0818, 0x175b: 0x0818, 0x175c: 0x0818, 0x175d: 0x0040, + 0x175e: 0x0040, 0x175f: 0x0040, 0x1760: 0x0040, 0x1761: 0x0040, 0x1762: 0x0040, 0x1763: 0x0040, + 0x1764: 0x0040, 0x1765: 0x0040, 0x1766: 0x0040, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0c18, + 0x176a: 0x0c18, 0x176b: 0x0c18, 0x176c: 0x0c18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0818, + 0x1770: 0x0040, 0x1771: 0x0040, 0x1772: 0x0040, 0x1773: 0x0040, 0x1774: 0x0040, 0x1775: 0x0040, + 0x1776: 0x0040, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, + 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, + // Block 0x5e, offset 0x1780 + 0x1780: 0x3308, 0x1781: 0x3308, 0x1782: 0x3008, 0x1783: 0x3008, 0x1784: 0x0040, 0x1785: 0x0008, + 0x1786: 0x0008, 0x1787: 0x0008, 0x1788: 0x0008, 0x1789: 0x0008, 0x178a: 0x0008, 0x178b: 0x0008, + 0x178c: 0x0008, 0x178d: 0x0040, 0x178e: 0x0040, 0x178f: 0x0008, 0x1790: 0x0008, 0x1791: 0x0040, + 0x1792: 0x0040, 0x1793: 0x0008, 0x1794: 0x0008, 0x1795: 0x0008, 0x1796: 0x0008, 0x1797: 0x0008, + 0x1798: 0x0008, 0x1799: 0x0008, 0x179a: 0x0008, 0x179b: 0x0008, 0x179c: 0x0008, 0x179d: 0x0008, + 0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x0008, 0x17a3: 0x0008, + 0x17a4: 0x0008, 0x17a5: 0x0008, 0x17a6: 0x0008, 0x17a7: 0x0008, 0x17a8: 0x0008, 0x17a9: 0x0040, + 0x17aa: 0x0008, 0x17ab: 0x0008, 0x17ac: 0x0008, 0x17ad: 0x0008, 0x17ae: 0x0008, 0x17af: 0x0008, + 0x17b0: 0x0008, 0x17b1: 0x0040, 0x17b2: 0x0008, 0x17b3: 0x0008, 0x17b4: 0x0040, 0x17b5: 0x0008, + 0x17b6: 0x0008, 0x17b7: 0x0008, 0x17b8: 0x0008, 0x17b9: 0x0008, 0x17ba: 0x0040, 0x17bb: 0x0040, + 0x17bc: 0x3308, 0x17bd: 0x0008, 0x17be: 0x3008, 0x17bf: 0x3008, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x3308, 0x17c1: 0x3008, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x3008, 0x17c5: 0x0040, + 0x17c6: 0x0040, 0x17c7: 0x3008, 0x17c8: 0x3008, 0x17c9: 0x0040, 0x17ca: 0x0040, 0x17cb: 0x3008, + 0x17cc: 0x3008, 0x17cd: 0x3808, 0x17ce: 0x0040, 0x17cf: 0x0040, 0x17d0: 0x0008, 0x17d1: 0x0040, + 0x17d2: 0x0040, 0x17d3: 0x0040, 0x17d4: 0x0040, 0x17d5: 0x0040, 0x17d6: 0x0040, 0x17d7: 0x3008, + 0x17d8: 0x0040, 0x17d9: 0x0040, 0x17da: 0x0040, 0x17db: 0x0040, 0x17dc: 0x0040, 0x17dd: 0x0008, + 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x3008, 0x17e3: 0x3008, + 0x17e4: 0x0040, 0x17e5: 0x0040, 0x17e6: 0x3308, 0x17e7: 0x3308, 0x17e8: 0x3308, 0x17e9: 0x3308, + 0x17ea: 0x3308, 0x17eb: 0x3308, 0x17ec: 0x3308, 0x17ed: 0x0040, 0x17ee: 0x0040, 0x17ef: 0x0040, + 0x17f0: 0x3308, 0x17f1: 0x3308, 0x17f2: 0x3308, 0x17f3: 0x3308, 0x17f4: 0x3308, 0x17f5: 0x0040, + 0x17f6: 0x0040, 0x17f7: 0x0040, 0x17f8: 0x0040, 0x17f9: 0x0040, 0x17fa: 0x0040, 0x17fb: 0x0040, + 0x17fc: 0x0040, 0x17fd: 0x0040, 0x17fe: 0x0040, 0x17ff: 0x0040, + // Block 0x60, offset 0x1800 + 0x1800: 0x0039, 0x1801: 0x0ee9, 0x1802: 0x1159, 0x1803: 0x0ef9, 0x1804: 0x0f09, 0x1805: 0x1199, + 0x1806: 0x0f31, 0x1807: 0x0249, 0x1808: 0x0f41, 0x1809: 0x0259, 0x180a: 0x0f51, 0x180b: 0x0359, + 0x180c: 0x0f61, 0x180d: 0x0f71, 0x180e: 0x00d9, 0x180f: 0x0f99, 0x1810: 0x2039, 0x1811: 0x0269, + 0x1812: 0x01d9, 0x1813: 0x0fa9, 0x1814: 0x0fb9, 0x1815: 0x1089, 0x1816: 0x0279, 0x1817: 0x0369, + 0x1818: 0x0289, 0x1819: 0x13d1, 0x181a: 0x0039, 0x181b: 0x0ee9, 0x181c: 0x1159, 0x181d: 0x0ef9, + 0x181e: 0x0f09, 0x181f: 0x1199, 0x1820: 0x0f31, 0x1821: 0x0249, 0x1822: 0x0f41, 0x1823: 0x0259, + 0x1824: 0x0f51, 0x1825: 0x0359, 0x1826: 0x0f61, 0x1827: 0x0f71, 0x1828: 0x00d9, 0x1829: 0x0f99, + 0x182a: 0x2039, 0x182b: 0x0269, 0x182c: 0x01d9, 0x182d: 0x0fa9, 0x182e: 0x0fb9, 0x182f: 0x1089, + 0x1830: 0x0279, 0x1831: 0x0369, 0x1832: 0x0289, 0x1833: 0x13d1, 0x1834: 0x0039, 0x1835: 0x0ee9, + 0x1836: 0x1159, 0x1837: 0x0ef9, 0x1838: 0x0f09, 0x1839: 0x1199, 0x183a: 0x0f31, 0x183b: 0x0249, + 0x183c: 0x0f41, 0x183d: 0x0259, 0x183e: 0x0f51, 0x183f: 0x0359, + // Block 0x61, offset 0x1840 + 0x1840: 0x0f61, 0x1841: 0x0f71, 0x1842: 0x00d9, 0x1843: 0x0f99, 0x1844: 0x2039, 0x1845: 0x0269, + 0x1846: 0x01d9, 0x1847: 0x0fa9, 0x1848: 0x0fb9, 0x1849: 0x1089, 0x184a: 0x0279, 0x184b: 0x0369, + 0x184c: 0x0289, 0x184d: 0x13d1, 0x184e: 0x0039, 0x184f: 0x0ee9, 0x1850: 0x1159, 0x1851: 0x0ef9, + 0x1852: 0x0f09, 0x1853: 0x1199, 0x1854: 0x0f31, 0x1855: 0x0040, 0x1856: 0x0f41, 0x1857: 0x0259, + 0x1858: 0x0f51, 0x1859: 0x0359, 0x185a: 0x0f61, 0x185b: 0x0f71, 0x185c: 0x00d9, 0x185d: 0x0f99, + 0x185e: 0x2039, 0x185f: 0x0269, 0x1860: 0x01d9, 0x1861: 0x0fa9, 0x1862: 0x0fb9, 0x1863: 0x1089, + 0x1864: 0x0279, 0x1865: 0x0369, 0x1866: 0x0289, 0x1867: 0x13d1, 0x1868: 0x0039, 0x1869: 0x0ee9, + 0x186a: 0x1159, 0x186b: 0x0ef9, 0x186c: 0x0f09, 0x186d: 0x1199, 0x186e: 0x0f31, 0x186f: 0x0249, + 0x1870: 0x0f41, 0x1871: 0x0259, 0x1872: 0x0f51, 0x1873: 0x0359, 0x1874: 0x0f61, 0x1875: 0x0f71, + 0x1876: 0x00d9, 0x1877: 0x0f99, 0x1878: 0x2039, 0x1879: 0x0269, 0x187a: 0x01d9, 0x187b: 0x0fa9, + 0x187c: 0x0fb9, 0x187d: 0x1089, 0x187e: 0x0279, 0x187f: 0x0369, + // Block 0x62, offset 0x1880 + 0x1880: 0x0289, 0x1881: 0x13d1, 0x1882: 0x0039, 0x1883: 0x0ee9, 0x1884: 0x1159, 0x1885: 0x0ef9, + 0x1886: 0x0f09, 0x1887: 0x1199, 0x1888: 0x0f31, 0x1889: 0x0249, 0x188a: 0x0f41, 0x188b: 0x0259, + 0x188c: 0x0f51, 0x188d: 0x0359, 0x188e: 0x0f61, 0x188f: 0x0f71, 0x1890: 0x00d9, 0x1891: 0x0f99, + 0x1892: 0x2039, 0x1893: 0x0269, 0x1894: 0x01d9, 0x1895: 0x0fa9, 0x1896: 0x0fb9, 0x1897: 0x1089, + 0x1898: 0x0279, 0x1899: 0x0369, 0x189a: 0x0289, 0x189b: 0x13d1, 0x189c: 0x0039, 0x189d: 0x0040, + 0x189e: 0x1159, 0x189f: 0x0ef9, 0x18a0: 0x0040, 0x18a1: 0x0040, 0x18a2: 0x0f31, 0x18a3: 0x0040, + 0x18a4: 0x0040, 0x18a5: 0x0259, 0x18a6: 0x0f51, 0x18a7: 0x0040, 0x18a8: 0x0040, 0x18a9: 0x0f71, + 0x18aa: 0x00d9, 0x18ab: 0x0f99, 0x18ac: 0x2039, 0x18ad: 0x0040, 0x18ae: 0x01d9, 0x18af: 0x0fa9, + 0x18b0: 0x0fb9, 0x18b1: 0x1089, 0x18b2: 0x0279, 0x18b3: 0x0369, 0x18b4: 0x0289, 0x18b5: 0x13d1, + 0x18b6: 0x0039, 0x18b7: 0x0ee9, 0x18b8: 0x1159, 0x18b9: 0x0ef9, 0x18ba: 0x0040, 0x18bb: 0x1199, + 0x18bc: 0x0040, 0x18bd: 0x0249, 0x18be: 0x0f41, 0x18bf: 0x0259, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0f51, 0x18c1: 0x0359, 0x18c2: 0x0f61, 0x18c3: 0x0f71, 0x18c4: 0x0040, 0x18c5: 0x0f99, + 0x18c6: 0x2039, 0x18c7: 0x0269, 0x18c8: 0x01d9, 0x18c9: 0x0fa9, 0x18ca: 0x0fb9, 0x18cb: 0x1089, + 0x18cc: 0x0279, 0x18cd: 0x0369, 0x18ce: 0x0289, 0x18cf: 0x13d1, 0x18d0: 0x0039, 0x18d1: 0x0ee9, + 0x18d2: 0x1159, 0x18d3: 0x0ef9, 0x18d4: 0x0f09, 0x18d5: 0x1199, 0x18d6: 0x0f31, 0x18d7: 0x0249, + 0x18d8: 0x0f41, 0x18d9: 0x0259, 0x18da: 0x0f51, 0x18db: 0x0359, 0x18dc: 0x0f61, 0x18dd: 0x0f71, + 0x18de: 0x00d9, 0x18df: 0x0f99, 0x18e0: 0x2039, 0x18e1: 0x0269, 0x18e2: 0x01d9, 0x18e3: 0x0fa9, + 0x18e4: 0x0fb9, 0x18e5: 0x1089, 0x18e6: 0x0279, 0x18e7: 0x0369, 0x18e8: 0x0289, 0x18e9: 0x13d1, + 0x18ea: 0x0039, 0x18eb: 0x0ee9, 0x18ec: 0x1159, 0x18ed: 0x0ef9, 0x18ee: 0x0f09, 0x18ef: 0x1199, + 0x18f0: 0x0f31, 0x18f1: 0x0249, 0x18f2: 0x0f41, 0x18f3: 0x0259, 0x18f4: 0x0f51, 0x18f5: 0x0359, + 0x18f6: 0x0f61, 0x18f7: 0x0f71, 0x18f8: 0x00d9, 0x18f9: 0x0f99, 0x18fa: 0x2039, 0x18fb: 0x0269, + 0x18fc: 0x01d9, 0x18fd: 0x0fa9, 0x18fe: 0x0fb9, 0x18ff: 0x1089, + // Block 0x64, offset 0x1900 + 0x1900: 0x0279, 0x1901: 0x0369, 0x1902: 0x0289, 0x1903: 0x13d1, 0x1904: 0x0039, 0x1905: 0x0ee9, + 0x1906: 0x0040, 0x1907: 0x0ef9, 0x1908: 0x0f09, 0x1909: 0x1199, 0x190a: 0x0f31, 0x190b: 0x0040, + 0x190c: 0x0040, 0x190d: 0x0259, 0x190e: 0x0f51, 0x190f: 0x0359, 0x1910: 0x0f61, 0x1911: 0x0f71, + 0x1912: 0x00d9, 0x1913: 0x0f99, 0x1914: 0x2039, 0x1915: 0x0040, 0x1916: 0x01d9, 0x1917: 0x0fa9, + 0x1918: 0x0fb9, 0x1919: 0x1089, 0x191a: 0x0279, 0x191b: 0x0369, 0x191c: 0x0289, 0x191d: 0x0040, + 0x191e: 0x0039, 0x191f: 0x0ee9, 0x1920: 0x1159, 0x1921: 0x0ef9, 0x1922: 0x0f09, 0x1923: 0x1199, + 0x1924: 0x0f31, 0x1925: 0x0249, 0x1926: 0x0f41, 0x1927: 0x0259, 0x1928: 0x0f51, 0x1929: 0x0359, + 0x192a: 0x0f61, 0x192b: 0x0f71, 0x192c: 0x00d9, 0x192d: 0x0f99, 0x192e: 0x2039, 0x192f: 0x0269, + 0x1930: 0x01d9, 0x1931: 0x0fa9, 0x1932: 0x0fb9, 0x1933: 0x1089, 0x1934: 0x0279, 0x1935: 0x0369, + 0x1936: 0x0289, 0x1937: 0x13d1, 0x1938: 0x0039, 0x1939: 0x0ee9, 0x193a: 0x0040, 0x193b: 0x0ef9, + 0x193c: 0x0f09, 0x193d: 0x1199, 0x193e: 0x0f31, 0x193f: 0x0040, + // Block 0x65, offset 0x1940 + 0x1940: 0x0f41, 0x1941: 0x0259, 0x1942: 0x0f51, 0x1943: 0x0359, 0x1944: 0x0f61, 0x1945: 0x0040, + 0x1946: 0x00d9, 0x1947: 0x0040, 0x1948: 0x0040, 0x1949: 0x0040, 0x194a: 0x01d9, 0x194b: 0x0fa9, + 0x194c: 0x0fb9, 0x194d: 0x1089, 0x194e: 0x0279, 0x194f: 0x0369, 0x1950: 0x0289, 0x1951: 0x0040, + 0x1952: 0x0039, 0x1953: 0x0ee9, 0x1954: 0x1159, 0x1955: 0x0ef9, 0x1956: 0x0f09, 0x1957: 0x1199, + 0x1958: 0x0f31, 0x1959: 0x0249, 0x195a: 0x0f41, 0x195b: 0x0259, 0x195c: 0x0f51, 0x195d: 0x0359, + 0x195e: 0x0f61, 0x195f: 0x0f71, 0x1960: 0x00d9, 0x1961: 0x0f99, 0x1962: 0x2039, 0x1963: 0x0269, + 0x1964: 0x01d9, 0x1965: 0x0fa9, 0x1966: 0x0fb9, 0x1967: 0x1089, 0x1968: 0x0279, 0x1969: 0x0369, + 0x196a: 0x0289, 0x196b: 0x13d1, 0x196c: 0x0039, 0x196d: 0x0ee9, 0x196e: 0x1159, 0x196f: 0x0ef9, + 0x1970: 0x0f09, 0x1971: 0x1199, 0x1972: 0x0f31, 0x1973: 0x0249, 0x1974: 0x0f41, 0x1975: 0x0259, + 0x1976: 0x0f51, 0x1977: 0x0359, 0x1978: 0x0f61, 0x1979: 0x0f71, 0x197a: 0x00d9, 0x197b: 0x0f99, + 0x197c: 0x2039, 0x197d: 0x0269, 0x197e: 0x01d9, 0x197f: 0x0fa9, + // Block 0x66, offset 0x1980 + 0x1980: 0x0fb9, 0x1981: 0x1089, 0x1982: 0x0279, 0x1983: 0x0369, 0x1984: 0x0289, 0x1985: 0x13d1, + 0x1986: 0x0039, 0x1987: 0x0ee9, 0x1988: 0x1159, 0x1989: 0x0ef9, 0x198a: 0x0f09, 0x198b: 0x1199, + 0x198c: 0x0f31, 0x198d: 0x0249, 0x198e: 0x0f41, 0x198f: 0x0259, 0x1990: 0x0f51, 0x1991: 0x0359, + 0x1992: 0x0f61, 0x1993: 0x0f71, 0x1994: 0x00d9, 0x1995: 0x0f99, 0x1996: 0x2039, 0x1997: 0x0269, + 0x1998: 0x01d9, 0x1999: 0x0fa9, 0x199a: 0x0fb9, 0x199b: 0x1089, 0x199c: 0x0279, 0x199d: 0x0369, + 0x199e: 0x0289, 0x199f: 0x13d1, 0x19a0: 0x0039, 0x19a1: 0x0ee9, 0x19a2: 0x1159, 0x19a3: 0x0ef9, + 0x19a4: 0x0f09, 0x19a5: 0x1199, 0x19a6: 0x0f31, 0x19a7: 0x0249, 0x19a8: 0x0f41, 0x19a9: 0x0259, + 0x19aa: 0x0f51, 0x19ab: 0x0359, 0x19ac: 0x0f61, 0x19ad: 0x0f71, 0x19ae: 0x00d9, 0x19af: 0x0f99, + 0x19b0: 0x2039, 0x19b1: 0x0269, 0x19b2: 0x01d9, 0x19b3: 0x0fa9, 0x19b4: 0x0fb9, 0x19b5: 0x1089, + 0x19b6: 0x0279, 0x19b7: 0x0369, 0x19b8: 0x0289, 0x19b9: 0x13d1, 0x19ba: 0x0039, 0x19bb: 0x0ee9, + 0x19bc: 0x1159, 0x19bd: 0x0ef9, 0x19be: 0x0f09, 0x19bf: 0x1199, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x0f31, 0x19c1: 0x0249, 0x19c2: 0x0f41, 0x19c3: 0x0259, 0x19c4: 0x0f51, 0x19c5: 0x0359, + 0x19c6: 0x0f61, 0x19c7: 0x0f71, 0x19c8: 0x00d9, 0x19c9: 0x0f99, 0x19ca: 0x2039, 0x19cb: 0x0269, + 0x19cc: 0x01d9, 0x19cd: 0x0fa9, 0x19ce: 0x0fb9, 0x19cf: 0x1089, 0x19d0: 0x0279, 0x19d1: 0x0369, + 0x19d2: 0x0289, 0x19d3: 0x13d1, 0x19d4: 0x0039, 0x19d5: 0x0ee9, 0x19d6: 0x1159, 0x19d7: 0x0ef9, + 0x19d8: 0x0f09, 0x19d9: 0x1199, 0x19da: 0x0f31, 0x19db: 0x0249, 0x19dc: 0x0f41, 0x19dd: 0x0259, + 0x19de: 0x0f51, 0x19df: 0x0359, 0x19e0: 0x0f61, 0x19e1: 0x0f71, 0x19e2: 0x00d9, 0x19e3: 0x0f99, + 0x19e4: 0x2039, 0x19e5: 0x0269, 0x19e6: 0x01d9, 0x19e7: 0x0fa9, 0x19e8: 0x0fb9, 0x19e9: 0x1089, + 0x19ea: 0x0279, 0x19eb: 0x0369, 0x19ec: 0x0289, 0x19ed: 0x13d1, 0x19ee: 0x0039, 0x19ef: 0x0ee9, + 0x19f0: 0x1159, 0x19f1: 0x0ef9, 0x19f2: 0x0f09, 0x19f3: 0x1199, 0x19f4: 0x0f31, 0x19f5: 0x0249, + 0x19f6: 0x0f41, 0x19f7: 0x0259, 0x19f8: 0x0f51, 0x19f9: 0x0359, 0x19fa: 0x0f61, 0x19fb: 0x0f71, + 0x19fc: 0x00d9, 0x19fd: 0x0f99, 0x19fe: 0x2039, 0x19ff: 0x0269, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x01d9, 0x1a01: 0x0fa9, 0x1a02: 0x0fb9, 0x1a03: 0x1089, 0x1a04: 0x0279, 0x1a05: 0x0369, + 0x1a06: 0x0289, 0x1a07: 0x13d1, 0x1a08: 0x0039, 0x1a09: 0x0ee9, 0x1a0a: 0x1159, 0x1a0b: 0x0ef9, + 0x1a0c: 0x0f09, 0x1a0d: 0x1199, 0x1a0e: 0x0f31, 0x1a0f: 0x0249, 0x1a10: 0x0f41, 0x1a11: 0x0259, + 0x1a12: 0x0f51, 0x1a13: 0x0359, 0x1a14: 0x0f61, 0x1a15: 0x0f71, 0x1a16: 0x00d9, 0x1a17: 0x0f99, + 0x1a18: 0x2039, 0x1a19: 0x0269, 0x1a1a: 0x01d9, 0x1a1b: 0x0fa9, 0x1a1c: 0x0fb9, 0x1a1d: 0x1089, + 0x1a1e: 0x0279, 0x1a1f: 0x0369, 0x1a20: 0x0289, 0x1a21: 0x13d1, 0x1a22: 0x0039, 0x1a23: 0x0ee9, + 0x1a24: 0x1159, 0x1a25: 0x0ef9, 0x1a26: 0x0f09, 0x1a27: 0x1199, 0x1a28: 0x0f31, 0x1a29: 0x0249, + 0x1a2a: 0x0f41, 0x1a2b: 0x0259, 0x1a2c: 0x0f51, 0x1a2d: 0x0359, 0x1a2e: 0x0f61, 0x1a2f: 0x0f71, + 0x1a30: 0x00d9, 0x1a31: 0x0f99, 0x1a32: 0x2039, 0x1a33: 0x0269, 0x1a34: 0x01d9, 0x1a35: 0x0fa9, + 0x1a36: 0x0fb9, 0x1a37: 0x1089, 0x1a38: 0x0279, 0x1a39: 0x0369, 0x1a3a: 0x0289, 0x1a3b: 0x13d1, + 0x1a3c: 0x0039, 0x1a3d: 0x0ee9, 0x1a3e: 0x1159, 0x1a3f: 0x0ef9, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x0f09, 0x1a41: 0x1199, 0x1a42: 0x0f31, 0x1a43: 0x0249, 0x1a44: 0x0f41, 0x1a45: 0x0259, + 0x1a46: 0x0f51, 0x1a47: 0x0359, 0x1a48: 0x0f61, 0x1a49: 0x0f71, 0x1a4a: 0x00d9, 0x1a4b: 0x0f99, + 0x1a4c: 0x2039, 0x1a4d: 0x0269, 0x1a4e: 0x01d9, 0x1a4f: 0x0fa9, 0x1a50: 0x0fb9, 0x1a51: 0x1089, + 0x1a52: 0x0279, 0x1a53: 0x0369, 0x1a54: 0x0289, 0x1a55: 0x13d1, 0x1a56: 0x0039, 0x1a57: 0x0ee9, + 0x1a58: 0x1159, 0x1a59: 0x0ef9, 0x1a5a: 0x0f09, 0x1a5b: 0x1199, 0x1a5c: 0x0f31, 0x1a5d: 0x0249, + 0x1a5e: 0x0f41, 0x1a5f: 0x0259, 0x1a60: 0x0f51, 0x1a61: 0x0359, 0x1a62: 0x0f61, 0x1a63: 0x0f71, + 0x1a64: 0x00d9, 0x1a65: 0x0f99, 0x1a66: 0x2039, 0x1a67: 0x0269, 0x1a68: 0x01d9, 0x1a69: 0x0fa9, + 0x1a6a: 0x0fb9, 0x1a6b: 0x1089, 0x1a6c: 0x0279, 0x1a6d: 0x0369, 0x1a6e: 0x0289, 0x1a6f: 0x13d1, + 0x1a70: 0x0039, 0x1a71: 0x0ee9, 0x1a72: 0x1159, 0x1a73: 0x0ef9, 0x1a74: 0x0f09, 0x1a75: 0x1199, + 0x1a76: 0x0f31, 0x1a77: 0x0249, 0x1a78: 0x0f41, 0x1a79: 0x0259, 0x1a7a: 0x0f51, 0x1a7b: 0x0359, + 0x1a7c: 0x0f61, 0x1a7d: 0x0f71, 0x1a7e: 0x00d9, 0x1a7f: 0x0f99, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x2039, 0x1a81: 0x0269, 0x1a82: 0x01d9, 0x1a83: 0x0fa9, 0x1a84: 0x0fb9, 0x1a85: 0x1089, + 0x1a86: 0x0279, 0x1a87: 0x0369, 0x1a88: 0x0289, 0x1a89: 0x13d1, 0x1a8a: 0x0039, 0x1a8b: 0x0ee9, + 0x1a8c: 0x1159, 0x1a8d: 0x0ef9, 0x1a8e: 0x0f09, 0x1a8f: 0x1199, 0x1a90: 0x0f31, 0x1a91: 0x0249, + 0x1a92: 0x0f41, 0x1a93: 0x0259, 0x1a94: 0x0f51, 0x1a95: 0x0359, 0x1a96: 0x0f61, 0x1a97: 0x0f71, + 0x1a98: 0x00d9, 0x1a99: 0x0f99, 0x1a9a: 0x2039, 0x1a9b: 0x0269, 0x1a9c: 0x01d9, 0x1a9d: 0x0fa9, + 0x1a9e: 0x0fb9, 0x1a9f: 0x1089, 0x1aa0: 0x0279, 0x1aa1: 0x0369, 0x1aa2: 0x0289, 0x1aa3: 0x13d1, + 0x1aa4: 0xba81, 0x1aa5: 0xba99, 0x1aa6: 0x0040, 0x1aa7: 0x0040, 0x1aa8: 0xbab1, 0x1aa9: 0x1099, + 0x1aaa: 0x10b1, 0x1aab: 0x10c9, 0x1aac: 0xbac9, 0x1aad: 0xbae1, 0x1aae: 0xbaf9, 0x1aaf: 0x1429, + 0x1ab0: 0x1a31, 0x1ab1: 0xbb11, 0x1ab2: 0xbb29, 0x1ab3: 0xbb41, 0x1ab4: 0xbb59, 0x1ab5: 0xbb71, + 0x1ab6: 0xbb89, 0x1ab7: 0x2109, 0x1ab8: 0x1111, 0x1ab9: 0x1429, 0x1aba: 0xbba1, 0x1abb: 0xbbb9, + 0x1abc: 0xbbd1, 0x1abd: 0x10e1, 0x1abe: 0x10f9, 0x1abf: 0xbbe9, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x2079, 0x1ac1: 0xbc01, 0x1ac2: 0xbab1, 0x1ac3: 0x1099, 0x1ac4: 0x10b1, 0x1ac5: 0x10c9, + 0x1ac6: 0xbac9, 0x1ac7: 0xbae1, 0x1ac8: 0xbaf9, 0x1ac9: 0x1429, 0x1aca: 0x1a31, 0x1acb: 0xbb11, + 0x1acc: 0xbb29, 0x1acd: 0xbb41, 0x1ace: 0xbb59, 0x1acf: 0xbb71, 0x1ad0: 0xbb89, 0x1ad1: 0x2109, + 0x1ad2: 0x1111, 0x1ad3: 0xbba1, 0x1ad4: 0xbba1, 0x1ad5: 0xbbb9, 0x1ad6: 0xbbd1, 0x1ad7: 0x10e1, + 0x1ad8: 0x10f9, 0x1ad9: 0xbbe9, 0x1ada: 0x2079, 0x1adb: 0xbc21, 0x1adc: 0xbac9, 0x1add: 0x1429, + 0x1ade: 0xbb11, 0x1adf: 0x10e1, 0x1ae0: 0x1111, 0x1ae1: 0x2109, 0x1ae2: 0xbab1, 0x1ae3: 0x1099, + 0x1ae4: 0x10b1, 0x1ae5: 0x10c9, 0x1ae6: 0xbac9, 0x1ae7: 0xbae1, 0x1ae8: 0xbaf9, 0x1ae9: 0x1429, + 0x1aea: 0x1a31, 0x1aeb: 0xbb11, 0x1aec: 0xbb29, 0x1aed: 0xbb41, 0x1aee: 0xbb59, 0x1aef: 0xbb71, + 0x1af0: 0xbb89, 0x1af1: 0x2109, 0x1af2: 0x1111, 0x1af3: 0x1429, 0x1af4: 0xbba1, 0x1af5: 0xbbb9, + 0x1af6: 0xbbd1, 0x1af7: 0x10e1, 0x1af8: 0x10f9, 0x1af9: 0xbbe9, 0x1afa: 0x2079, 0x1afb: 0xbc01, + 0x1afc: 0xbab1, 0x1afd: 0x1099, 0x1afe: 0x10b1, 0x1aff: 0x10c9, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0xbac9, 0x1b01: 0xbae1, 0x1b02: 0xbaf9, 0x1b03: 0x1429, 0x1b04: 0x1a31, 0x1b05: 0xbb11, + 0x1b06: 0xbb29, 0x1b07: 0xbb41, 0x1b08: 0xbb59, 0x1b09: 0xbb71, 0x1b0a: 0xbb89, 0x1b0b: 0x2109, + 0x1b0c: 0x1111, 0x1b0d: 0xbba1, 0x1b0e: 0xbba1, 0x1b0f: 0xbbb9, 0x1b10: 0xbbd1, 0x1b11: 0x10e1, + 0x1b12: 0x10f9, 0x1b13: 0xbbe9, 0x1b14: 0x2079, 0x1b15: 0xbc21, 0x1b16: 0xbac9, 0x1b17: 0x1429, + 0x1b18: 0xbb11, 0x1b19: 0x10e1, 0x1b1a: 0x1111, 0x1b1b: 0x2109, 0x1b1c: 0xbab1, 0x1b1d: 0x1099, + 0x1b1e: 0x10b1, 0x1b1f: 0x10c9, 0x1b20: 0xbac9, 0x1b21: 0xbae1, 0x1b22: 0xbaf9, 0x1b23: 0x1429, + 0x1b24: 0x1a31, 0x1b25: 0xbb11, 0x1b26: 0xbb29, 0x1b27: 0xbb41, 0x1b28: 0xbb59, 0x1b29: 0xbb71, + 0x1b2a: 0xbb89, 0x1b2b: 0x2109, 0x1b2c: 0x1111, 0x1b2d: 0x1429, 0x1b2e: 0xbba1, 0x1b2f: 0xbbb9, + 0x1b30: 0xbbd1, 0x1b31: 0x10e1, 0x1b32: 0x10f9, 0x1b33: 0xbbe9, 0x1b34: 0x2079, 0x1b35: 0xbc01, + 0x1b36: 0xbab1, 0x1b37: 0x1099, 0x1b38: 0x10b1, 0x1b39: 0x10c9, 0x1b3a: 0xbac9, 0x1b3b: 0xbae1, + 0x1b3c: 0xbaf9, 0x1b3d: 0x1429, 0x1b3e: 0x1a31, 0x1b3f: 0xbb11, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0xbb29, 0x1b41: 0xbb41, 0x1b42: 0xbb59, 0x1b43: 0xbb71, 0x1b44: 0xbb89, 0x1b45: 0x2109, + 0x1b46: 0x1111, 0x1b47: 0xbba1, 0x1b48: 0xbba1, 0x1b49: 0xbbb9, 0x1b4a: 0xbbd1, 0x1b4b: 0x10e1, + 0x1b4c: 0x10f9, 0x1b4d: 0xbbe9, 0x1b4e: 0x2079, 0x1b4f: 0xbc21, 0x1b50: 0xbac9, 0x1b51: 0x1429, + 0x1b52: 0xbb11, 0x1b53: 0x10e1, 0x1b54: 0x1111, 0x1b55: 0x2109, 0x1b56: 0xbab1, 0x1b57: 0x1099, + 0x1b58: 0x10b1, 0x1b59: 0x10c9, 0x1b5a: 0xbac9, 0x1b5b: 0xbae1, 0x1b5c: 0xbaf9, 0x1b5d: 0x1429, + 0x1b5e: 0x1a31, 0x1b5f: 0xbb11, 0x1b60: 0xbb29, 0x1b61: 0xbb41, 0x1b62: 0xbb59, 0x1b63: 0xbb71, + 0x1b64: 0xbb89, 0x1b65: 0x2109, 0x1b66: 0x1111, 0x1b67: 0x1429, 0x1b68: 0xbba1, 0x1b69: 0xbbb9, + 0x1b6a: 0xbbd1, 0x1b6b: 0x10e1, 0x1b6c: 0x10f9, 0x1b6d: 0xbbe9, 0x1b6e: 0x2079, 0x1b6f: 0xbc01, + 0x1b70: 0xbab1, 0x1b71: 0x1099, 0x1b72: 0x10b1, 0x1b73: 0x10c9, 0x1b74: 0xbac9, 0x1b75: 0xbae1, + 0x1b76: 0xbaf9, 0x1b77: 0x1429, 0x1b78: 0x1a31, 0x1b79: 0xbb11, 0x1b7a: 0xbb29, 0x1b7b: 0xbb41, + 0x1b7c: 0xbb59, 0x1b7d: 0xbb71, 0x1b7e: 0xbb89, 0x1b7f: 0x2109, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x1111, 0x1b81: 0xbba1, 0x1b82: 0xbba1, 0x1b83: 0xbbb9, 0x1b84: 0xbbd1, 0x1b85: 0x10e1, + 0x1b86: 0x10f9, 0x1b87: 0xbbe9, 0x1b88: 0x2079, 0x1b89: 0xbc21, 0x1b8a: 0xbac9, 0x1b8b: 0x1429, + 0x1b8c: 0xbb11, 0x1b8d: 0x10e1, 0x1b8e: 0x1111, 0x1b8f: 0x2109, 0x1b90: 0xbab1, 0x1b91: 0x1099, + 0x1b92: 0x10b1, 0x1b93: 0x10c9, 0x1b94: 0xbac9, 0x1b95: 0xbae1, 0x1b96: 0xbaf9, 0x1b97: 0x1429, + 0x1b98: 0x1a31, 0x1b99: 0xbb11, 0x1b9a: 0xbb29, 0x1b9b: 0xbb41, 0x1b9c: 0xbb59, 0x1b9d: 0xbb71, + 0x1b9e: 0xbb89, 0x1b9f: 0x2109, 0x1ba0: 0x1111, 0x1ba1: 0x1429, 0x1ba2: 0xbba1, 0x1ba3: 0xbbb9, + 0x1ba4: 0xbbd1, 0x1ba5: 0x10e1, 0x1ba6: 0x10f9, 0x1ba7: 0xbbe9, 0x1ba8: 0x2079, 0x1ba9: 0xbc01, + 0x1baa: 0xbab1, 0x1bab: 0x1099, 0x1bac: 0x10b1, 0x1bad: 0x10c9, 0x1bae: 0xbac9, 0x1baf: 0xbae1, + 0x1bb0: 0xbaf9, 0x1bb1: 0x1429, 0x1bb2: 0x1a31, 0x1bb3: 0xbb11, 0x1bb4: 0xbb29, 0x1bb5: 0xbb41, + 0x1bb6: 0xbb59, 0x1bb7: 0xbb71, 0x1bb8: 0xbb89, 0x1bb9: 0x2109, 0x1bba: 0x1111, 0x1bbb: 0xbba1, + 0x1bbc: 0xbba1, 0x1bbd: 0xbbb9, 0x1bbe: 0xbbd1, 0x1bbf: 0x10e1, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x10f9, 0x1bc1: 0xbbe9, 0x1bc2: 0x2079, 0x1bc3: 0xbc21, 0x1bc4: 0xbac9, 0x1bc5: 0x1429, + 0x1bc6: 0xbb11, 0x1bc7: 0x10e1, 0x1bc8: 0x1111, 0x1bc9: 0x2109, 0x1bca: 0xbc41, 0x1bcb: 0xbc41, + 0x1bcc: 0x0040, 0x1bcd: 0x0040, 0x1bce: 0x1f41, 0x1bcf: 0x00c9, 0x1bd0: 0x0069, 0x1bd1: 0x0079, + 0x1bd2: 0x1f51, 0x1bd3: 0x1f61, 0x1bd4: 0x1f71, 0x1bd5: 0x1f81, 0x1bd6: 0x1f91, 0x1bd7: 0x1fa1, + 0x1bd8: 0x1f41, 0x1bd9: 0x00c9, 0x1bda: 0x0069, 0x1bdb: 0x0079, 0x1bdc: 0x1f51, 0x1bdd: 0x1f61, + 0x1bde: 0x1f71, 0x1bdf: 0x1f81, 0x1be0: 0x1f91, 0x1be1: 0x1fa1, 0x1be2: 0x1f41, 0x1be3: 0x00c9, + 0x1be4: 0x0069, 0x1be5: 0x0079, 0x1be6: 0x1f51, 0x1be7: 0x1f61, 0x1be8: 0x1f71, 0x1be9: 0x1f81, + 0x1bea: 0x1f91, 0x1beb: 0x1fa1, 0x1bec: 0x1f41, 0x1bed: 0x00c9, 0x1bee: 0x0069, 0x1bef: 0x0079, + 0x1bf0: 0x1f51, 0x1bf1: 0x1f61, 0x1bf2: 0x1f71, 0x1bf3: 0x1f81, 0x1bf4: 0x1f91, 0x1bf5: 0x1fa1, + 0x1bf6: 0x1f41, 0x1bf7: 0x00c9, 0x1bf8: 0x0069, 0x1bf9: 0x0079, 0x1bfa: 0x1f51, 0x1bfb: 0x1f61, + 0x1bfc: 0x1f71, 0x1bfd: 0x1f81, 0x1bfe: 0x1f91, 0x1bff: 0x1fa1, + // Block 0x70, offset 0x1c00 + 0x1c00: 0xe115, 0x1c01: 0xe115, 0x1c02: 0xe135, 0x1c03: 0xe135, 0x1c04: 0xe115, 0x1c05: 0xe115, + 0x1c06: 0xe175, 0x1c07: 0xe175, 0x1c08: 0xe115, 0x1c09: 0xe115, 0x1c0a: 0xe135, 0x1c0b: 0xe135, + 0x1c0c: 0xe115, 0x1c0d: 0xe115, 0x1c0e: 0xe1f5, 0x1c0f: 0xe1f5, 0x1c10: 0xe115, 0x1c11: 0xe115, + 0x1c12: 0xe135, 0x1c13: 0xe135, 0x1c14: 0xe115, 0x1c15: 0xe115, 0x1c16: 0xe175, 0x1c17: 0xe175, + 0x1c18: 0xe115, 0x1c19: 0xe115, 0x1c1a: 0xe135, 0x1c1b: 0xe135, 0x1c1c: 0xe115, 0x1c1d: 0xe115, + 0x1c1e: 0x8b05, 0x1c1f: 0x8b05, 0x1c20: 0x04b5, 0x1c21: 0x04b5, 0x1c22: 0x0a08, 0x1c23: 0x0a08, + 0x1c24: 0x0a08, 0x1c25: 0x0a08, 0x1c26: 0x0a08, 0x1c27: 0x0a08, 0x1c28: 0x0a08, 0x1c29: 0x0a08, + 0x1c2a: 0x0a08, 0x1c2b: 0x0a08, 0x1c2c: 0x0a08, 0x1c2d: 0x0a08, 0x1c2e: 0x0a08, 0x1c2f: 0x0a08, + 0x1c30: 0x0a08, 0x1c31: 0x0a08, 0x1c32: 0x0a08, 0x1c33: 0x0a08, 0x1c34: 0x0a08, 0x1c35: 0x0a08, + 0x1c36: 0x0a08, 0x1c37: 0x0a08, 0x1c38: 0x0a08, 0x1c39: 0x0a08, 0x1c3a: 0x0a08, 0x1c3b: 0x0a08, + 0x1c3c: 0x0a08, 0x1c3d: 0x0a08, 0x1c3e: 0x0a08, 0x1c3f: 0x0a08, + // Block 0x71, offset 0x1c40 + 0x1c40: 0xb189, 0x1c41: 0xb1a1, 0x1c42: 0xb201, 0x1c43: 0xb249, 0x1c44: 0x0040, 0x1c45: 0xb411, + 0x1c46: 0xb291, 0x1c47: 0xb219, 0x1c48: 0xb309, 0x1c49: 0xb429, 0x1c4a: 0xb399, 0x1c4b: 0xb3b1, + 0x1c4c: 0xb3c9, 0x1c4d: 0xb3e1, 0x1c4e: 0xb2a9, 0x1c4f: 0xb339, 0x1c50: 0xb369, 0x1c51: 0xb2d9, + 0x1c52: 0xb381, 0x1c53: 0xb279, 0x1c54: 0xb2c1, 0x1c55: 0xb1d1, 0x1c56: 0xb1e9, 0x1c57: 0xb231, + 0x1c58: 0xb261, 0x1c59: 0xb2f1, 0x1c5a: 0xb321, 0x1c5b: 0xb351, 0x1c5c: 0xbc59, 0x1c5d: 0x7949, + 0x1c5e: 0xbc71, 0x1c5f: 0xbc89, 0x1c60: 0x0040, 0x1c61: 0xb1a1, 0x1c62: 0xb201, 0x1c63: 0x0040, + 0x1c64: 0xb3f9, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0xb219, 0x1c68: 0x0040, 0x1c69: 0xb429, + 0x1c6a: 0xb399, 0x1c6b: 0xb3b1, 0x1c6c: 0xb3c9, 0x1c6d: 0xb3e1, 0x1c6e: 0xb2a9, 0x1c6f: 0xb339, + 0x1c70: 0xb369, 0x1c71: 0xb2d9, 0x1c72: 0xb381, 0x1c73: 0x0040, 0x1c74: 0xb2c1, 0x1c75: 0xb1d1, + 0x1c76: 0xb1e9, 0x1c77: 0xb231, 0x1c78: 0x0040, 0x1c79: 0xb2f1, 0x1c7a: 0x0040, 0x1c7b: 0xb351, + 0x1c7c: 0x0040, 0x1c7d: 0x0040, 0x1c7e: 0x0040, 0x1c7f: 0x0040, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x0040, 0x1c81: 0x0040, 0x1c82: 0xb201, 0x1c83: 0x0040, 0x1c84: 0x0040, 0x1c85: 0x0040, + 0x1c86: 0x0040, 0x1c87: 0xb219, 0x1c88: 0x0040, 0x1c89: 0xb429, 0x1c8a: 0x0040, 0x1c8b: 0xb3b1, + 0x1c8c: 0x0040, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0x0040, 0x1c91: 0xb2d9, + 0x1c92: 0xb381, 0x1c93: 0x0040, 0x1c94: 0xb2c1, 0x1c95: 0x0040, 0x1c96: 0x0040, 0x1c97: 0xb231, + 0x1c98: 0x0040, 0x1c99: 0xb2f1, 0x1c9a: 0x0040, 0x1c9b: 0xb351, 0x1c9c: 0x0040, 0x1c9d: 0x7949, + 0x1c9e: 0x0040, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, + 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0xb309, 0x1ca9: 0xb429, + 0x1caa: 0xb399, 0x1cab: 0x0040, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, + 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, + 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0xb321, 0x1cbb: 0xb351, + 0x1cbc: 0xbc59, 0x1cbd: 0x0040, 0x1cbe: 0xbc71, 0x1cbf: 0x0040, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0xb189, 0x1cc1: 0xb1a1, 0x1cc2: 0xb201, 0x1cc3: 0xb249, 0x1cc4: 0xb3f9, 0x1cc5: 0xb411, + 0x1cc6: 0xb291, 0x1cc7: 0xb219, 0x1cc8: 0xb309, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, + 0x1ccc: 0xb3c9, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0xb369, 0x1cd1: 0xb2d9, + 0x1cd2: 0xb381, 0x1cd3: 0xb279, 0x1cd4: 0xb2c1, 0x1cd5: 0xb1d1, 0x1cd6: 0xb1e9, 0x1cd7: 0xb231, + 0x1cd8: 0xb261, 0x1cd9: 0xb2f1, 0x1cda: 0xb321, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x0040, + 0x1cde: 0x0040, 0x1cdf: 0x0040, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0xb249, + 0x1ce4: 0x0040, 0x1ce5: 0xb411, 0x1ce6: 0xb291, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, + 0x1cea: 0x0040, 0x1ceb: 0xb3b1, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, + 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0xb279, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, + 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0xb261, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, + 0x1cfc: 0x0040, 0x1cfd: 0x0040, 0x1cfe: 0x0040, 0x1cff: 0x0040, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x0040, 0x1d01: 0xbca2, 0x1d02: 0xbcba, 0x1d03: 0xbcd2, 0x1d04: 0xbcea, 0x1d05: 0xbd02, + 0x1d06: 0xbd1a, 0x1d07: 0xbd32, 0x1d08: 0xbd4a, 0x1d09: 0xbd62, 0x1d0a: 0xbd7a, 0x1d0b: 0x0018, + 0x1d0c: 0x0018, 0x1d0d: 0x0040, 0x1d0e: 0x0040, 0x1d0f: 0x0040, 0x1d10: 0xbd92, 0x1d11: 0xbdb2, + 0x1d12: 0xbdd2, 0x1d13: 0xbdf2, 0x1d14: 0xbe12, 0x1d15: 0xbe32, 0x1d16: 0xbe52, 0x1d17: 0xbe72, + 0x1d18: 0xbe92, 0x1d19: 0xbeb2, 0x1d1a: 0xbed2, 0x1d1b: 0xbef2, 0x1d1c: 0xbf12, 0x1d1d: 0xbf32, + 0x1d1e: 0xbf52, 0x1d1f: 0xbf72, 0x1d20: 0xbf92, 0x1d21: 0xbfb2, 0x1d22: 0xbfd2, 0x1d23: 0xbff2, + 0x1d24: 0xc012, 0x1d25: 0xc032, 0x1d26: 0xc052, 0x1d27: 0xc072, 0x1d28: 0xc092, 0x1d29: 0xc0b2, + 0x1d2a: 0xc0d1, 0x1d2b: 0x1159, 0x1d2c: 0x0269, 0x1d2d: 0x6671, 0x1d2e: 0xc111, 0x1d2f: 0x0040, + 0x1d30: 0x0039, 0x1d31: 0x0ee9, 0x1d32: 0x1159, 0x1d33: 0x0ef9, 0x1d34: 0x0f09, 0x1d35: 0x1199, + 0x1d36: 0x0f31, 0x1d37: 0x0249, 0x1d38: 0x0f41, 0x1d39: 0x0259, 0x1d3a: 0x0f51, 0x1d3b: 0x0359, + 0x1d3c: 0x0f61, 0x1d3d: 0x0f71, 0x1d3e: 0x00d9, 0x1d3f: 0x0f99, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x2039, 0x1d41: 0x0269, 0x1d42: 0x01d9, 0x1d43: 0x0fa9, 0x1d44: 0x0fb9, 0x1d45: 0x1089, + 0x1d46: 0x0279, 0x1d47: 0x0369, 0x1d48: 0x0289, 0x1d49: 0x13d1, 0x1d4a: 0xc129, 0x1d4b: 0x65b1, + 0x1d4c: 0xc141, 0x1d4d: 0x1441, 0x1d4e: 0xc159, 0x1d4f: 0xc179, 0x1d50: 0x0018, 0x1d51: 0x0018, + 0x1d52: 0x0018, 0x1d53: 0x0018, 0x1d54: 0x0018, 0x1d55: 0x0018, 0x1d56: 0x0018, 0x1d57: 0x0018, + 0x1d58: 0x0018, 0x1d59: 0x0018, 0x1d5a: 0x0018, 0x1d5b: 0x0018, 0x1d5c: 0x0018, 0x1d5d: 0x0018, + 0x1d5e: 0x0018, 0x1d5f: 0x0018, 0x1d60: 0x0018, 0x1d61: 0x0018, 0x1d62: 0x0018, 0x1d63: 0x0018, + 0x1d64: 0x0018, 0x1d65: 0x0018, 0x1d66: 0x0018, 0x1d67: 0x0018, 0x1d68: 0x0018, 0x1d69: 0x0018, + 0x1d6a: 0xc191, 0x1d6b: 0xc1a9, 0x1d6c: 0x0040, 0x1d6d: 0x0040, 0x1d6e: 0x0040, 0x1d6f: 0x0040, + 0x1d70: 0x0018, 0x1d71: 0x0018, 0x1d72: 0x0018, 0x1d73: 0x0018, 0x1d74: 0x0018, 0x1d75: 0x0018, + 0x1d76: 0x0018, 0x1d77: 0x0018, 0x1d78: 0x0018, 0x1d79: 0x0018, 0x1d7a: 0x0018, 0x1d7b: 0x0018, + 0x1d7c: 0x0018, 0x1d7d: 0x0018, 0x1d7e: 0x0018, 0x1d7f: 0x0018, + // Block 0x76, offset 0x1d80 + 0x1d80: 0xc1d9, 0x1d81: 0xc211, 0x1d82: 0xc249, 0x1d83: 0x0040, 0x1d84: 0x0040, 0x1d85: 0x0040, + 0x1d86: 0x0040, 0x1d87: 0x0040, 0x1d88: 0x0040, 0x1d89: 0x0040, 0x1d8a: 0x0040, 0x1d8b: 0x0040, + 0x1d8c: 0x0040, 0x1d8d: 0x0040, 0x1d8e: 0x0040, 0x1d8f: 0x0040, 0x1d90: 0xc269, 0x1d91: 0xc289, + 0x1d92: 0xc2a9, 0x1d93: 0xc2c9, 0x1d94: 0xc2e9, 0x1d95: 0xc309, 0x1d96: 0xc329, 0x1d97: 0xc349, + 0x1d98: 0xc369, 0x1d99: 0xc389, 0x1d9a: 0xc3a9, 0x1d9b: 0xc3c9, 0x1d9c: 0xc3e9, 0x1d9d: 0xc409, + 0x1d9e: 0xc429, 0x1d9f: 0xc449, 0x1da0: 0xc469, 0x1da1: 0xc489, 0x1da2: 0xc4a9, 0x1da3: 0xc4c9, + 0x1da4: 0xc4e9, 0x1da5: 0xc509, 0x1da6: 0xc529, 0x1da7: 0xc549, 0x1da8: 0xc569, 0x1da9: 0xc589, + 0x1daa: 0xc5a9, 0x1dab: 0xc5c9, 0x1dac: 0xc5e9, 0x1dad: 0xc609, 0x1dae: 0xc629, 0x1daf: 0xc649, + 0x1db0: 0xc669, 0x1db1: 0xc689, 0x1db2: 0xc6a9, 0x1db3: 0xc6c9, 0x1db4: 0xc6e9, 0x1db5: 0xc709, + 0x1db6: 0xc729, 0x1db7: 0xc749, 0x1db8: 0xc769, 0x1db9: 0xc789, 0x1dba: 0xc7a9, 0x1dbb: 0xc7c9, + 0x1dbc: 0x0040, 0x1dbd: 0x0040, 0x1dbe: 0x0040, 0x1dbf: 0x0040, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0xcaf9, 0x1dc1: 0xcb19, 0x1dc2: 0xcb39, 0x1dc3: 0x8b1d, 0x1dc4: 0xcb59, 0x1dc5: 0xcb79, + 0x1dc6: 0xcb99, 0x1dc7: 0xcbb9, 0x1dc8: 0xcbd9, 0x1dc9: 0xcbf9, 0x1dca: 0xcc19, 0x1dcb: 0xcc39, + 0x1dcc: 0xcc59, 0x1dcd: 0x8b3d, 0x1dce: 0xcc79, 0x1dcf: 0xcc99, 0x1dd0: 0xccb9, 0x1dd1: 0xccd9, + 0x1dd2: 0x8b5d, 0x1dd3: 0xccf9, 0x1dd4: 0xcd19, 0x1dd5: 0xc429, 0x1dd6: 0x8b7d, 0x1dd7: 0xcd39, + 0x1dd8: 0xcd59, 0x1dd9: 0xcd79, 0x1dda: 0xcd99, 0x1ddb: 0xcdb9, 0x1ddc: 0x8b9d, 0x1ddd: 0xcdd9, + 0x1dde: 0xcdf9, 0x1ddf: 0xce19, 0x1de0: 0xce39, 0x1de1: 0xce59, 0x1de2: 0xc789, 0x1de3: 0xce79, + 0x1de4: 0xce99, 0x1de5: 0xceb9, 0x1de6: 0xced9, 0x1de7: 0xcef9, 0x1de8: 0xcf19, 0x1de9: 0xcf39, + 0x1dea: 0xcf59, 0x1deb: 0xcf79, 0x1dec: 0xcf99, 0x1ded: 0xcfb9, 0x1dee: 0xcfd9, 0x1def: 0xcff9, + 0x1df0: 0xd019, 0x1df1: 0xd039, 0x1df2: 0xd039, 0x1df3: 0xd039, 0x1df4: 0x8bbd, 0x1df5: 0xd059, + 0x1df6: 0xd079, 0x1df7: 0xd099, 0x1df8: 0x8bdd, 0x1df9: 0xd0b9, 0x1dfa: 0xd0d9, 0x1dfb: 0xd0f9, + 0x1dfc: 0xd119, 0x1dfd: 0xd139, 0x1dfe: 0xd159, 0x1dff: 0xd179, + // Block 0x78, offset 0x1e00 + 0x1e00: 0xd199, 0x1e01: 0xd1b9, 0x1e02: 0xd1d9, 0x1e03: 0xd1f9, 0x1e04: 0xd219, 0x1e05: 0xd239, + 0x1e06: 0xd239, 0x1e07: 0xd259, 0x1e08: 0xd279, 0x1e09: 0xd299, 0x1e0a: 0xd2b9, 0x1e0b: 0xd2d9, + 0x1e0c: 0xd2f9, 0x1e0d: 0xd319, 0x1e0e: 0xd339, 0x1e0f: 0xd359, 0x1e10: 0xd379, 0x1e11: 0xd399, + 0x1e12: 0xd3b9, 0x1e13: 0xd3d9, 0x1e14: 0xd3f9, 0x1e15: 0xd419, 0x1e16: 0xd439, 0x1e17: 0xd459, + 0x1e18: 0xd479, 0x1e19: 0x8bfd, 0x1e1a: 0xd499, 0x1e1b: 0xd4b9, 0x1e1c: 0xd4d9, 0x1e1d: 0xc309, + 0x1e1e: 0xd4f9, 0x1e1f: 0xd519, 0x1e20: 0x8c1d, 0x1e21: 0x8c3d, 0x1e22: 0xd539, 0x1e23: 0xd559, + 0x1e24: 0xd579, 0x1e25: 0xd599, 0x1e26: 0xd5b9, 0x1e27: 0xd5d9, 0x1e28: 0x2040, 0x1e29: 0xd5f9, + 0x1e2a: 0xd619, 0x1e2b: 0xd619, 0x1e2c: 0x8c5d, 0x1e2d: 0xd639, 0x1e2e: 0xd659, 0x1e2f: 0xd679, + 0x1e30: 0xd699, 0x1e31: 0x8c7d, 0x1e32: 0xd6b9, 0x1e33: 0xd6d9, 0x1e34: 0x2040, 0x1e35: 0xd6f9, + 0x1e36: 0xd719, 0x1e37: 0xd739, 0x1e38: 0xd759, 0x1e39: 0xd779, 0x1e3a: 0xd799, 0x1e3b: 0x8c9d, + 0x1e3c: 0xd7b9, 0x1e3d: 0x8cbd, 0x1e3e: 0xd7d9, 0x1e3f: 0xd7f9, + // Block 0x79, offset 0x1e40 + 0x1e40: 0xd819, 0x1e41: 0xd839, 0x1e42: 0xd859, 0x1e43: 0xd879, 0x1e44: 0xd899, 0x1e45: 0xd8b9, + 0x1e46: 0xd8d9, 0x1e47: 0xd8f9, 0x1e48: 0xd919, 0x1e49: 0x8cdd, 0x1e4a: 0xd939, 0x1e4b: 0xd959, + 0x1e4c: 0xd979, 0x1e4d: 0xd999, 0x1e4e: 0xd9b9, 0x1e4f: 0x8cfd, 0x1e50: 0xd9d9, 0x1e51: 0x8d1d, + 0x1e52: 0x8d3d, 0x1e53: 0xd9f9, 0x1e54: 0xda19, 0x1e55: 0xda19, 0x1e56: 0xda39, 0x1e57: 0x8d5d, + 0x1e58: 0x8d7d, 0x1e59: 0xda59, 0x1e5a: 0xda79, 0x1e5b: 0xda99, 0x1e5c: 0xdab9, 0x1e5d: 0xdad9, + 0x1e5e: 0xdaf9, 0x1e5f: 0xdb19, 0x1e60: 0xdb39, 0x1e61: 0xdb59, 0x1e62: 0xdb79, 0x1e63: 0xdb99, + 0x1e64: 0x8d9d, 0x1e65: 0xdbb9, 0x1e66: 0xdbd9, 0x1e67: 0xdbf9, 0x1e68: 0xdc19, 0x1e69: 0xdbf9, + 0x1e6a: 0xdc39, 0x1e6b: 0xdc59, 0x1e6c: 0xdc79, 0x1e6d: 0xdc99, 0x1e6e: 0xdcb9, 0x1e6f: 0xdcd9, + 0x1e70: 0xdcf9, 0x1e71: 0xdd19, 0x1e72: 0xdd39, 0x1e73: 0xdd59, 0x1e74: 0xdd79, 0x1e75: 0xdd99, + 0x1e76: 0xddb9, 0x1e77: 0xddd9, 0x1e78: 0x8dbd, 0x1e79: 0xddf9, 0x1e7a: 0xde19, 0x1e7b: 0xde39, + 0x1e7c: 0xde59, 0x1e7d: 0xde79, 0x1e7e: 0x8ddd, 0x1e7f: 0xde99, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0xe599, 0x1e81: 0xe5b9, 0x1e82: 0xe5d9, 0x1e83: 0xe5f9, 0x1e84: 0xe619, 0x1e85: 0xe639, + 0x1e86: 0x8efd, 0x1e87: 0xe659, 0x1e88: 0xe679, 0x1e89: 0xe699, 0x1e8a: 0xe6b9, 0x1e8b: 0xe6d9, + 0x1e8c: 0xe6f9, 0x1e8d: 0x8f1d, 0x1e8e: 0xe719, 0x1e8f: 0xe739, 0x1e90: 0x8f3d, 0x1e91: 0x8f5d, + 0x1e92: 0xe759, 0x1e93: 0xe779, 0x1e94: 0xe799, 0x1e95: 0xe7b9, 0x1e96: 0xe7d9, 0x1e97: 0xe7f9, + 0x1e98: 0xe819, 0x1e99: 0xe839, 0x1e9a: 0xe859, 0x1e9b: 0x8f7d, 0x1e9c: 0xe879, 0x1e9d: 0x8f9d, + 0x1e9e: 0xe899, 0x1e9f: 0x2040, 0x1ea0: 0xe8b9, 0x1ea1: 0xe8d9, 0x1ea2: 0xe8f9, 0x1ea3: 0x8fbd, + 0x1ea4: 0xe919, 0x1ea5: 0xe939, 0x1ea6: 0x8fdd, 0x1ea7: 0x8ffd, 0x1ea8: 0xe959, 0x1ea9: 0xe979, + 0x1eaa: 0xe999, 0x1eab: 0xe9b9, 0x1eac: 0xe9d9, 0x1ead: 0xe9d9, 0x1eae: 0xe9f9, 0x1eaf: 0xea19, + 0x1eb0: 0xea39, 0x1eb1: 0xea59, 0x1eb2: 0xea79, 0x1eb3: 0xea99, 0x1eb4: 0xeab9, 0x1eb5: 0x901d, + 0x1eb6: 0xead9, 0x1eb7: 0x903d, 0x1eb8: 0xeaf9, 0x1eb9: 0x905d, 0x1eba: 0xeb19, 0x1ebb: 0x907d, + 0x1ebc: 0x909d, 0x1ebd: 0x90bd, 0x1ebe: 0xeb39, 0x1ebf: 0xeb59, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xeb79, 0x1ec1: 0x90dd, 0x1ec2: 0x90fd, 0x1ec3: 0x911d, 0x1ec4: 0x913d, 0x1ec5: 0xeb99, + 0x1ec6: 0xebb9, 0x1ec7: 0xebb9, 0x1ec8: 0xebd9, 0x1ec9: 0xebf9, 0x1eca: 0xec19, 0x1ecb: 0xec39, + 0x1ecc: 0xec59, 0x1ecd: 0x915d, 0x1ece: 0xec79, 0x1ecf: 0xec99, 0x1ed0: 0xecb9, 0x1ed1: 0xecd9, + 0x1ed2: 0x917d, 0x1ed3: 0xecf9, 0x1ed4: 0x919d, 0x1ed5: 0x91bd, 0x1ed6: 0xed19, 0x1ed7: 0xed39, + 0x1ed8: 0xed59, 0x1ed9: 0xed79, 0x1eda: 0xed99, 0x1edb: 0xedb9, 0x1edc: 0x91dd, 0x1edd: 0x91fd, + 0x1ede: 0x921d, 0x1edf: 0x2040, 0x1ee0: 0xedd9, 0x1ee1: 0x923d, 0x1ee2: 0xedf9, 0x1ee3: 0xee19, + 0x1ee4: 0xee39, 0x1ee5: 0x925d, 0x1ee6: 0xee59, 0x1ee7: 0xee79, 0x1ee8: 0xee99, 0x1ee9: 0xeeb9, + 0x1eea: 0xeed9, 0x1eeb: 0x927d, 0x1eec: 0xeef9, 0x1eed: 0xef19, 0x1eee: 0xef39, 0x1eef: 0xef59, + 0x1ef0: 0xef79, 0x1ef1: 0xef99, 0x1ef2: 0x929d, 0x1ef3: 0x92bd, 0x1ef4: 0xefb9, 0x1ef5: 0x92dd, + 0x1ef6: 0xefd9, 0x1ef7: 0x92fd, 0x1ef8: 0xeff9, 0x1ef9: 0xf019, 0x1efa: 0xf039, 0x1efb: 0x931d, + 0x1efc: 0x933d, 0x1efd: 0xf059, 0x1efe: 0x935d, 0x1eff: 0xf079, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0xf6b9, 0x1f01: 0xf6d9, 0x1f02: 0xf6f9, 0x1f03: 0xf719, 0x1f04: 0xf739, 0x1f05: 0x951d, + 0x1f06: 0xf759, 0x1f07: 0xf779, 0x1f08: 0xf799, 0x1f09: 0xf7b9, 0x1f0a: 0xf7d9, 0x1f0b: 0x953d, + 0x1f0c: 0x955d, 0x1f0d: 0xf7f9, 0x1f0e: 0xf819, 0x1f0f: 0xf839, 0x1f10: 0xf859, 0x1f11: 0xf879, + 0x1f12: 0xf899, 0x1f13: 0x957d, 0x1f14: 0xf8b9, 0x1f15: 0xf8d9, 0x1f16: 0xf8f9, 0x1f17: 0xf919, + 0x1f18: 0x959d, 0x1f19: 0x95bd, 0x1f1a: 0xf939, 0x1f1b: 0xf959, 0x1f1c: 0xf979, 0x1f1d: 0x95dd, + 0x1f1e: 0xf999, 0x1f1f: 0xf9b9, 0x1f20: 0x6815, 0x1f21: 0x95fd, 0x1f22: 0xf9d9, 0x1f23: 0xf9f9, + 0x1f24: 0xfa19, 0x1f25: 0x961d, 0x1f26: 0xfa39, 0x1f27: 0xfa59, 0x1f28: 0xfa79, 0x1f29: 0xfa99, + 0x1f2a: 0xfab9, 0x1f2b: 0xfad9, 0x1f2c: 0xfaf9, 0x1f2d: 0x963d, 0x1f2e: 0xfb19, 0x1f2f: 0xfb39, + 0x1f30: 0xfb59, 0x1f31: 0x965d, 0x1f32: 0xfb79, 0x1f33: 0xfb99, 0x1f34: 0xfbb9, 0x1f35: 0xfbd9, + 0x1f36: 0x7b35, 0x1f37: 0x967d, 0x1f38: 0xfbf9, 0x1f39: 0xfc19, 0x1f3a: 0xfc39, 0x1f3b: 0x969d, + 0x1f3c: 0xfc59, 0x1f3d: 0x96bd, 0x1f3e: 0xfc79, 0x1f3f: 0xfc79, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xfc99, 0x1f41: 0x96dd, 0x1f42: 0xfcb9, 0x1f43: 0xfcd9, 0x1f44: 0xfcf9, 0x1f45: 0xfd19, + 0x1f46: 0xfd39, 0x1f47: 0xfd59, 0x1f48: 0xfd79, 0x1f49: 0x96fd, 0x1f4a: 0xfd99, 0x1f4b: 0xfdb9, + 0x1f4c: 0xfdd9, 0x1f4d: 0xfdf9, 0x1f4e: 0xfe19, 0x1f4f: 0xfe39, 0x1f50: 0x971d, 0x1f51: 0xfe59, + 0x1f52: 0x973d, 0x1f53: 0x975d, 0x1f54: 0x977d, 0x1f55: 0xfe79, 0x1f56: 0xfe99, 0x1f57: 0xfeb9, + 0x1f58: 0xfed9, 0x1f59: 0xfef9, 0x1f5a: 0xff19, 0x1f5b: 0xff39, 0x1f5c: 0xff59, 0x1f5d: 0x979d, + 0x1f5e: 0x0040, 0x1f5f: 0x0040, 0x1f60: 0x0040, 0x1f61: 0x0040, 0x1f62: 0x0040, 0x1f63: 0x0040, + 0x1f64: 0x0040, 0x1f65: 0x0040, 0x1f66: 0x0040, 0x1f67: 0x0040, 0x1f68: 0x0040, 0x1f69: 0x0040, + 0x1f6a: 0x0040, 0x1f6b: 0x0040, 0x1f6c: 0x0040, 0x1f6d: 0x0040, 0x1f6e: 0x0040, 0x1f6f: 0x0040, + 0x1f70: 0x0040, 0x1f71: 0x0040, 0x1f72: 0x0040, 0x1f73: 0x0040, 0x1f74: 0x0040, 0x1f75: 0x0040, + 0x1f76: 0x0040, 0x1f77: 0x0040, 0x1f78: 0x0040, 0x1f79: 0x0040, 0x1f7a: 0x0040, 0x1f7b: 0x0040, + 0x1f7c: 0x0040, 0x1f7d: 0x0040, 0x1f7e: 0x0040, 0x1f7f: 0x0040, +} + +// idnaIndex: 35 blocks, 2240 entries, 4480 bytes +// Block 0 is the zero block. +var idnaIndex = [2240]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x7c, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7d, 0xca: 0x7e, 0xcb: 0x07, 0xcc: 0x7f, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x80, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x81, 0xd6: 0x82, 0xd7: 0x83, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x84, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x85, 0xde: 0x86, 0xdf: 0x87, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, + 0xf0: 0x1c, 0xf1: 0x1d, 0xf2: 0x1d, 0xf3: 0x1f, 0xf4: 0x20, + // Block 0x4, offset 0x100 + 0x120: 0x88, 0x121: 0x89, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x13, 0x126: 0x14, 0x127: 0x15, + 0x128: 0x16, 0x129: 0x17, 0x12a: 0x18, 0x12b: 0x19, 0x12c: 0x1a, 0x12d: 0x1b, 0x12e: 0x1c, 0x12f: 0x8d, + 0x130: 0x8e, 0x131: 0x1d, 0x132: 0x1e, 0x133: 0x1f, 0x134: 0x8f, 0x135: 0x20, 0x136: 0x90, 0x137: 0x91, + 0x138: 0x92, 0x139: 0x93, 0x13a: 0x21, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x22, 0x13e: 0x23, 0x13f: 0x96, + // Block 0x5, offset 0x140 + 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, + 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, + 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, + 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, + 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, + 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, + 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x24, 0x175: 0x25, 0x176: 0x26, 0x177: 0xc3, + 0x178: 0x27, 0x179: 0x27, 0x17a: 0x28, 0x17b: 0x27, 0x17c: 0xc4, 0x17d: 0x29, 0x17e: 0x2a, 0x17f: 0x2b, + // Block 0x6, offset 0x180 + 0x180: 0x2c, 0x181: 0x2d, 0x182: 0x2e, 0x183: 0xc5, 0x184: 0x2f, 0x185: 0x30, 0x186: 0xc6, 0x187: 0x9b, + 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0xca, + 0x190: 0xcb, 0x191: 0x31, 0x192: 0x32, 0x193: 0x33, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, + 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, + 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, + 0x1a8: 0xcc, 0x1a9: 0xcd, 0x1aa: 0x9b, 0x1ab: 0xce, 0x1ac: 0x9b, 0x1ad: 0xcf, 0x1ae: 0xd0, 0x1af: 0xd1, + 0x1b0: 0xd2, 0x1b1: 0x34, 0x1b2: 0x27, 0x1b3: 0x35, 0x1b4: 0xd3, 0x1b5: 0xd4, 0x1b6: 0xd5, 0x1b7: 0xd6, + 0x1b8: 0xd7, 0x1b9: 0xd8, 0x1ba: 0xd9, 0x1bb: 0xda, 0x1bc: 0xdb, 0x1bd: 0xdc, 0x1be: 0xdd, 0x1bf: 0x36, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x37, 0x1c1: 0xde, 0x1c2: 0xdf, 0x1c3: 0xe0, 0x1c4: 0xe1, 0x1c5: 0x38, 0x1c6: 0x39, 0x1c7: 0xe2, + 0x1c8: 0xe3, 0x1c9: 0x3a, 0x1ca: 0x3b, 0x1cb: 0x3c, 0x1cc: 0x3d, 0x1cd: 0x3e, 0x1ce: 0x3f, 0x1cf: 0x40, + 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, + 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, + 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, + 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, + 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, + 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, + // Block 0x8, offset 0x200 + 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, + 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, + 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, + 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, + 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, + 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, + 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, + 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, + // Block 0x9, offset 0x240 + 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, + 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, + 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, + 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, + 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, + 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, + 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, + 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, + // Block 0xa, offset 0x280 + 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, + 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, + 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, + 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, + 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, + 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, + 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, + 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe4, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, + 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, + 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe5, 0x2d3: 0xe6, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, + 0x2d8: 0xe7, 0x2d9: 0x41, 0x2da: 0x42, 0x2db: 0xe8, 0x2dc: 0x43, 0x2dd: 0x44, 0x2de: 0x45, 0x2df: 0xe9, + 0x2e0: 0xea, 0x2e1: 0xeb, 0x2e2: 0xec, 0x2e3: 0xed, 0x2e4: 0xee, 0x2e5: 0xef, 0x2e6: 0xf0, 0x2e7: 0xf1, + 0x2e8: 0xf2, 0x2e9: 0xf3, 0x2ea: 0xf4, 0x2eb: 0xf5, 0x2ec: 0xf6, 0x2ed: 0xf7, 0x2ee: 0xf8, 0x2ef: 0xf9, + 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, + 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, + // Block 0xc, offset 0x300 + 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, + 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, + 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, + 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xfa, 0x31f: 0xfb, + // Block 0xd, offset 0x340 + 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, + 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, + 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, + 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, + 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, + 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, + 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, + 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, + // Block 0xe, offset 0x380 + 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, + 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, + 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, + 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, + 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfc, 0x3a5: 0xfd, 0x3a6: 0xfe, 0x3a7: 0xff, + 0x3a8: 0x46, 0x3a9: 0x100, 0x3aa: 0x101, 0x3ab: 0x47, 0x3ac: 0x48, 0x3ad: 0x49, 0x3ae: 0x4a, 0x3af: 0x4b, + 0x3b0: 0x102, 0x3b1: 0x4c, 0x3b2: 0x4d, 0x3b3: 0x4e, 0x3b4: 0x4f, 0x3b5: 0x50, 0x3b6: 0x103, 0x3b7: 0x51, + 0x3b8: 0x52, 0x3b9: 0x53, 0x3ba: 0x54, 0x3bb: 0x55, 0x3bc: 0x56, 0x3bd: 0x57, 0x3be: 0x58, 0x3bf: 0x59, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x104, 0x3c1: 0x105, 0x3c2: 0x9f, 0x3c3: 0x106, 0x3c4: 0x107, 0x3c5: 0x9b, 0x3c6: 0x108, 0x3c7: 0x109, + 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x10a, 0x3cb: 0x10b, 0x3cc: 0x10c, 0x3cd: 0x10d, 0x3ce: 0x10e, 0x3cf: 0x10f, + 0x3d0: 0x110, 0x3d1: 0x9f, 0x3d2: 0x111, 0x3d3: 0x112, 0x3d4: 0x113, 0x3d5: 0x114, 0x3d6: 0xba, 0x3d7: 0xba, + 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x115, 0x3dd: 0x116, 0x3de: 0xba, 0x3df: 0xba, + 0x3e0: 0x117, 0x3e1: 0x118, 0x3e2: 0x119, 0x3e3: 0x11a, 0x3e4: 0x11b, 0x3e5: 0xba, 0x3e6: 0x11c, 0x3e7: 0x11d, + 0x3e8: 0x11e, 0x3e9: 0x11f, 0x3ea: 0x120, 0x3eb: 0x5a, 0x3ec: 0x121, 0x3ed: 0x122, 0x3ee: 0x5b, 0x3ef: 0xba, + 0x3f0: 0x123, 0x3f1: 0x124, 0x3f2: 0x125, 0x3f3: 0x126, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, + 0x3f8: 0xba, 0x3f9: 0x127, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba, + // Block 0x10, offset 0x400 + 0x400: 0x128, 0x401: 0x129, 0x402: 0x12a, 0x403: 0x12b, 0x404: 0x12c, 0x405: 0x12d, 0x406: 0x12e, 0x407: 0x12f, + 0x408: 0x130, 0x409: 0xba, 0x40a: 0x131, 0x40b: 0x132, 0x40c: 0x5c, 0x40d: 0x5d, 0x40e: 0xba, 0x40f: 0xba, + 0x410: 0x133, 0x411: 0x134, 0x412: 0x135, 0x413: 0x136, 0x414: 0xba, 0x415: 0xba, 0x416: 0x137, 0x417: 0x138, + 0x418: 0x139, 0x419: 0x13a, 0x41a: 0x13b, 0x41b: 0x13c, 0x41c: 0x13d, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, + 0x420: 0xba, 0x421: 0xba, 0x422: 0x13e, 0x423: 0x13f, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba, + 0x428: 0xba, 0x429: 0xba, 0x42a: 0xba, 0x42b: 0x140, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, + 0x430: 0x141, 0x431: 0x142, 0x432: 0x143, 0x433: 0xba, 0x434: 0xba, 0x435: 0xba, 0x436: 0xba, 0x437: 0xba, + 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba, + // Block 0x11, offset 0x440 + 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, + 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x144, 0x44f: 0xba, + 0x450: 0x9b, 0x451: 0x145, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x146, 0x456: 0xba, 0x457: 0xba, + 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, + 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, + 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, + 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, + 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, + // Block 0x12, offset 0x480 + 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, + 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, + 0x490: 0x147, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, + 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, + 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, + 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, + 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, + 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, + // Block 0x13, offset 0x4c0 + 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, + 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, + 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, + 0x4d8: 0x9f, 0x4d9: 0x148, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, + 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, + 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, + 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, + 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, + // Block 0x14, offset 0x500 + 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, + 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, + 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, + 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, + 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, + 0x528: 0x140, 0x529: 0x149, 0x52a: 0xba, 0x52b: 0x14a, 0x52c: 0x14b, 0x52d: 0x14c, 0x52e: 0x14d, 0x52f: 0xba, + 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, + 0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x14e, 0x53e: 0x14f, 0x53f: 0x150, + // Block 0x15, offset 0x540 + 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, + 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, + 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, + 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x151, + 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, + 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x152, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, + 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, + 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, + // Block 0x16, offset 0x580 + 0x580: 0x153, 0x581: 0xba, 0x582: 0xba, 0x583: 0xba, 0x584: 0xba, 0x585: 0xba, 0x586: 0xba, 0x587: 0xba, + 0x588: 0xba, 0x589: 0xba, 0x58a: 0xba, 0x58b: 0xba, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, + 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, + 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, + 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, + 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, + 0x5b0: 0x9f, 0x5b1: 0x154, 0x5b2: 0x155, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, + 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x156, 0x5c4: 0x157, 0x5c5: 0x158, 0x5c6: 0x159, 0x5c7: 0x15a, + 0x5c8: 0x9b, 0x5c9: 0x15b, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x15c, 0x5ce: 0xba, 0x5cf: 0xba, + 0x5d0: 0x5e, 0x5d1: 0x5f, 0x5d2: 0x60, 0x5d3: 0x61, 0x5d4: 0x62, 0x5d5: 0x63, 0x5d6: 0x64, 0x5d7: 0x65, + 0x5d8: 0x66, 0x5d9: 0x67, 0x5da: 0x68, 0x5db: 0x69, 0x5dc: 0x6a, 0x5dd: 0x6b, 0x5de: 0x6c, 0x5df: 0x6d, + 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, + 0x5e8: 0x15d, 0x5e9: 0x15e, 0x5ea: 0x15f, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, + 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, + 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, + // Block 0x18, offset 0x600 + 0x600: 0x160, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba, + 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, + 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, + 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, + 0x620: 0x123, 0x621: 0x123, 0x622: 0x123, 0x623: 0x161, 0x624: 0x6e, 0x625: 0x162, 0x626: 0xba, 0x627: 0xba, + 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, + 0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, + 0x638: 0x6f, 0x639: 0x70, 0x63a: 0x71, 0x63b: 0x163, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, + // Block 0x19, offset 0x640 + 0x640: 0x164, 0x641: 0x9b, 0x642: 0x165, 0x643: 0x166, 0x644: 0x72, 0x645: 0x73, 0x646: 0x167, 0x647: 0x168, + 0x648: 0x74, 0x649: 0x169, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, + 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, + 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x16a, 0x65c: 0x9b, 0x65d: 0x16b, 0x65e: 0x9b, 0x65f: 0x16c, + 0x660: 0x16d, 0x661: 0x16e, 0x662: 0x16f, 0x663: 0xba, 0x664: 0x170, 0x665: 0x171, 0x666: 0x172, 0x667: 0x173, + 0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, + 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, + 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, + // Block 0x1a, offset 0x680 + 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, + 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, + 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, + 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x174, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, + 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, + 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, + 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, + 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, + 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, + 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, + 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x175, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, + 0x6e0: 0x176, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, + 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, + 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, + 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, + // Block 0x1c, offset 0x700 + 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, + 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, + 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, + 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, + 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, + 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, + 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, + 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x177, 0x73b: 0xba, 0x73c: 0xba, 0x73d: 0xba, 0x73e: 0xba, 0x73f: 0xba, + // Block 0x1d, offset 0x740 + 0x740: 0xba, 0x741: 0xba, 0x742: 0xba, 0x743: 0xba, 0x744: 0xba, 0x745: 0xba, 0x746: 0xba, 0x747: 0xba, + 0x748: 0xba, 0x749: 0xba, 0x74a: 0xba, 0x74b: 0xba, 0x74c: 0xba, 0x74d: 0xba, 0x74e: 0xba, 0x74f: 0xba, + 0x750: 0xba, 0x751: 0xba, 0x752: 0xba, 0x753: 0xba, 0x754: 0xba, 0x755: 0xba, 0x756: 0xba, 0x757: 0xba, + 0x758: 0xba, 0x759: 0xba, 0x75a: 0xba, 0x75b: 0xba, 0x75c: 0xba, 0x75d: 0xba, 0x75e: 0xba, 0x75f: 0xba, + 0x760: 0x75, 0x761: 0x76, 0x762: 0x77, 0x763: 0x178, 0x764: 0x78, 0x765: 0x79, 0x766: 0x179, 0x767: 0x7a, + 0x768: 0x7b, 0x769: 0xba, 0x76a: 0xba, 0x76b: 0xba, 0x76c: 0xba, 0x76d: 0xba, 0x76e: 0xba, 0x76f: 0xba, + 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, + 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, + // Block 0x1e, offset 0x780 + 0x790: 0x0d, 0x791: 0x0e, 0x792: 0x0f, 0x793: 0x10, 0x794: 0x11, 0x795: 0x0b, 0x796: 0x12, 0x797: 0x07, + 0x798: 0x13, 0x799: 0x0b, 0x79a: 0x0b, 0x79b: 0x14, 0x79c: 0x0b, 0x79d: 0x15, 0x79e: 0x16, 0x79f: 0x17, + 0x7a0: 0x07, 0x7a1: 0x07, 0x7a2: 0x07, 0x7a3: 0x07, 0x7a4: 0x07, 0x7a5: 0x07, 0x7a6: 0x07, 0x7a7: 0x07, + 0x7a8: 0x07, 0x7a9: 0x07, 0x7aa: 0x18, 0x7ab: 0x19, 0x7ac: 0x1a, 0x7ad: 0x0b, 0x7ae: 0x0b, 0x7af: 0x1b, + 0x7b0: 0x0b, 0x7b1: 0x0b, 0x7b2: 0x0b, 0x7b3: 0x0b, 0x7b4: 0x0b, 0x7b5: 0x0b, 0x7b6: 0x0b, 0x7b7: 0x0b, + 0x7b8: 0x0b, 0x7b9: 0x0b, 0x7ba: 0x0b, 0x7bb: 0x0b, 0x7bc: 0x0b, 0x7bd: 0x0b, 0x7be: 0x0b, 0x7bf: 0x0b, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x0b, 0x7c1: 0x0b, 0x7c2: 0x0b, 0x7c3: 0x0b, 0x7c4: 0x0b, 0x7c5: 0x0b, 0x7c6: 0x0b, 0x7c7: 0x0b, + 0x7c8: 0x0b, 0x7c9: 0x0b, 0x7ca: 0x0b, 0x7cb: 0x0b, 0x7cc: 0x0b, 0x7cd: 0x0b, 0x7ce: 0x0b, 0x7cf: 0x0b, + 0x7d0: 0x0b, 0x7d1: 0x0b, 0x7d2: 0x0b, 0x7d3: 0x0b, 0x7d4: 0x0b, 0x7d5: 0x0b, 0x7d6: 0x0b, 0x7d7: 0x0b, + 0x7d8: 0x0b, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x0b, 0x7dc: 0x0b, 0x7dd: 0x0b, 0x7de: 0x0b, 0x7df: 0x0b, + 0x7e0: 0x0b, 0x7e1: 0x0b, 0x7e2: 0x0b, 0x7e3: 0x0b, 0x7e4: 0x0b, 0x7e5: 0x0b, 0x7e6: 0x0b, 0x7e7: 0x0b, + 0x7e8: 0x0b, 0x7e9: 0x0b, 0x7ea: 0x0b, 0x7eb: 0x0b, 0x7ec: 0x0b, 0x7ed: 0x0b, 0x7ee: 0x0b, 0x7ef: 0x0b, + 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, + 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, + // Block 0x20, offset 0x800 + 0x800: 0x17a, 0x801: 0x17b, 0x802: 0xba, 0x803: 0xba, 0x804: 0x17c, 0x805: 0x17c, 0x806: 0x17c, 0x807: 0x17d, + 0x808: 0xba, 0x809: 0xba, 0x80a: 0xba, 0x80b: 0xba, 0x80c: 0xba, 0x80d: 0xba, 0x80e: 0xba, 0x80f: 0xba, + 0x810: 0xba, 0x811: 0xba, 0x812: 0xba, 0x813: 0xba, 0x814: 0xba, 0x815: 0xba, 0x816: 0xba, 0x817: 0xba, + 0x818: 0xba, 0x819: 0xba, 0x81a: 0xba, 0x81b: 0xba, 0x81c: 0xba, 0x81d: 0xba, 0x81e: 0xba, 0x81f: 0xba, + 0x820: 0xba, 0x821: 0xba, 0x822: 0xba, 0x823: 0xba, 0x824: 0xba, 0x825: 0xba, 0x826: 0xba, 0x827: 0xba, + 0x828: 0xba, 0x829: 0xba, 0x82a: 0xba, 0x82b: 0xba, 0x82c: 0xba, 0x82d: 0xba, 0x82e: 0xba, 0x82f: 0xba, + 0x830: 0xba, 0x831: 0xba, 0x832: 0xba, 0x833: 0xba, 0x834: 0xba, 0x835: 0xba, 0x836: 0xba, 0x837: 0xba, + 0x838: 0xba, 0x839: 0xba, 0x83a: 0xba, 0x83b: 0xba, 0x83c: 0xba, 0x83d: 0xba, 0x83e: 0xba, 0x83f: 0xba, + // Block 0x21, offset 0x840 + 0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b, + 0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b, + 0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b, + 0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b, + 0x860: 0x1e, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b, + 0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b, + 0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b, + 0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b, + // Block 0x22, offset 0x880 + 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, + 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, +} + +// idnaSparseOffset: 258 entries, 516 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x93, 0x98, 0xa1, 0xb1, 0xbf, 0xcc, 0xd8, 0xe9, 0xf3, 0xfa, 0x107, 0x118, 0x11f, 0x12a, 0x139, 0x147, 0x151, 0x153, 0x158, 0x15b, 0x15e, 0x160, 0x16c, 0x177, 0x17f, 0x185, 0x18b, 0x190, 0x195, 0x198, 0x19c, 0x1a2, 0x1a7, 0x1b3, 0x1bd, 0x1c3, 0x1d4, 0x1de, 0x1e1, 0x1e9, 0x1ec, 0x1f9, 0x201, 0x205, 0x20c, 0x214, 0x224, 0x230, 0x232, 0x23c, 0x248, 0x254, 0x260, 0x268, 0x26d, 0x277, 0x288, 0x28c, 0x297, 0x29b, 0x2a4, 0x2ac, 0x2b2, 0x2b7, 0x2ba, 0x2bd, 0x2c1, 0x2c7, 0x2cb, 0x2cf, 0x2d5, 0x2dc, 0x2e2, 0x2ea, 0x2f1, 0x2fc, 0x306, 0x30a, 0x30d, 0x313, 0x317, 0x319, 0x31c, 0x31e, 0x321, 0x32b, 0x32e, 0x33d, 0x341, 0x346, 0x349, 0x34d, 0x352, 0x357, 0x35d, 0x363, 0x372, 0x378, 0x37c, 0x38b, 0x390, 0x398, 0x3a2, 0x3ad, 0x3b5, 0x3c6, 0x3cf, 0x3df, 0x3ec, 0x3f6, 0x3fb, 0x408, 0x40c, 0x411, 0x413, 0x417, 0x419, 0x41d, 0x426, 0x42c, 0x430, 0x440, 0x44a, 0x44f, 0x452, 0x458, 0x45f, 0x464, 0x468, 0x46e, 0x473, 0x47c, 0x481, 0x487, 0x48e, 0x495, 0x49c, 0x4a0, 0x4a5, 0x4a8, 0x4ad, 0x4b9, 0x4bf, 0x4c4, 0x4cb, 0x4d3, 0x4d8, 0x4dc, 0x4ec, 0x4f3, 0x4f7, 0x4fb, 0x502, 0x504, 0x507, 0x50a, 0x50e, 0x512, 0x518, 0x521, 0x52d, 0x534, 0x53d, 0x545, 0x54c, 0x55a, 0x567, 0x574, 0x57d, 0x581, 0x58f, 0x597, 0x5a2, 0x5ab, 0x5b1, 0x5b9, 0x5c2, 0x5cc, 0x5cf, 0x5db, 0x5de, 0x5e3, 0x5e6, 0x5f0, 0x5f9, 0x605, 0x608, 0x60d, 0x610, 0x613, 0x616, 0x61d, 0x624, 0x628, 0x633, 0x636, 0x63c, 0x641, 0x645, 0x648, 0x64b, 0x64e, 0x653, 0x65d, 0x660, 0x664, 0x673, 0x67f, 0x683, 0x688, 0x68d, 0x691, 0x696, 0x69f, 0x6aa, 0x6b0, 0x6b8, 0x6bc, 0x6c0, 0x6c6, 0x6cc, 0x6d1, 0x6d4, 0x6e2, 0x6e9, 0x6ec, 0x6ef, 0x6f3, 0x6f9, 0x6fe, 0x708, 0x70d, 0x710, 0x713, 0x716, 0x719, 0x71d, 0x720, 0x730, 0x741, 0x746, 0x748, 0x74a} + +// idnaSparseValues: 1869 entries, 7476 bytes +var idnaSparseValues = [1869]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x07}, + {value: 0xe105, lo: 0x80, hi: 0x96}, + {value: 0x0018, lo: 0x97, hi: 0x97}, + {value: 0xe105, lo: 0x98, hi: 0x9e}, + {value: 0x001f, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbf}, + // Block 0x1, offset 0x8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0xe01d, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0335, lo: 0x83, hi: 0x83}, + {value: 0x034d, lo: 0x84, hi: 0x84}, + {value: 0x0365, lo: 0x85, hi: 0x85}, + {value: 0xe00d, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0xe00d, lo: 0x88, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x89}, + {value: 0xe00d, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe00d, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0x8d}, + {value: 0xe00d, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0xbf}, + // Block 0x2, offset 0x19 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0249, lo: 0xb0, hi: 0xb0}, + {value: 0x037d, lo: 0xb1, hi: 0xb1}, + {value: 0x0259, lo: 0xb2, hi: 0xb2}, + {value: 0x0269, lo: 0xb3, hi: 0xb3}, + {value: 0x034d, lo: 0xb4, hi: 0xb4}, + {value: 0x0395, lo: 0xb5, hi: 0xb5}, + {value: 0xe1bd, lo: 0xb6, hi: 0xb6}, + {value: 0x0279, lo: 0xb7, hi: 0xb7}, + {value: 0x0289, lo: 0xb8, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbf}, + // Block 0x3, offset 0x25 + {value: 0x0000, lo: 0x01}, + {value: 0x3308, lo: 0x80, hi: 0xbf}, + // Block 0x4, offset 0x27 + {value: 0x0000, lo: 0x04}, + {value: 0x03f5, lo: 0x80, hi: 0x8f}, + {value: 0xe105, lo: 0x90, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x5, offset 0x2c + {value: 0x0000, lo: 0x07}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x0545, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x0008, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x6, offset 0x34 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0401, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x88}, + {value: 0x0018, lo: 0x89, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x7, offset 0x3f + {value: 0x0000, lo: 0x0b}, + {value: 0x0818, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x82}, + {value: 0x0818, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x85}, + {value: 0x0818, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0808, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x8, offset 0x4b + {value: 0x0000, lo: 0x03}, + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0c08, lo: 0x88, hi: 0x99}, + {value: 0x0a08, lo: 0x9a, hi: 0xbf}, + // Block 0x9, offset 0x4f + {value: 0x0000, lo: 0x0e}, + {value: 0x3308, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0c08, lo: 0x8d, hi: 0x8d}, + {value: 0x0a08, lo: 0x8e, hi: 0x98}, + {value: 0x0c08, lo: 0x99, hi: 0x9b}, + {value: 0x0a08, lo: 0x9c, hi: 0xaa}, + {value: 0x0c08, lo: 0xab, hi: 0xac}, + {value: 0x0a08, lo: 0xad, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xb5, hi: 0xb7}, + {value: 0x0c08, lo: 0xb8, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbf}, + // Block 0xa, offset 0x5e + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xb, offset 0x63 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0xc, offset 0x6b + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x99}, + {value: 0x0808, lo: 0x9a, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa3}, + {value: 0x0808, lo: 0xa4, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa7}, + {value: 0x0808, lo: 0xa8, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0818, lo: 0xb0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd, offset 0x77 + {value: 0x0000, lo: 0x0d}, + {value: 0x0c08, lo: 0x80, hi: 0x80}, + {value: 0x0a08, lo: 0x81, hi: 0x85}, + {value: 0x0c08, lo: 0x86, hi: 0x87}, + {value: 0x0a08, lo: 0x88, hi: 0x88}, + {value: 0x0c08, lo: 0x89, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0x93}, + {value: 0x0c08, lo: 0x94, hi: 0x94}, + {value: 0x0a08, lo: 0x95, hi: 0x95}, + {value: 0x0808, lo: 0x96, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xe, offset 0x85 + {value: 0x0000, lo: 0x0d}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0a08, lo: 0xa0, hi: 0xa9}, + {value: 0x0c08, lo: 0xaa, hi: 0xac}, + {value: 0x0808, lo: 0xad, hi: 0xad}, + {value: 0x0c08, lo: 0xae, hi: 0xae}, + {value: 0x0a08, lo: 0xaf, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb2}, + {value: 0x0a08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0a08, lo: 0xb6, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xf, offset 0x93 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa1}, + {value: 0x0840, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xbf}, + // Block 0x10, offset 0x98 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x11, offset 0xa1 + {value: 0x0000, lo: 0x0f}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x85}, + {value: 0x3008, lo: 0x86, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8c}, + {value: 0x3b08, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x12, offset 0xb1 + {value: 0x0000, lo: 0x0d}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x13, offset 0xbf + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x14, offset 0xcc + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x15, offset 0xd8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x89}, + {value: 0x3b08, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x3008, lo: 0x98, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x16, offset 0xe9 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb2}, + {value: 0x08f1, lo: 0xb3, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb9}, + {value: 0x3b08, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0x17, offset 0xf3 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x8e}, + {value: 0x0018, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0xbf}, + // Block 0x18, offset 0xfa + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0961, lo: 0x9c, hi: 0x9c}, + {value: 0x0999, lo: 0x9d, hi: 0x9d}, + {value: 0x0008, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x19, offset 0x107 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe03d, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x1a, offset 0x118 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0x1b, offset 0x11f + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x1c, offset 0x12a + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xa1}, + {value: 0x3008, lo: 0xa2, hi: 0xa4}, + {value: 0x0008, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xbf}, + // Block 0x1d, offset 0x139 + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x8c}, + {value: 0x3308, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x3008, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x1e, offset 0x147 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x86}, + {value: 0x055d, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8c}, + {value: 0x055d, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0xe105, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0x1f, offset 0x151 + {value: 0x0000, lo: 0x01}, + {value: 0x0018, lo: 0x80, hi: 0xbf}, + // Block 0x20, offset 0x153 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa0}, + {value: 0x2018, lo: 0xa1, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x21, offset 0x158 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa7}, + {value: 0x2018, lo: 0xa8, hi: 0xbf}, + // Block 0x22, offset 0x15b + {value: 0x0000, lo: 0x02}, + {value: 0x2018, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0xbf}, + // Block 0x23, offset 0x15e + {value: 0x0000, lo: 0x01}, + {value: 0x0008, lo: 0x80, hi: 0xbf}, + // Block 0x24, offset 0x160 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x25, offset 0x16c + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x26, offset 0x177 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x27, offset 0x17f + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x28, offset 0x185 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x29, offset 0x18b + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2a, offset 0x190 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x2b, offset 0x195 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x2c, offset 0x198 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xbf}, + // Block 0x2d, offset 0x19c + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2e, offset 0x1a2 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x2f, offset 0x1a7 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x3b08, lo: 0x94, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x30, offset 0x1b3 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x31, offset 0x1bd + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xb3}, + {value: 0x3340, lo: 0xb4, hi: 0xb5}, + {value: 0x3008, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x32, offset 0x1c3 + {value: 0x0000, lo: 0x10}, + {value: 0x3008, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x91}, + {value: 0x3b08, lo: 0x92, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0x93}, + {value: 0x0018, lo: 0x94, hi: 0x96}, + {value: 0x0008, lo: 0x97, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x33, offset 0x1d4 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x86}, + {value: 0x0218, lo: 0x87, hi: 0x87}, + {value: 0x0018, lo: 0x88, hi: 0x8a}, + {value: 0x33c0, lo: 0x8b, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0208, lo: 0xa0, hi: 0xbf}, + // Block 0x34, offset 0x1de + {value: 0x0000, lo: 0x02}, + {value: 0x0208, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x35, offset 0x1e1 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0208, lo: 0x87, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xa9}, + {value: 0x0208, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x36, offset 0x1e9 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0x37, offset 0x1ec + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x38, offset 0x1f9 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x39, offset 0x201 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x3a, offset 0x205 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0028, lo: 0x9a, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xbf}, + // Block 0x3b, offset 0x20c + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x3308, lo: 0x97, hi: 0x98}, + {value: 0x3008, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x3c, offset 0x214 + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x94}, + {value: 0x3008, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xac}, + {value: 0x3008, lo: 0xad, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x224 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xbd}, + {value: 0x3318, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x3e, offset 0x230 + {value: 0x0000, lo: 0x01}, + {value: 0x0040, lo: 0x80, hi: 0xbf}, + // Block 0x3f, offset 0x232 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3008, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x40, offset 0x23c + {value: 0x0000, lo: 0x0b}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x3808, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x41, offset 0x248 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3808, lo: 0xaa, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xbf}, + // Block 0x42, offset 0x254 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3008, lo: 0xaa, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3808, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x43, offset 0x260 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x3008, lo: 0xa4, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbf}, + // Block 0x44, offset 0x268 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x45, offset 0x26d + {value: 0x0000, lo: 0x09}, + {value: 0x0e29, lo: 0x80, hi: 0x80}, + {value: 0x0e41, lo: 0x81, hi: 0x81}, + {value: 0x0e59, lo: 0x82, hi: 0x82}, + {value: 0x0e71, lo: 0x83, hi: 0x83}, + {value: 0x0e89, lo: 0x84, hi: 0x85}, + {value: 0x0ea1, lo: 0x86, hi: 0x86}, + {value: 0x0eb9, lo: 0x87, hi: 0x87}, + {value: 0x057d, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0x46, offset 0x277 + {value: 0x0000, lo: 0x10}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x92}, + {value: 0x0018, lo: 0x93, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa8}, + {value: 0x0008, lo: 0xa9, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x47, offset 0x288 + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0x48, offset 0x28c + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x87}, + {value: 0xe045, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0xe045, lo: 0x98, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0xe045, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbf}, + // Block 0x49, offset 0x297 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x3318, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbf}, + // Block 0x4a, offset 0x29b + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x24c1, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x4b, offset 0x2a4 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x24f1, lo: 0xac, hi: 0xac}, + {value: 0x2529, lo: 0xad, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xae}, + {value: 0x2579, lo: 0xaf, hi: 0xaf}, + {value: 0x25b1, lo: 0xb0, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0x4c, offset 0x2ac + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x9f}, + {value: 0x0080, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xad}, + {value: 0x0080, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x4d, offset 0x2b2 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa8}, + {value: 0x09c5, lo: 0xa9, hi: 0xa9}, + {value: 0x09e5, lo: 0xaa, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xbf}, + // Block 0x4e, offset 0x2b7 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x4f, offset 0x2ba + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0x50, offset 0x2bd + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x28c1, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x51, offset 0x2c1 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0e66, lo: 0xb4, hi: 0xb4}, + {value: 0x292a, lo: 0xb5, hi: 0xb5}, + {value: 0x0e86, lo: 0xb6, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x52, offset 0x2c7 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x9b}, + {value: 0x2941, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0xbf}, + // Block 0x53, offset 0x2cb + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x54, offset 0x2cf + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0018, lo: 0xbd, hi: 0xbf}, + // Block 0x55, offset 0x2d5 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0xab}, + {value: 0x0018, lo: 0xac, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x56, offset 0x2dc + {value: 0x0000, lo: 0x05}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x03f5, lo: 0x90, hi: 0x9f}, + {value: 0x0ea5, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x57, offset 0x2e2 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x58, offset 0x2ea + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xae}, + {value: 0xe075, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0x59, offset 0x2f1 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x5a, offset 0x2fc + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xbf}, + // Block 0x5b, offset 0x306 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x5c, offset 0x30a + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0xbf}, + // Block 0x5d, offset 0x30d + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9e}, + {value: 0x0edd, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x5e, offset 0x313 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb2}, + {value: 0x0efd, lo: 0xb3, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x5f, offset 0x317 + {value: 0x0020, lo: 0x01}, + {value: 0x0f1d, lo: 0x80, hi: 0xbf}, + // Block 0x60, offset 0x319 + {value: 0x0020, lo: 0x02}, + {value: 0x171d, lo: 0x80, hi: 0x8f}, + {value: 0x18fd, lo: 0x90, hi: 0xbf}, + // Block 0x61, offset 0x31c + {value: 0x0020, lo: 0x01}, + {value: 0x1efd, lo: 0x80, hi: 0xbf}, + // Block 0x62, offset 0x31e + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x63, offset 0x321 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9a}, + {value: 0x29e2, lo: 0x9b, hi: 0x9b}, + {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9e}, + {value: 0x2a31, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x64, offset 0x32b + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbe}, + {value: 0x2a69, lo: 0xbf, hi: 0xbf}, + // Block 0x65, offset 0x32e + {value: 0x0000, lo: 0x0e}, + {value: 0x0040, lo: 0x80, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xb0}, + {value: 0x2a1d, lo: 0xb1, hi: 0xb1}, + {value: 0x2a3d, lo: 0xb2, hi: 0xb2}, + {value: 0x2a5d, lo: 0xb3, hi: 0xb3}, + {value: 0x2a7d, lo: 0xb4, hi: 0xb4}, + {value: 0x2a5d, lo: 0xb5, hi: 0xb5}, + {value: 0x2a9d, lo: 0xb6, hi: 0xb6}, + {value: 0x2abd, lo: 0xb7, hi: 0xb7}, + {value: 0x2add, lo: 0xb8, hi: 0xb9}, + {value: 0x2afd, lo: 0xba, hi: 0xbb}, + {value: 0x2b1d, lo: 0xbc, hi: 0xbd}, + {value: 0x2afd, lo: 0xbe, hi: 0xbf}, + // Block 0x66, offset 0x33d + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x67, offset 0x341 + {value: 0x0030, lo: 0x04}, + {value: 0x2aa2, lo: 0x80, hi: 0x9d}, + {value: 0x305a, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x30a2, lo: 0xa0, hi: 0xbf}, + // Block 0x68, offset 0x346 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x69, offset 0x349 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x6a, offset 0x34d + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x6b, offset 0x352 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0x6c, offset 0x357 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb1}, + {value: 0x0018, lo: 0xb2, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6d, offset 0x35d + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0xb6}, + {value: 0x0008, lo: 0xb7, hi: 0xb7}, + {value: 0x2009, lo: 0xb8, hi: 0xb8}, + {value: 0x6e89, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xbf}, + // Block 0x6e, offset 0x363 + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x3308, lo: 0x8b, hi: 0x8b}, + {value: 0x0008, lo: 0x8c, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x6f, offset 0x372 + {value: 0x0000, lo: 0x05}, + {value: 0x0208, lo: 0x80, hi: 0xb1}, + {value: 0x0108, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x70, offset 0x378 + {value: 0x0000, lo: 0x03}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xbf}, + // Block 0x71, offset 0x37c + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0008, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x72, offset 0x38b + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x73, offset 0x390 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x91}, + {value: 0x3008, lo: 0x92, hi: 0x92}, + {value: 0x3808, lo: 0x93, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x74, offset 0x398 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb9}, + {value: 0x3008, lo: 0xba, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x75, offset 0x3a2 + {value: 0x0000, lo: 0x0a}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x76, offset 0x3ad + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x77, offset 0x3b5 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8c}, + {value: 0x3008, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbd}, + {value: 0x0008, lo: 0xbe, hi: 0xbf}, + // Block 0x78, offset 0x3c6 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x79, offset 0x3cf + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x9a}, + {value: 0x0008, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3b08, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x7a, offset 0x3df + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x90}, + {value: 0x0008, lo: 0x91, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x7b, offset 0x3ec + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x4465, lo: 0x9c, hi: 0x9c}, + {value: 0x447d, lo: 0x9d, hi: 0x9d}, + {value: 0x2971, lo: 0x9e, hi: 0x9e}, + {value: 0xe06d, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xaf}, + {value: 0x4495, lo: 0xb0, hi: 0xbf}, + // Block 0x7c, offset 0x3f6 + {value: 0x0000, lo: 0x04}, + {value: 0x44b5, lo: 0x80, hi: 0x8f}, + {value: 0x44d5, lo: 0x90, hi: 0x9f}, + {value: 0x44f5, lo: 0xa0, hi: 0xaf}, + {value: 0x44d5, lo: 0xb0, hi: 0xbf}, + // Block 0x7d, offset 0x3fb + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3b08, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x7e, offset 0x408 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x7f, offset 0x40c + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x80, offset 0x411 + {value: 0x0020, lo: 0x01}, + {value: 0x4515, lo: 0x80, hi: 0xbf}, + // Block 0x81, offset 0x413 + {value: 0x0020, lo: 0x03}, + {value: 0x4d15, lo: 0x80, hi: 0x94}, + {value: 0x4ad5, lo: 0x95, hi: 0x95}, + {value: 0x4fb5, lo: 0x96, hi: 0xbf}, + // Block 0x82, offset 0x417 + {value: 0x0020, lo: 0x01}, + {value: 0x54f5, lo: 0x80, hi: 0xbf}, + // Block 0x83, offset 0x419 + {value: 0x0020, lo: 0x03}, + {value: 0x5cf5, lo: 0x80, hi: 0x84}, + {value: 0x5655, lo: 0x85, hi: 0x85}, + {value: 0x5d95, lo: 0x86, hi: 0xbf}, + // Block 0x84, offset 0x41d + {value: 0x0020, lo: 0x08}, + {value: 0x6b55, lo: 0x80, hi: 0x8f}, + {value: 0x6d15, lo: 0x90, hi: 0x90}, + {value: 0x6d55, lo: 0x91, hi: 0xab}, + {value: 0x6ea1, lo: 0xac, hi: 0xac}, + {value: 0x70b5, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x70d5, lo: 0xb0, hi: 0xbf}, + // Block 0x85, offset 0x426 + {value: 0x0020, lo: 0x05}, + {value: 0x72d5, lo: 0x80, hi: 0xad}, + {value: 0x6535, lo: 0xae, hi: 0xae}, + {value: 0x7895, lo: 0xaf, hi: 0xb5}, + {value: 0x6f55, lo: 0xb6, hi: 0xb6}, + {value: 0x7975, lo: 0xb7, hi: 0xbf}, + // Block 0x86, offset 0x42c + {value: 0x0028, lo: 0x03}, + {value: 0x7c21, lo: 0x80, hi: 0x82}, + {value: 0x7be1, lo: 0x83, hi: 0x83}, + {value: 0x7c99, lo: 0x84, hi: 0xbf}, + // Block 0x87, offset 0x430 + {value: 0x0038, lo: 0x0f}, + {value: 0x9db1, lo: 0x80, hi: 0x83}, + {value: 0x9e59, lo: 0x84, hi: 0x85}, + {value: 0x9e91, lo: 0x86, hi: 0x87}, + {value: 0x9ec9, lo: 0x88, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0xa089, lo: 0x92, hi: 0x97}, + {value: 0xa1a1, lo: 0x98, hi: 0x9c}, + {value: 0xa281, lo: 0x9d, hi: 0xb3}, + {value: 0x9d41, lo: 0xb4, hi: 0xb4}, + {value: 0x9db1, lo: 0xb5, hi: 0xb5}, + {value: 0xa789, lo: 0xb6, hi: 0xbb}, + {value: 0xa869, lo: 0xbc, hi: 0xbc}, + {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, + {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, + // Block 0x88, offset 0x440 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0008, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x89, offset 0x44a + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0x8a, offset 0x44f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x8b, offset 0x452 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x8c, offset 0x458 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x8d, offset 0x45f + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x8e, offset 0x464 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x8f, offset 0x468 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x90, offset 0x46e + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x91, offset 0x473 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x92, offset 0x47c + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x93, offset 0x481 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x94, offset 0x487 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x97}, + {value: 0x8ad5, lo: 0x98, hi: 0x9f}, + {value: 0x8aed, lo: 0xa0, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xbf}, + // Block 0x95, offset 0x48e + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x8aed, lo: 0xb0, hi: 0xb7}, + {value: 0x8ad5, lo: 0xb8, hi: 0xbf}, + // Block 0x96, offset 0x495 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x97, offset 0x49c + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x98, offset 0x4a0 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xae}, + {value: 0x0018, lo: 0xaf, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x99, offset 0x4a5 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x9a, offset 0x4a8 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xbf}, + // Block 0x9b, offset 0x4ad + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0808, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0808, lo: 0x8a, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb6}, + {value: 0x0808, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbb}, + {value: 0x0808, lo: 0xbc, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x0808, lo: 0xbf, hi: 0xbf}, + // Block 0x9c, offset 0x4b9 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x96}, + {value: 0x0818, lo: 0x97, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0818, lo: 0xb7, hi: 0xbf}, + // Block 0x9d, offset 0x4bf + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa6}, + {value: 0x0818, lo: 0xa7, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x9e, offset 0x4c4 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x0818, lo: 0xbb, hi: 0xbf}, + // Block 0x9f, offset 0x4cb + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0818, lo: 0x96, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbe}, + {value: 0x0818, lo: 0xbf, hi: 0xbf}, + // Block 0xa0, offset 0x4d3 + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbb}, + {value: 0x0818, lo: 0xbc, hi: 0xbd}, + {value: 0x0808, lo: 0xbe, hi: 0xbf}, + // Block 0xa1, offset 0x4d8 + {value: 0x0000, lo: 0x03}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0xa2, offset 0x4dc + {value: 0x0000, lo: 0x0f}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x94}, + {value: 0x0808, lo: 0x95, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x98}, + {value: 0x0808, lo: 0x99, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xa3, offset 0x4ec + {value: 0x0000, lo: 0x06}, + {value: 0x0818, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0818, lo: 0x90, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xbc}, + {value: 0x0818, lo: 0xbd, hi: 0xbf}, + // Block 0xa4, offset 0x4f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xa5, offset 0x4f7 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb8}, + {value: 0x0018, lo: 0xb9, hi: 0xbf}, + // Block 0xa6, offset 0x4fb + {value: 0x0000, lo: 0x06}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0818, lo: 0x98, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb7}, + {value: 0x0818, lo: 0xb8, hi: 0xbf}, + // Block 0xa7, offset 0x502 + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa8, offset 0x504 + {value: 0x0000, lo: 0x02}, + {value: 0x0808, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xa9, offset 0x507 + {value: 0x0000, lo: 0x02}, + {value: 0x03dd, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xaa, offset 0x50a + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xab, offset 0x50e + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xac, offset 0x512 + {value: 0x0000, lo: 0x05}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xad, offset 0x518 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x91}, + {value: 0x0018, lo: 0x92, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xae, offset 0x521 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbc}, + {value: 0x0340, lo: 0xbd, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0xaf, offset 0x52d + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb0, offset 0x534 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb2}, + {value: 0x3b08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xbf}, + // Block 0xb1, offset 0x53d + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xb2, offset 0x545 + {value: 0x0000, lo: 0x06}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xbe}, + {value: 0x3008, lo: 0xbf, hi: 0xbf}, + // Block 0xb3, offset 0x54c + {value: 0x0000, lo: 0x0d}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xb4, offset 0x55a + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3808, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xb5, offset 0x567 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0008, lo: 0x9f, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xb6, offset 0x574 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x3308, lo: 0x9f, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa9}, + {value: 0x3b08, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb7, offset 0x57d + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xb8, offset 0x581 + {value: 0x0000, lo: 0x0d}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xb9, offset 0x58f + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xba, offset 0x597 + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x85}, + {value: 0x0018, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xbb, offset 0x5a2 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbc, offset 0x5ab + {value: 0x0000, lo: 0x05}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9b}, + {value: 0x3308, lo: 0x9c, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xbd, offset 0x5b1 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbe, offset 0x5b9 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xbf, offset 0x5c2 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb5}, + {value: 0x3808, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0xc0, offset 0x5cc + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0xc1, offset 0x5cf + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0xc2, offset 0x5db + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xbf}, + // Block 0xc3, offset 0x5de + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0xc4, offset 0x5e3 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xc5, offset 0x5e6 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xc6, offset 0x5f0 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xbf}, + // Block 0xc7, offset 0x5f9 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xaa, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xc8, offset 0x605 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xc9, offset 0x608 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xca, offset 0x60d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0xbf}, + // Block 0xcb, offset 0x610 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xbf}, + // Block 0xcc, offset 0x613 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xbf}, + // Block 0xcd, offset 0x616 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xce, offset 0x61d + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xcf, offset 0x624 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0xd0, offset 0x628 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0xd1, offset 0x633 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xd2, offset 0x636 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3008, lo: 0x91, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd3, offset 0x63c + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xd4, offset 0x641 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0xd5, offset 0x645 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xd6, offset 0x648 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xd7, offset 0x64b + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0xbf}, + // Block 0xd8, offset 0x64e + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0xd9, offset 0x653 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x03c0, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xbf}, + // Block 0xda, offset 0x65d + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xdb, offset 0x660 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xbf}, + // Block 0xdc, offset 0x664 + {value: 0x0000, lo: 0x0e}, + {value: 0x0018, lo: 0x80, hi: 0x9d}, + {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, + {value: 0xb601, lo: 0x9f, hi: 0x9f}, + {value: 0xb649, lo: 0xa0, hi: 0xa0}, + {value: 0xb6b1, lo: 0xa1, hi: 0xa1}, + {value: 0xb719, lo: 0xa2, hi: 0xa2}, + {value: 0xb781, lo: 0xa3, hi: 0xa3}, + {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, + {value: 0x3018, lo: 0xa5, hi: 0xa6}, + {value: 0x3318, lo: 0xa7, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xac}, + {value: 0x3018, lo: 0xad, hi: 0xb2}, + {value: 0x0340, lo: 0xb3, hi: 0xba}, + {value: 0x3318, lo: 0xbb, hi: 0xbf}, + // Block 0xdd, offset 0x673 + {value: 0x0000, lo: 0x0b}, + {value: 0x3318, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0x84}, + {value: 0x3318, lo: 0x85, hi: 0x8b}, + {value: 0x0018, lo: 0x8c, hi: 0xa9}, + {value: 0x3318, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xba}, + {value: 0xb851, lo: 0xbb, hi: 0xbb}, + {value: 0xb899, lo: 0xbc, hi: 0xbc}, + {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, + {value: 0xb949, lo: 0xbe, hi: 0xbe}, + {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, + // Block 0xde, offset 0x67f + {value: 0x0000, lo: 0x03}, + {value: 0xba19, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xbf}, + // Block 0xdf, offset 0x683 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x3318, lo: 0x82, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0xbf}, + // Block 0xe0, offset 0x688 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe1, offset 0x68d + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xe2, offset 0x691 + {value: 0x0000, lo: 0x04}, + {value: 0x3308, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0xe3, offset 0x696 + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x3308, lo: 0xa1, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xe4, offset 0x69f + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0xe5, offset 0x6aa + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x86}, + {value: 0x0818, lo: 0x87, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xe6, offset 0x6b0 + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xe7, offset 0x6b8 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe8, offset 0x6bc + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0xe9, offset 0x6c0 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0xea, offset 0x6c6 + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xeb, offset 0x6cc + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0xc1c1, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xec, offset 0x6d1 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xbf}, + // Block 0xed, offset 0x6d4 + {value: 0x0000, lo: 0x0d}, + {value: 0xc7e9, lo: 0x80, hi: 0x80}, + {value: 0xc839, lo: 0x81, hi: 0x81}, + {value: 0xc889, lo: 0x82, hi: 0x82}, + {value: 0xc8d9, lo: 0x83, hi: 0x83}, + {value: 0xc929, lo: 0x84, hi: 0x84}, + {value: 0xc979, lo: 0x85, hi: 0x85}, + {value: 0xc9c9, lo: 0x86, hi: 0x86}, + {value: 0xca19, lo: 0x87, hi: 0x87}, + {value: 0xca69, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0xcab9, lo: 0x90, hi: 0x90}, + {value: 0xcad9, lo: 0x91, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0xbf}, + // Block 0xee, offset 0x6e2 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x92}, + {value: 0x0040, lo: 0x93, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xef, offset 0x6e9 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0xf0, offset 0x6ec + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0xbf}, + // Block 0xf1, offset 0x6ef + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0xf2, offset 0x6f3 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0xf3, offset 0x6f9 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0xf4, offset 0x6fe + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb2}, + {value: 0x0018, lo: 0xb3, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xf5, offset 0x708 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xf6, offset 0x70d + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0xbf}, + // Block 0xf7, offset 0x710 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0xbf}, + // Block 0xf8, offset 0x713 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xf9, offset 0x716 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xfa, offset 0x719 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0xfb, offset 0x71d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xbf}, + // Block 0xfc, offset 0x720 + {value: 0x0020, lo: 0x0f}, + {value: 0xdeb9, lo: 0x80, hi: 0x89}, + {value: 0x8dfd, lo: 0x8a, hi: 0x8a}, + {value: 0xdff9, lo: 0x8b, hi: 0x9c}, + {value: 0x8e1d, lo: 0x9d, hi: 0x9d}, + {value: 0xe239, lo: 0x9e, hi: 0xa2}, + {value: 0x8e3d, lo: 0xa3, hi: 0xa3}, + {value: 0xe2d9, lo: 0xa4, hi: 0xab}, + {value: 0x7ed5, lo: 0xac, hi: 0xac}, + {value: 0xe3d9, lo: 0xad, hi: 0xaf}, + {value: 0x8e5d, lo: 0xb0, hi: 0xb0}, + {value: 0xe439, lo: 0xb1, hi: 0xb6}, + {value: 0x8e7d, lo: 0xb7, hi: 0xb9}, + {value: 0xe4f9, lo: 0xba, hi: 0xba}, + {value: 0x8edd, lo: 0xbb, hi: 0xbb}, + {value: 0xe519, lo: 0xbc, hi: 0xbf}, + // Block 0xfd, offset 0x730 + {value: 0x0020, lo: 0x10}, + {value: 0x937d, lo: 0x80, hi: 0x80}, + {value: 0xf099, lo: 0x81, hi: 0x86}, + {value: 0x939d, lo: 0x87, hi: 0x8a}, + {value: 0xd9f9, lo: 0x8b, hi: 0x8b}, + {value: 0xf159, lo: 0x8c, hi: 0x96}, + {value: 0x941d, lo: 0x97, hi: 0x97}, + {value: 0xf2b9, lo: 0x98, hi: 0xa3}, + {value: 0x943d, lo: 0xa4, hi: 0xa6}, + {value: 0xf439, lo: 0xa7, hi: 0xaa}, + {value: 0x949d, lo: 0xab, hi: 0xab}, + {value: 0xf4b9, lo: 0xac, hi: 0xac}, + {value: 0x94bd, lo: 0xad, hi: 0xad}, + {value: 0xf4d9, lo: 0xae, hi: 0xaf}, + {value: 0x94dd, lo: 0xb0, hi: 0xb1}, + {value: 0xf519, lo: 0xb2, hi: 0xbe}, + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0xfe, offset 0x741 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0340, lo: 0x81, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x9f}, + {value: 0x0340, lo: 0xa0, hi: 0xbf}, + // Block 0xff, offset 0x746 + {value: 0x0000, lo: 0x01}, + {value: 0x0340, lo: 0x80, hi: 0xbf}, + // Block 0x100, offset 0x748 + {value: 0x0000, lo: 0x01}, + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x101, offset 0x74a + {value: 0x0000, lo: 0x02}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, +} + +// Total table size 41662 bytes (40KiB); checksum: 355A58A4 diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr.go b/vendor/golang.org/x/net/internal/socket/cmsghdr.go index 1eb07d26d..0a73e277e 100644 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr.go +++ b/vendor/golang.org/x/net/internal/socket/cmsghdr.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package socket diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go index d1d0c2de5..14dbb3ad4 100644 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go +++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd netbsd openbsd +// +build aix darwin dragonfly freebsd netbsd openbsd package socket diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go index 63f0534fa..27be0efac 100644 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go +++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x +// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x // +build linux package socket diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go index a4e71226f..e581011b0 100644 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go +++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris package socket diff --git a/vendor/golang.org/x/net/internal/socket/defs_aix.go b/vendor/golang.org/x/net/internal/socket/defs_aix.go new file mode 100644 index 000000000..c9d05b261 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/defs_aix.go @@ -0,0 +1,39 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package socket + +/* +#include + +#include +*/ +import "C" + +type iovec C.struct_iovec + +type msghdr C.struct_msghdr + +type mmsghdr C.struct_mmsghdr + +type cmsghdr C.struct_cmsghdr + +type sockaddrInet C.struct_sockaddr_in + +type sockaddrInet6 C.struct_sockaddr_in6 + +const ( + sizeofIovec = C.sizeof_struct_iovec + sizeofMsghdr = C.sizeof_struct_msghdr + sizeofMmsghdr = C.sizeof_struct_mmsghdr + sizeofCmsghdr = C.sizeof_struct_cmsghdr + + sizeofSockaddrInet = C.sizeof_struct_sockaddr_in + sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 +) diff --git a/vendor/golang.org/x/net/internal/socket/defs_darwin.go b/vendor/golang.org/x/net/internal/socket/defs_darwin.go index 14e28c0b4..b780bc67a 100644 --- a/vendor/golang.org/x/net/internal/socket/defs_darwin.go +++ b/vendor/golang.org/x/net/internal/socket/defs_darwin.go @@ -16,14 +16,6 @@ package socket */ import "C" -const ( - sysAF_UNSPEC = C.AF_UNSPEC - sysAF_INET = C.AF_INET - sysAF_INET6 = C.AF_INET6 - - sysSOCK_RAW = C.SOCK_RAW -) - type iovec C.struct_iovec type msghdr C.struct_msghdr diff --git a/vendor/golang.org/x/net/internal/socket/defs_dragonfly.go b/vendor/golang.org/x/net/internal/socket/defs_dragonfly.go index 14e28c0b4..b780bc67a 100644 --- a/vendor/golang.org/x/net/internal/socket/defs_dragonfly.go +++ b/vendor/golang.org/x/net/internal/socket/defs_dragonfly.go @@ -16,14 +16,6 @@ package socket */ import "C" -const ( - sysAF_UNSPEC = C.AF_UNSPEC - sysAF_INET = C.AF_INET - sysAF_INET6 = C.AF_INET6 - - sysSOCK_RAW = C.SOCK_RAW -) - type iovec C.struct_iovec type msghdr C.struct_msghdr diff --git a/vendor/golang.org/x/net/internal/socket/defs_freebsd.go b/vendor/golang.org/x/net/internal/socket/defs_freebsd.go index 14e28c0b4..b780bc67a 100644 --- a/vendor/golang.org/x/net/internal/socket/defs_freebsd.go +++ b/vendor/golang.org/x/net/internal/socket/defs_freebsd.go @@ -16,14 +16,6 @@ package socket */ import "C" -const ( - sysAF_UNSPEC = C.AF_UNSPEC - sysAF_INET = C.AF_INET - sysAF_INET6 = C.AF_INET6 - - sysSOCK_RAW = C.SOCK_RAW -) - type iovec C.struct_iovec type msghdr C.struct_msghdr diff --git a/vendor/golang.org/x/net/internal/socket/defs_linux.go b/vendor/golang.org/x/net/internal/socket/defs_linux.go index ce9ec2f6d..6c5c11dcc 100644 --- a/vendor/golang.org/x/net/internal/socket/defs_linux.go +++ b/vendor/golang.org/x/net/internal/socket/defs_linux.go @@ -18,14 +18,6 @@ package socket */ import "C" -const ( - sysAF_UNSPEC = C.AF_UNSPEC - sysAF_INET = C.AF_INET - sysAF_INET6 = C.AF_INET6 - - sysSOCK_RAW = C.SOCK_RAW -) - type iovec C.struct_iovec type msghdr C.struct_msghdr diff --git a/vendor/golang.org/x/net/internal/socket/defs_netbsd.go b/vendor/golang.org/x/net/internal/socket/defs_netbsd.go index 3f8433569..3d3b77639 100644 --- a/vendor/golang.org/x/net/internal/socket/defs_netbsd.go +++ b/vendor/golang.org/x/net/internal/socket/defs_netbsd.go @@ -16,14 +16,6 @@ package socket */ import "C" -const ( - sysAF_UNSPEC = C.AF_UNSPEC - sysAF_INET = C.AF_INET - sysAF_INET6 = C.AF_INET6 - - sysSOCK_RAW = C.SOCK_RAW -) - type iovec C.struct_iovec type msghdr C.struct_msghdr diff --git a/vendor/golang.org/x/net/internal/socket/defs_openbsd.go b/vendor/golang.org/x/net/internal/socket/defs_openbsd.go index 14e28c0b4..b780bc67a 100644 --- a/vendor/golang.org/x/net/internal/socket/defs_openbsd.go +++ b/vendor/golang.org/x/net/internal/socket/defs_openbsd.go @@ -16,14 +16,6 @@ package socket */ import "C" -const ( - sysAF_UNSPEC = C.AF_UNSPEC - sysAF_INET = C.AF_INET - sysAF_INET6 = C.AF_INET6 - - sysSOCK_RAW = C.SOCK_RAW -) - type iovec C.struct_iovec type msghdr C.struct_msghdr diff --git a/vendor/golang.org/x/net/internal/socket/defs_solaris.go b/vendor/golang.org/x/net/internal/socket/defs_solaris.go index 14e28c0b4..b780bc67a 100644 --- a/vendor/golang.org/x/net/internal/socket/defs_solaris.go +++ b/vendor/golang.org/x/net/internal/socket/defs_solaris.go @@ -16,14 +16,6 @@ package socket */ import "C" -const ( - sysAF_UNSPEC = C.AF_UNSPEC - sysAF_INET = C.AF_INET - sysAF_INET6 = C.AF_INET6 - - sysSOCK_RAW = C.SOCK_RAW -) - type iovec C.struct_iovec type msghdr C.struct_msghdr diff --git a/vendor/golang.org/x/net/internal/socket/empty.s b/vendor/golang.org/x/net/internal/socket/empty.s new file mode 100644 index 000000000..bff0231c7 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/empty.s @@ -0,0 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin,go1.12 + +// This exists solely so we can linkname in symbols from syscall. diff --git a/vendor/golang.org/x/net/internal/socket/error_unix.go b/vendor/golang.org/x/net/internal/socket/error_unix.go index 93dff9180..f14872d3d 100644 --- a/vendor/golang.org/x/net/internal/socket/error_unix.go +++ b/vendor/golang.org/x/net/internal/socket/error_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package socket diff --git a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_64bit.go index afb34ad58..dfeda752b 100644 --- a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go +++ b/vendor/golang.org/x/net/internal/socket/iovec_64bit.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x -// +build darwin dragonfly freebsd linux netbsd openbsd +// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x +// +build aix darwin dragonfly freebsd linux netbsd openbsd package socket diff --git a/vendor/golang.org/x/net/internal/socket/iovec_stub.go b/vendor/golang.org/x/net/internal/socket/iovec_stub.go index c87d2a933..a746e90e3 100644 --- a/vendor/golang.org/x/net/internal/socket/iovec_stub.go +++ b/vendor/golang.org/x/net/internal/socket/iovec_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris package socket diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go index 2e80a9cb7..1a7f2792f 100644 --- a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go +++ b/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !linux,!netbsd +// +build !aix,!linux,!netbsd package socket diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go index 3c42ea7ad..f1100683a 100644 --- a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go +++ b/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build linux netbsd +// +build aix linux netbsd package socket diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go index 5567afc88..77f44c1f1 100644 --- a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go +++ b/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd netbsd openbsd +// +build aix darwin dragonfly freebsd netbsd openbsd package socket diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go index b8c87b72b..c5562dd66 100644 --- a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go +++ b/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd netbsd +// +build aix darwin dragonfly freebsd netbsd package socket diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go index 610fc4f3b..e731833a2 100644 --- a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go +++ b/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x +// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x // +build linux package socket diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go b/vendor/golang.org/x/net/internal/socket/msghdr_stub.go index 64e817335..873490a7a 100644 --- a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go +++ b/vendor/golang.org/x/net/internal/socket/msghdr_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris package socket diff --git a/vendor/golang.org/x/net/internal/socket/rawconn.go b/vendor/golang.org/x/net/internal/socket/rawconn.go index d6871d55f..b07b89005 100644 --- a/vendor/golang.org/x/net/internal/socket/rawconn.go +++ b/vendor/golang.org/x/net/internal/socket/rawconn.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.9 - package socket import ( diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go index 499164a3f..1f4cb3b36 100644 --- a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go +++ b/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.9 // +build linux package socket diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go index b21d2e641..a97201181 100644 --- a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go +++ b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.9 -// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows package socket diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go index f78832aa4..fe5bb942b 100644 --- a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go +++ b/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go @@ -2,17 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.9 // +build !linux package socket -import "errors" - func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go index 96733cbe1..b8cea6fe5 100644 --- a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go +++ b/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go @@ -2,17 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.9 -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package socket -import "errors" - func (c *Conn) recvMsg(m *Message, flags int) error { - return errors.New("not implemented") + return errNotImplemented } func (c *Conn) sendMsg(m *Message, flags int) error { - return errors.New("not implemented") + return errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_stub.go b/vendor/golang.org/x/net/internal/socket/rawconn_stub.go deleted file mode 100644 index d2add1a0a..000000000 --- a/vendor/golang.org/x/net/internal/socket/rawconn_stub.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 - -package socket - -import "errors" - -func (c *Conn) recvMsg(m *Message, flags int) error { - return errors.New("not implemented") -} - -func (c *Conn) sendMsg(m *Message, flags int) error { - return errors.New("not implemented") -} - -func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) { - return 0, errors.New("not implemented") -} - -func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) { - return 0, errors.New("not implemented") -} diff --git a/vendor/golang.org/x/net/internal/socket/reflect.go b/vendor/golang.org/x/net/internal/socket/reflect.go deleted file mode 100644 index bb179f11d..000000000 --- a/vendor/golang.org/x/net/internal/socket/reflect.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 - -package socket - -import ( - "errors" - "net" - "os" - "reflect" - "runtime" -) - -// A Conn represents a raw connection. -type Conn struct { - c net.Conn -} - -// NewConn returns a new raw connection. -func NewConn(c net.Conn) (*Conn, error) { - return &Conn{c: c}, nil -} - -func (o *Option) get(c *Conn, b []byte) (int, error) { - s, err := socketOf(c.c) - if err != nil { - return 0, err - } - n, err := getsockopt(s, o.Level, o.Name, b) - return n, os.NewSyscallError("getsockopt", err) -} - -func (o *Option) set(c *Conn, b []byte) error { - s, err := socketOf(c.c) - if err != nil { - return err - } - return os.NewSyscallError("setsockopt", setsockopt(s, o.Level, o.Name, b)) -} - -func socketOf(c net.Conn) (uintptr, error) { - switch c.(type) { - case *net.TCPConn, *net.UDPConn, *net.IPConn: - v := reflect.ValueOf(c) - switch e := v.Elem(); e.Kind() { - case reflect.Struct: - fd := e.FieldByName("conn").FieldByName("fd") - switch e := fd.Elem(); e.Kind() { - case reflect.Struct: - sysfd := e.FieldByName("sysfd") - if runtime.GOOS == "windows" { - return uintptr(sysfd.Uint()), nil - } - return uintptr(sysfd.Int()), nil - } - } - } - return 0, errors.New("invalid type") -} diff --git a/vendor/golang.org/x/net/internal/socket/socket.go b/vendor/golang.org/x/net/internal/socket/socket.go index 5f9730e6d..23571b8d4 100644 --- a/vendor/golang.org/x/net/internal/socket/socket.go +++ b/vendor/golang.org/x/net/internal/socket/socket.go @@ -9,9 +9,12 @@ package socket // import "golang.org/x/net/internal/socket" import ( "errors" "net" + "runtime" "unsafe" ) +var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH) + // An Option represents a sticky socket option. type Option struct { Level int // level diff --git a/vendor/golang.org/x/net/internal/socket/sys.go b/vendor/golang.org/x/net/internal/socket/sys.go index 4f0eead13..ee492ba86 100644 --- a/vendor/golang.org/x/net/internal/socket/sys.go +++ b/vendor/golang.org/x/net/internal/socket/sys.go @@ -29,5 +29,5 @@ func init() { } func roundup(l int) int { - return (l + kernelAlign - 1) & ^(kernelAlign - 1) + return (l + kernelAlign - 1) &^ (kernelAlign - 1) } diff --git a/vendor/golang.org/x/net/internal/socket/sys_bsd.go b/vendor/golang.org/x/net/internal/socket/sys_bsd.go index f13e14ff3..d432835b4 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_bsd.go +++ b/vendor/golang.org/x/net/internal/socket/sys_bsd.go @@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd openbsd +// +build aix darwin dragonfly freebsd openbsd package socket -import "errors" - func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/sys_bsdvar.go b/vendor/golang.org/x/net/internal/socket/sys_bsdvar.go index f723fa36a..b4f41b552 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_bsdvar.go +++ b/vendor/golang.org/x/net/internal/socket/sys_bsdvar.go @@ -2,13 +2,22 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build freebsd netbsd openbsd +// +build aix freebsd netbsd openbsd package socket -import "unsafe" +import ( + "runtime" + "unsafe" +) func probeProtocolStack() int { + if (runtime.GOOS == "netbsd" || runtime.GOOS == "openbsd") && runtime.GOARCH == "arm" { + return 8 + } + if runtime.GOOS == "aix" { + return 1 + } var p uintptr return int(unsafe.Sizeof(p)) } diff --git a/vendor/golang.org/x/net/internal/socket/sys_const_unix.go b/vendor/golang.org/x/net/internal/socket/sys_const_unix.go new file mode 100644 index 000000000..43797d6e5 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/sys_const_unix.go @@ -0,0 +1,17 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris + +package socket + +import "golang.org/x/sys/unix" + +const ( + sysAF_UNSPEC = unix.AF_UNSPEC + sysAF_INET = unix.AF_INET + sysAF_INET6 = unix.AF_INET6 + + sysSOCK_RAW = unix.SOCK_RAW +) diff --git a/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go b/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go new file mode 100644 index 000000000..02d2b3cc8 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go @@ -0,0 +1,33 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.12 + +package socket + +import ( + "syscall" + "unsafe" +) + +func getsockopt(s uintptr, level, name int, b []byte) (int, error) { + l := uint32(len(b)) + _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0) + return int(l), errnoErr(errno) +} + +func setsockopt(s uintptr, level, name int, b []byte) error { + _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0) + return errnoErr(errno) +} + +func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { + n, _, errno := syscall.Syscall(syscall.SYS_RECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) + return int(n), errnoErr(errno) +} + +func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { + n, _, errno := syscall.Syscall(syscall.SYS_SENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) + return int(n), errnoErr(errno) +} diff --git a/vendor/golang.org/x/net/internal/socket/sys_linkname.go b/vendor/golang.org/x/net/internal/socket/sys_linkname.go new file mode 100644 index 000000000..61c3f38a5 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/sys_linkname.go @@ -0,0 +1,42 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix go1.12,darwin + +package socket + +import ( + "syscall" + "unsafe" +) + +//go:linkname syscall_getsockopt syscall.getsockopt +func syscall_getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *uint32) error + +func getsockopt(s uintptr, level, name int, b []byte) (int, error) { + l := uint32(len(b)) + err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l) + return int(l), err +} + +//go:linkname syscall_setsockopt syscall.setsockopt +func syscall_setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error + +func setsockopt(s uintptr, level, name int, b []byte) error { + return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b))) +} + +//go:linkname syscall_recvmsg syscall.recvmsg +func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error) + +func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { + return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) +} + +//go:linkname syscall_sendmsg syscall.sendmsg +func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error) + +func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { + return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) +} diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go new file mode 100644 index 000000000..64f69f1dc --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go @@ -0,0 +1,12 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build riscv64 + +package socket + +const ( + sysRECVMMSG = 0xf3 + sysSENDMMSG = 0x10d +) diff --git a/vendor/golang.org/x/net/internal/socket/sys_posix.go b/vendor/golang.org/x/net/internal/socket/sys_posix.go index dc130c27e..22eae809c 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_posix.go +++ b/vendor/golang.org/x/net/internal/socket/sys_posix.go @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.9 -// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows package socket @@ -34,7 +33,7 @@ func marshalSockaddr(ip net.IP, port int, zone string) []byte { if ip4 := ip.To4(); ip4 != nil { b := make([]byte, sizeofSockaddrInet) switch runtime.GOOS { - case "android", "linux", "solaris", "windows": + case "android", "illumos", "linux", "solaris", "windows": NativeEndian.PutUint16(b[:2], uint16(sysAF_INET)) default: b[0] = sizeofSockaddrInet @@ -47,7 +46,7 @@ func marshalSockaddr(ip net.IP, port int, zone string) []byte { if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil { b := make([]byte, sizeofSockaddrInet6) switch runtime.GOOS { - case "android", "linux", "solaris", "windows": + case "android", "illumos", "linux", "solaris", "windows": NativeEndian.PutUint16(b[:2], uint16(sysAF_INET6)) default: b[0] = sizeofSockaddrInet6 @@ -69,7 +68,7 @@ func parseInetAddr(b []byte, network string) (net.Addr, error) { } var af int switch runtime.GOOS { - case "android", "linux", "solaris", "windows": + case "android", "illumos", "linux", "solaris", "windows": af = int(NativeEndian.Uint16(b[:2])) default: af = int(b[1]) @@ -121,18 +120,21 @@ var zoneCache = ipv6ZoneCache{ toName: make(map[int]string), } -func (zc *ipv6ZoneCache) update(ift []net.Interface) { +// update refreshes the network interface information if the cache was last +// updated more than 1 minute ago, or if force is set. It returns whether the +// cache was updated. +func (zc *ipv6ZoneCache) update(ift []net.Interface, force bool) (updated bool) { zc.Lock() defer zc.Unlock() now := time.Now() - if zc.lastFetched.After(now.Add(-60 * time.Second)) { - return + if !force && zc.lastFetched.After(now.Add(-60*time.Second)) { + return false } zc.lastFetched = now if len(ift) == 0 { var err error if ift, err = net.Interfaces(); err != nil { - return + return false } } zc.toIndex = make(map[string]int, len(ift)) @@ -143,25 +145,38 @@ func (zc *ipv6ZoneCache) update(ift []net.Interface) { zc.toName[ifi.Index] = ifi.Name } } + return true } func (zc *ipv6ZoneCache) name(zone int) string { - zoneCache.update(nil) + updated := zoneCache.update(nil, false) zoneCache.RLock() - defer zoneCache.RUnlock() name, ok := zoneCache.toName[zone] - if !ok { + zoneCache.RUnlock() + if !ok && !updated { + zoneCache.update(nil, true) + zoneCache.RLock() + name, ok = zoneCache.toName[zone] + zoneCache.RUnlock() + } + if !ok { // last resort name = strconv.Itoa(zone) } return name } func (zc *ipv6ZoneCache) index(zone string) int { - zoneCache.update(nil) + updated := zoneCache.update(nil, false) zoneCache.RLock() - defer zoneCache.RUnlock() index, ok := zoneCache.toIndex[zone] - if !ok { + zoneCache.RUnlock() + if !ok && !updated { + zoneCache.update(nil, true) + zoneCache.RLock() + index, ok = zoneCache.toIndex[zone] + zoneCache.RUnlock() + } + if !ok { // last resort index, _ = strconv.Atoi(zone) } return index diff --git a/vendor/golang.org/x/net/internal/socket/sys_solaris.go b/vendor/golang.org/x/net/internal/socket/sys_solaris.go index cced74e60..66b554786 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_solaris.go +++ b/vendor/golang.org/x/net/internal/socket/sys_solaris.go @@ -5,7 +5,6 @@ package socket import ( - "errors" "runtime" "syscall" "unsafe" @@ -63,9 +62,9 @@ func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { } func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/sys_stub.go b/vendor/golang.org/x/net/internal/socket/sys_stub.go index d9f06d00e..0f6174262 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_stub.go +++ b/vendor/golang.org/x/net/internal/socket/sys_stub.go @@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package socket import ( - "errors" "net" "runtime" "unsafe" @@ -36,29 +35,29 @@ func marshalInetAddr(ip net.IP, port int, zone string) []byte { } func parseInetAddr(b []byte, network string) (net.Addr, error) { - return nil, errors.New("not implemented") + return nil, errNotImplemented } func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func setsockopt(s uintptr, level, name int, b []byte) error { - return errors.New("not implemented") + return errNotImplemented } func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go index 18eba3085..0eb71283f 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_unix.go +++ b/vendor/golang.org/x/net/internal/socket/sys_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux,!s390x,!386 netbsd openbsd +// +build dragonfly freebsd linux,!s390x,!386 netbsd openbsd package socket diff --git a/vendor/golang.org/x/net/internal/socket/sys_windows.go b/vendor/golang.org/x/net/internal/socket/sys_windows.go index 54a470ebe..d556a4461 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_windows.go +++ b/vendor/golang.org/x/net/internal/socket/sys_windows.go @@ -5,9 +5,10 @@ package socket import ( - "errors" "syscall" "unsafe" + + "golang.org/x/sys/windows" ) func probeProtocolStack() int { @@ -16,11 +17,11 @@ func probeProtocolStack() int { } const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x17 + sysAF_UNSPEC = windows.AF_UNSPEC + sysAF_INET = windows.AF_INET + sysAF_INET6 = windows.AF_INET6 - sysSOCK_RAW = 0x3 + sysSOCK_RAW = windows.SOCK_RAW ) type sockaddrInet struct { @@ -54,17 +55,17 @@ func setsockopt(s uintptr, level, name int, b []byte) error { } func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errors.New("not implemented") + return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go new file mode 100644 index 000000000..813385a98 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go @@ -0,0 +1,61 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_aix.go + +// Added for go1.11 compatibility +// +build aix + +package socket + +type iovec struct { + Base *byte + Len uint64 +} + +type msghdr struct { + Name *byte + Namelen uint32 + Iov *iovec + Iovlen int32 + Control *byte + Controllen uint32 + Flags int32 +} + +type mmsghdr struct { + Hdr msghdr + Len uint32 + Pad_cgo_0 [4]byte +} + +type cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type sockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]uint8 +} + +type sockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +const ( + sizeofIovec = 0x10 + sizeofMsghdr = 0x30 + sizeofMmsghdr = 0x38 + sizeofCmsghdr = 0xc + + sizeofSockaddrInet = 0x10 + sizeofSockaddrInet6 = 0x1c +) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go index 26f8feff3..083bda51c 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_darwin.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1e - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go index e2987f7db..55c6c9f57 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_darwin.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1e - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go index 26f8feff3..083bda51c 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_darwin.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1e - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go index e2987f7db..55c6c9f57 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_darwin.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1e - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go index c582abd57..8b7d161d7 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_dragonfly.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1c - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go index 04a24886c..3e71ff574 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1c - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go index 35c7cb9c9..238d90de6 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1c - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go index 04a24886c..3e71ff574 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1c - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go new file mode 100644 index 000000000..238d90de6 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go @@ -0,0 +1,53 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_freebsd.go + +package socket + +type iovec struct { + Base *byte + Len uint64 +} + +type msghdr struct { + Name *byte + Namelen uint32 + Pad_cgo_0 [4]byte + Iov *iovec + Iovlen int32 + Pad_cgo_1 [4]byte + Control *byte + Controllen uint32 + Flags int32 +} + +type cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type sockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +const ( + sizeofIovec = 0x10 + sizeofMsghdr = 0x30 + sizeofCmsghdr = 0xc + + sizeofSockaddrInet = 0x10 + sizeofSockaddrInet6 = 0x1c +) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go index 430206930..72d8b2542 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go index 1502f6c55..3545319ae 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go index 430206930..72d8b2542 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go index 1502f6c55..3545319ae 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go index 430206930..72d8b2542 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go index 1502f6c55..3545319ae 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go index 1502f6c55..3545319ae 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go index 430206930..72d8b2542 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go index 1502f6c55..3545319ae 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go index 1502f6c55..3545319ae 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go new file mode 100644 index 000000000..dbff234fb --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go @@ -0,0 +1,59 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_linux.go + +// +build riscv64 + +package socket + +type iovec struct { + Base *byte + Len uint64 +} + +type msghdr struct { + Name *byte + Namelen uint32 + Iov *iovec + Iovlen uint64 + Control *byte + Controllen uint64 + Flags int32 + Pad_cgo_0 [4]byte +} + +type mmsghdr struct { + Hdr msghdr + Len uint32 + Pad_cgo_0 [4]byte +} + +type cmsghdr struct { + Len uint64 + Level int32 + Type int32 +} + +type sockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +const ( + sizeofIovec = 0x10 + sizeofMsghdr = 0x38 + sizeofMmsghdr = 0x40 + sizeofCmsghdr = 0x10 + + sizeofSockaddrInet = 0x10 + sizeofSockaddrInet6 = 0x1c +) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go index 1502f6c55..3545319ae 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go index db60491fe..bf8f47c88 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_netbsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x18 - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go index 2a1a79985..a46eff991 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_netbsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x18 - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go index db60491fe..bf8f47c88 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_netbsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x18 - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go new file mode 100644 index 000000000..a46eff991 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go @@ -0,0 +1,60 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_netbsd.go + +package socket + +type iovec struct { + Base *byte + Len uint64 +} + +type msghdr struct { + Name *byte + Namelen uint32 + Pad_cgo_0 [4]byte + Iov *iovec + Iovlen int32 + Pad_cgo_1 [4]byte + Control *byte + Controllen uint32 + Flags int32 +} + +type mmsghdr struct { + Hdr msghdr + Len uint32 + Pad_cgo_0 [4]byte +} + +type cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type sockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +const ( + sizeofIovec = 0x10 + sizeofMsghdr = 0x30 + sizeofMmsghdr = 0x40 + sizeofCmsghdr = 0xc + + sizeofSockaddrInet = 0x10 + sizeofSockaddrInet6 = 0x1c +) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go index 1c836361e..73655a14c 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_openbsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x18 - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go index a6c0bf464..0a4de80f2 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_openbsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x18 - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint64 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go index 1c836361e..73655a14c 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_openbsd.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x18 - - sysSOCK_RAW = 0x3 -) - type iovec struct { Base *byte Len uint32 diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go new file mode 100644 index 000000000..0a4de80f2 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go @@ -0,0 +1,53 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_openbsd.go + +package socket + +type iovec struct { + Base *byte + Len uint64 +} + +type msghdr struct { + Name *byte + Namelen uint32 + Pad_cgo_0 [4]byte + Iov *iovec + Iovlen uint32 + Pad_cgo_1 [4]byte + Control *byte + Controllen uint32 + Flags int32 +} + +type cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type sockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +const ( + sizeofIovec = 0x10 + sizeofMsghdr = 0x30 + sizeofCmsghdr = 0xc + + sizeofSockaddrInet = 0x10 + sizeofSockaddrInet6 = 0x1c +) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go index 327c63290..353cd5fb4 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go @@ -1,16 +1,8 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_solaris.go package socket -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0x1a - - sysSOCK_RAW = 0x4 -) - type iovec struct { Base *int8 Len uint64 diff --git a/vendor/golang.org/x/net/internal/socks/socks.go b/vendor/golang.org/x/net/internal/socks/socks.go index d93e699b4..6929a9fd5 100644 --- a/vendor/golang.org/x/net/internal/socks/socks.go +++ b/vendor/golang.org/x/net/internal/socks/socks.go @@ -224,6 +224,7 @@ func (d *Dialer) Dial(network, address string) (net.Conn, error) { return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err} } if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil { + c.Close() return nil, err } return c, nil diff --git a/vendor/golang.org/x/net/ipv4/batch.go b/vendor/golang.org/x/net/ipv4/batch.go index b44549928..1a3a4fc0c 100644 --- a/vendor/golang.org/x/net/ipv4/batch.go +++ b/vendor/golang.org/x/net/ipv4/batch.go @@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.9 - package ipv4 import ( "net" "runtime" - "syscall" "golang.org/x/net/internal/socket" ) @@ -76,7 +73,7 @@ type Message = socket.Message // headers. func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": @@ -92,6 +89,9 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { n = 0 err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} } + if compatFreeBSD32 && ms[0].NN > 0 { + adjustFreeBSD32(&ms[0]) + } return n, err } } @@ -107,7 +107,7 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { // On other platforms, this method will write only a single message. func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": @@ -139,7 +139,7 @@ func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) { // On other platforms, this method will read only a single message. func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": @@ -155,6 +155,9 @@ func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) { n = 0 err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} } + if compatFreeBSD32 && ms[0].NN > 0 { + adjustFreeBSD32(&ms[0]) + } return n, err } } @@ -170,7 +173,7 @@ func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) { // On other platforms, this method will write only a single message. func (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": diff --git a/vendor/golang.org/x/net/ipv4/control_bsd.go b/vendor/golang.org/x/net/ipv4/control_bsd.go index 77e7ad5be..19845c55b 100644 --- a/vendor/golang.org/x/net/ipv4/control_bsd.go +++ b/vendor/golang.org/x/net/ipv4/control_bsd.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd netbsd openbsd +// +build aix darwin dragonfly freebsd netbsd openbsd package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/control_stub.go b/vendor/golang.org/x/net/ipv4/control_stub.go index 5a2f7d8d3..a0c049d68 100644 --- a/vendor/golang.org/x/net/ipv4/control_stub.go +++ b/vendor/golang.org/x/net/ipv4/control_stub.go @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package ipv4 import "golang.org/x/net/internal/socket" func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv4/control_unix.go b/vendor/golang.org/x/net/ipv4/control_unix.go index e1ae8167b..b27fa4903 100644 --- a/vendor/golang.org/x/net/ipv4/control_unix.go +++ b/vendor/golang.org/x/net/ipv4/control_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/control_windows.go b/vendor/golang.org/x/net/ipv4/control_windows.go index ce55c6644..82c630642 100644 --- a/vendor/golang.org/x/net/ipv4/control_windows.go +++ b/vendor/golang.org/x/net/ipv4/control_windows.go @@ -4,13 +4,9 @@ package ipv4 -import ( - "syscall" - - "golang.org/x/net/internal/socket" -) +import "golang.org/x/net/internal/socket" func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { // TODO(mikio): implement this - return syscall.EWINDOWS + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv4/defs_aix.go b/vendor/golang.org/x/net/ipv4/defs_aix.go new file mode 100644 index 000000000..0f37211c6 --- /dev/null +++ b/vendor/golang.org/x/net/ipv4/defs_aix.go @@ -0,0 +1,39 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ + +package ipv4 + +/* +#include +*/ +import "C" + +const ( + sysIP_OPTIONS = C.IP_OPTIONS + sysIP_HDRINCL = C.IP_HDRINCL + sysIP_TOS = C.IP_TOS + sysIP_TTL = C.IP_TTL + sysIP_RECVOPTS = C.IP_RECVOPTS + sysIP_RECVRETOPTS = C.IP_RECVRETOPTS + sysIP_RECVDSTADDR = C.IP_RECVDSTADDR + sysIP_RETOPTS = C.IP_RETOPTS + // IP_RECVIF is defined on AIX but doesn't work. + // IP_RECVINTERFACE must be used instead. + sysIP_RECVIF = C.IP_RECVINTERFACE + sysIP_RECVTTL = C.IP_RECVTTL + + sysIP_MULTICAST_IF = C.IP_MULTICAST_IF + sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL + sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP + sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP + sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP + + sizeofIPMreq = C.sizeof_struct_ip_mreq +) + +type ipMreq C.struct_ip_mreq diff --git a/vendor/golang.org/x/net/ipv4/dgramopt.go b/vendor/golang.org/x/net/ipv4/dgramopt.go index 54d77d5fe..c191c22ab 100644 --- a/vendor/golang.org/x/net/ipv4/dgramopt.go +++ b/vendor/golang.org/x/net/ipv4/dgramopt.go @@ -6,7 +6,6 @@ package ipv4 import ( "net" - "syscall" "golang.org/x/net/bpf" ) @@ -15,11 +14,11 @@ import ( // multicast packets. func (c *dgramOpt) MulticastTTL() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoMulticastTTL] if !ok { - return 0, errOpNoSupport + return 0, errNotImplemented } return so.GetInt(c.Conn) } @@ -28,11 +27,11 @@ func (c *dgramOpt) MulticastTTL() (int, error) { // outgoing multicast packets. func (c *dgramOpt) SetMulticastTTL(ttl int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastTTL] if !ok { - return errOpNoSupport + return errNotImplemented } return so.SetInt(c.Conn, ttl) } @@ -41,11 +40,11 @@ func (c *dgramOpt) SetMulticastTTL(ttl int) error { // packet transmissions. func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { if !c.ok() { - return nil, syscall.EINVAL + return nil, errInvalidConn } so, ok := sockOpts[ssoMulticastInterface] if !ok { - return nil, errOpNoSupport + return nil, errNotImplemented } return so.getMulticastInterface(c.Conn) } @@ -54,11 +53,11 @@ func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { // multicast packet transmissions. func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastInterface] if !ok { - return errOpNoSupport + return errNotImplemented } return so.setMulticastInterface(c.Conn, ifi) } @@ -67,11 +66,11 @@ func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { // should be copied and send back to the originator. func (c *dgramOpt) MulticastLoopback() (bool, error) { if !c.ok() { - return false, syscall.EINVAL + return false, errInvalidConn } so, ok := sockOpts[ssoMulticastLoopback] if !ok { - return false, errOpNoSupport + return false, errNotImplemented } on, err := so.GetInt(c.Conn) if err != nil { @@ -84,11 +83,11 @@ func (c *dgramOpt) MulticastLoopback() (bool, error) { // should be copied and send back to the originator. func (c *dgramOpt) SetMulticastLoopback(on bool) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastLoopback] if !ok { - return errOpNoSupport + return errNotImplemented } return so.SetInt(c.Conn, boolint(on)) } @@ -104,11 +103,11 @@ func (c *dgramOpt) SetMulticastLoopback(on bool) error { // configuration. func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoJoinGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP4(group) if grp == nil { @@ -122,11 +121,11 @@ func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { // source-specific group. func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoLeaveGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP4(group) if grp == nil { @@ -143,11 +142,11 @@ func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { // routing configuration. func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoJoinSourceGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP4(group) if grp == nil { @@ -164,11 +163,11 @@ func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net // interface ifi. func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoLeaveSourceGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP4(group) if grp == nil { @@ -186,11 +185,11 @@ func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source ne // ifi. func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoBlockSourceGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP4(group) if grp == nil { @@ -207,11 +206,11 @@ func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source // group by ExcludeSourceSpecificGroup again on the interface ifi. func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoUnblockSourceGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP4(group) if grp == nil { @@ -228,11 +227,11 @@ func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source // Currently only Linux supports this. func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { if !c.ok() { - return nil, syscall.EINVAL + return nil, errInvalidConn } so, ok := sockOpts[ssoICMPFilter] if !ok { - return nil, errOpNoSupport + return nil, errNotImplemented } return so.getICMPFilter(c.Conn) } @@ -241,11 +240,11 @@ func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { // Currently only Linux supports this. func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoICMPFilter] if !ok { - return errOpNoSupport + return errNotImplemented } return so.setICMPFilter(c.Conn, f) } @@ -255,11 +254,11 @@ func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { // Only supported on Linux. func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoAttachFilter] if !ok { - return errOpNoSupport + return errNotImplemented } return so.setBPF(c.Conn, filter) } diff --git a/vendor/golang.org/x/net/ipv4/doc.go b/vendor/golang.org/x/net/ipv4/doc.go index b43935a5a..245834979 100644 --- a/vendor/golang.org/x/net/ipv4/doc.go +++ b/vendor/golang.org/x/net/ipv4/doc.go @@ -55,7 +55,7 @@ // Multicasting // // The options for multicasting are available for net.UDPConn and -// net.IPconn which are created as network connections that use the +// net.IPConn which are created as network connections that use the // IPv4 transport. A few network facilities must be prepared before // you begin multicasting, at a minimum joining network interfaces and // multicast groups. @@ -209,7 +209,7 @@ // LeaveSourceSpecificGroup for the operation known as "include" mode, // // ssmgroup := net.UDPAddr{IP: net.IPv4(232, 7, 8, 9)} -// ssmsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}) +// ssmsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)} // if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil { // // error handling // } @@ -241,4 +241,4 @@ // IncludeSourceSpecificGroup may return an error. package ipv4 // import "golang.org/x/net/ipv4" -// BUG(mikio): This package is not implemented on NaCl and Plan 9. +// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9. diff --git a/vendor/golang.org/x/net/ipv4/endpoint.go b/vendor/golang.org/x/net/ipv4/endpoint.go index 2ab877363..4a6d7a85e 100644 --- a/vendor/golang.org/x/net/ipv4/endpoint.go +++ b/vendor/golang.org/x/net/ipv4/endpoint.go @@ -6,7 +6,6 @@ package ipv4 import ( "net" - "syscall" "time" "golang.org/x/net/internal/socket" @@ -58,7 +57,7 @@ func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil } // SetControlMessage sets the per packet IP-level socket options. func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on) } @@ -67,7 +66,7 @@ func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { // endpoint. func (c *PacketConn) SetDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.PacketConn.SetDeadline(t) } @@ -76,7 +75,7 @@ func (c *PacketConn) SetDeadline(t time.Time) error { // endpoint. func (c *PacketConn) SetReadDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.PacketConn.SetReadDeadline(t) } @@ -85,7 +84,7 @@ func (c *PacketConn) SetReadDeadline(t time.Time) error { // endpoint. func (c *PacketConn) SetWriteDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.PacketConn.SetWriteDeadline(t) } @@ -93,7 +92,7 @@ func (c *PacketConn) SetWriteDeadline(t time.Time) error { // Close closes the endpoint. func (c *PacketConn) Close() error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.PacketConn.Close() } @@ -124,7 +123,7 @@ type RawConn struct { // SetControlMessage sets the per packet IP-level socket options. func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on) } @@ -133,7 +132,7 @@ func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error { // endpoint. func (c *RawConn) SetDeadline(t time.Time) error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.packetHandler.IPConn.SetDeadline(t) } @@ -142,7 +141,7 @@ func (c *RawConn) SetDeadline(t time.Time) error { // endpoint. func (c *RawConn) SetReadDeadline(t time.Time) error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.packetHandler.IPConn.SetReadDeadline(t) } @@ -151,7 +150,7 @@ func (c *RawConn) SetReadDeadline(t time.Time) error { // endpoint. func (c *RawConn) SetWriteDeadline(t time.Time) error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.packetHandler.IPConn.SetWriteDeadline(t) } @@ -159,7 +158,7 @@ func (c *RawConn) SetWriteDeadline(t time.Time) error { // Close closes the endpoint. func (c *RawConn) Close() error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.packetHandler.IPConn.Close() } @@ -178,7 +177,7 @@ func NewRawConn(c net.PacketConn) (*RawConn, error) { } so, ok := sockOpts[ssoHeaderPrepend] if !ok { - return nil, errOpNoSupport + return nil, errNotImplemented } if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil { return nil, err diff --git a/vendor/golang.org/x/net/ipv4/genericopt.go b/vendor/golang.org/x/net/ipv4/genericopt.go index 119bf841b..51c12371e 100644 --- a/vendor/golang.org/x/net/ipv4/genericopt.go +++ b/vendor/golang.org/x/net/ipv4/genericopt.go @@ -4,16 +4,14 @@ package ipv4 -import "syscall" - // TOS returns the type-of-service field value for outgoing packets. func (c *genericOpt) TOS() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoTOS] if !ok { - return 0, errOpNoSupport + return 0, errNotImplemented } return so.GetInt(c.Conn) } @@ -22,11 +20,11 @@ func (c *genericOpt) TOS() (int, error) { // packets. func (c *genericOpt) SetTOS(tos int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoTOS] if !ok { - return errOpNoSupport + return errNotImplemented } return so.SetInt(c.Conn, tos) } @@ -34,11 +32,11 @@ func (c *genericOpt) SetTOS(tos int) error { // TTL returns the time-to-live field value for outgoing packets. func (c *genericOpt) TTL() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoTTL] if !ok { - return 0, errOpNoSupport + return 0, errNotImplemented } return so.GetInt(c.Conn) } @@ -47,11 +45,11 @@ func (c *genericOpt) TTL() (int, error) { // packets. func (c *genericOpt) SetTTL(ttl int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoTTL] if !ok { - return errOpNoSupport + return errNotImplemented } return so.SetInt(c.Conn, ttl) } diff --git a/vendor/golang.org/x/net/ipv4/header.go b/vendor/golang.org/x/net/ipv4/header.go index c8822a6ab..701bd4b22 100644 --- a/vendor/golang.org/x/net/ipv4/header.go +++ b/vendor/golang.org/x/net/ipv4/header.go @@ -9,7 +9,6 @@ import ( "fmt" "net" "runtime" - "syscall" "golang.org/x/net/internal/socket" ) @@ -52,9 +51,13 @@ func (h *Header) String() string { } // Marshal returns the binary encoding of h. +// +// The returned slice is in the format used by a raw IP socket on the +// local system. +// This may differ from the wire format, depending on the system. func (h *Header) Marshal() ([]byte, error) { if h == nil { - return nil, syscall.EINVAL + return nil, errNilHeader } if h.Len < HeaderLen { return nil, errHeaderTooShort @@ -99,13 +102,20 @@ func (h *Header) Marshal() ([]byte, error) { } // Parse parses b as an IPv4 header and stores the result in h. +// +// The provided b must be in the format used by a raw IP socket on the +// local system. +// This may differ from the wire format, depending on the system. func (h *Header) Parse(b []byte) error { - if h == nil || len(b) < HeaderLen { + if h == nil || b == nil { + return errNilHeader + } + if len(b) < HeaderLen { return errHeaderTooShort } hdrlen := int(b[0]&0x0f) << 2 - if hdrlen > len(b) { - return errBufferTooShort + if len(b) < hdrlen { + return errExtHeaderTooShort } h.Version = int(b[0] >> 4) h.Len = hdrlen @@ -150,6 +160,10 @@ func (h *Header) Parse(b []byte) error { } // ParseHeader parses b as an IPv4 header. +// +// The provided b must be in the format used by a raw IP socket on the +// local system. +// This may differ from the wire format, depending on the system. func ParseHeader(b []byte) (*Header, error) { h := new(Header) if err := h.Parse(b); err != nil { diff --git a/vendor/golang.org/x/net/ipv4/helper.go b/vendor/golang.org/x/net/ipv4/helper.go index a5052e324..b494a2cde 100644 --- a/vendor/golang.org/x/net/ipv4/helper.go +++ b/vendor/golang.org/x/net/ipv4/helper.go @@ -7,22 +7,39 @@ package ipv4 import ( "errors" "net" + "runtime" + + "golang.org/x/net/internal/socket" ) var ( + errInvalidConn = errors.New("invalid connection") errMissingAddress = errors.New("missing address") errMissingHeader = errors.New("missing header") + errNilHeader = errors.New("nil header") errHeaderTooShort = errors.New("header too short") - errBufferTooShort = errors.New("buffer too short") + errExtHeaderTooShort = errors.New("extension header too short") errInvalidConnType = errors.New("invalid conn type") - errOpNoSupport = errors.New("operation not supported") errNoSuchInterface = errors.New("no such interface") errNoSuchMulticastInterface = errors.New("no such multicast interface") + errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH) - // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html. - freebsdVersion uint32 + // See https://www.freebsd.org/doc/en/books/porters-handbook/versions.html. + freebsdVersion uint32 + compatFreeBSD32 bool // 386 emulation on amd64 ) +// See golang.org/issue/30899. +func adjustFreeBSD32(m *socket.Message) { + // FreeBSD 12.0-RELEASE is affected by https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236737 + if 1200086 <= freebsdVersion && freebsdVersion < 1201000 { + l := (m.NN + 4 - 1) &^ (4 - 1) + if m.NN < l && l <= len(m.OOB) { + m.NN = l + } + } +} + func boolint(b bool) int { if b { return 1 diff --git a/vendor/golang.org/x/net/ipv4/packet.go b/vendor/golang.org/x/net/ipv4/packet.go index f00f5b052..7d784e06d 100644 --- a/vendor/golang.org/x/net/ipv4/packet.go +++ b/vendor/golang.org/x/net/ipv4/packet.go @@ -6,7 +6,6 @@ package ipv4 import ( "net" - "syscall" "golang.org/x/net/internal/socket" ) @@ -28,9 +27,37 @@ func (c *packetHandler) ok() bool { return c != nil && c.IPConn != nil && c.Conn // header h, the payload p and the control message cm. func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) { if !c.ok() { - return nil, nil, nil, syscall.EINVAL + return nil, nil, nil, errInvalidConn } - return c.readFrom(b) + c.rawOpt.RLock() + m := socket.Message{ + Buffers: [][]byte{b}, + OOB: NewControlMessage(c.rawOpt.cflags), + } + c.rawOpt.RUnlock() + if err := c.RecvMsg(&m, 0); err != nil { + return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} + } + var hs []byte + if hs, p, err = slicePacket(b[:m.N]); err != nil { + return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} + } + if h, err = ParseHeader(hs); err != nil { + return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} + } + if m.NN > 0 { + if compatFreeBSD32 { + adjustFreeBSD32(&m) + } + cm = new(ControlMessage) + if err := cm.Parse(m.OOB[:m.NN]); err != nil { + return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} + } + } + if src, ok := m.Addr.(*net.IPAddr); ok && cm != nil { + cm.Src = src.IP + } + return } func slicePacket(b []byte) (h, p []byte, err error) { @@ -63,7 +90,28 @@ func slicePacket(b []byte) (h, p []byte, err error) { // Options = optional func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } - return c.writeTo(h, p, cm) + m := socket.Message{ + OOB: cm.Marshal(), + } + wh, err := h.Marshal() + if err != nil { + return err + } + m.Buffers = [][]byte{wh, p} + dst := new(net.IPAddr) + if cm != nil { + if ip := cm.Dst.To4(); ip != nil { + dst.IP = ip + } + } + if dst.IP == nil { + dst.IP = h.Dst + } + m.Addr = dst + if err := c.SendMsg(&m, 0); err != nil { + return &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Addr: opAddr(dst), Err: err} + } + return nil } diff --git a/vendor/golang.org/x/net/ipv4/packet_go1_8.go b/vendor/golang.org/x/net/ipv4/packet_go1_8.go deleted file mode 100644 index b47d18683..000000000 --- a/vendor/golang.org/x/net/ipv4/packet_go1_8.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 - -package ipv4 - -import "net" - -func (c *packetHandler) readFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) { - c.rawOpt.RLock() - oob := NewControlMessage(c.rawOpt.cflags) - c.rawOpt.RUnlock() - n, nn, _, src, err := c.ReadMsgIP(b, oob) - if err != nil { - return nil, nil, nil, err - } - var hs []byte - if hs, p, err = slicePacket(b[:n]); err != nil { - return nil, nil, nil, err - } - if h, err = ParseHeader(hs); err != nil { - return nil, nil, nil, err - } - if nn > 0 { - cm = new(ControlMessage) - if err := cm.Parse(oob[:nn]); err != nil { - return nil, nil, nil, err - } - } - if src != nil && cm != nil { - cm.Src = src.IP - } - return -} - -func (c *packetHandler) writeTo(h *Header, p []byte, cm *ControlMessage) error { - oob := cm.Marshal() - wh, err := h.Marshal() - if err != nil { - return err - } - dst := new(net.IPAddr) - if cm != nil { - if ip := cm.Dst.To4(); ip != nil { - dst.IP = ip - } - } - if dst.IP == nil { - dst.IP = h.Dst - } - wh = append(wh, p...) - _, _, err = c.WriteMsgIP(wh, oob, dst) - return err -} diff --git a/vendor/golang.org/x/net/ipv4/packet_go1_9.go b/vendor/golang.org/x/net/ipv4/packet_go1_9.go deleted file mode 100644 index 082c36d73..000000000 --- a/vendor/golang.org/x/net/ipv4/packet_go1_9.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.9 - -package ipv4 - -import ( - "net" - - "golang.org/x/net/internal/socket" -) - -func (c *packetHandler) readFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) { - c.rawOpt.RLock() - m := socket.Message{ - Buffers: [][]byte{b}, - OOB: NewControlMessage(c.rawOpt.cflags), - } - c.rawOpt.RUnlock() - if err := c.RecvMsg(&m, 0); err != nil { - return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - var hs []byte - if hs, p, err = slicePacket(b[:m.N]); err != nil { - return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - if h, err = ParseHeader(hs); err != nil { - return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - if m.NN > 0 { - cm = new(ControlMessage) - if err := cm.Parse(m.OOB[:m.NN]); err != nil { - return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - } - if src, ok := m.Addr.(*net.IPAddr); ok && cm != nil { - cm.Src = src.IP - } - return -} - -func (c *packetHandler) writeTo(h *Header, p []byte, cm *ControlMessage) error { - m := socket.Message{ - OOB: cm.Marshal(), - } - wh, err := h.Marshal() - if err != nil { - return err - } - m.Buffers = [][]byte{wh, p} - dst := new(net.IPAddr) - if cm != nil { - if ip := cm.Dst.To4(); ip != nil { - dst.IP = ip - } - } - if dst.IP == nil { - dst.IP = h.Dst - } - m.Addr = dst - if err := c.SendMsg(&m, 0); err != nil { - return &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Addr: opAddr(dst), Err: err} - } - return nil -} diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg.go b/vendor/golang.org/x/net/ipv4/payload_cmsg.go index 3f06d7606..e7614661d 100644 --- a/vendor/golang.org/x/net/ipv4/payload_cmsg.go +++ b/vendor/golang.org/x/net/ipv4/payload_cmsg.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !nacl,!plan9,!windows +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package ipv4 import ( "net" - "syscall" + + "golang.org/x/net/internal/socket" ) // ReadFrom reads a payload of the received IPv4 datagram, from the @@ -17,9 +18,47 @@ import ( // src of the received datagram. func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { if !c.ok() { - return 0, nil, nil, syscall.EINVAL + return 0, nil, nil, errInvalidConn } - return c.readFrom(b) + c.rawOpt.RLock() + m := socket.Message{ + OOB: NewControlMessage(c.rawOpt.cflags), + } + c.rawOpt.RUnlock() + switch c.PacketConn.(type) { + case *net.UDPConn: + m.Buffers = [][]byte{b} + if err := c.RecvMsg(&m, 0); err != nil { + return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} + } + case *net.IPConn: + h := make([]byte, HeaderLen) + m.Buffers = [][]byte{h, b} + if err := c.RecvMsg(&m, 0); err != nil { + return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} + } + hdrlen := int(h[0]&0x0f) << 2 + if hdrlen > len(h) { + d := hdrlen - len(h) + copy(b, b[d:]) + m.N -= d + } else { + m.N -= hdrlen + } + default: + return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType} + } + if m.NN > 0 { + if compatFreeBSD32 { + adjustFreeBSD32(&m) + } + cm = new(ControlMessage) + if err := cm.Parse(m.OOB[:m.NN]); err != nil { + return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} + } + cm.Src = netAddrToIP4(m.Addr) + } + return m.N, cm, m.Addr, nil } // WriteTo writes a payload of the IPv4 datagram, to the destination @@ -30,7 +69,16 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. // control of the outgoing datagram is not required. func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } - return c.writeTo(b, cm, dst) + m := socket.Message{ + Buffers: [][]byte{b}, + OOB: cm.Marshal(), + Addr: dst, + } + err = c.SendMsg(&m, 0) + if err != nil { + err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err} + } + return m.N, err } diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_8.go b/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_8.go deleted file mode 100644 index d26ccd90c..000000000 --- a/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_8.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 -// +build !nacl,!plan9,!windows - -package ipv4 - -import "net" - -func (c *payloadHandler) readFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { - c.rawOpt.RLock() - oob := NewControlMessage(c.rawOpt.cflags) - c.rawOpt.RUnlock() - var nn int - switch c := c.PacketConn.(type) { - case *net.UDPConn: - if n, nn, _, src, err = c.ReadMsgUDP(b, oob); err != nil { - return 0, nil, nil, err - } - case *net.IPConn: - nb := make([]byte, maxHeaderLen+len(b)) - if n, nn, _, src, err = c.ReadMsgIP(nb, oob); err != nil { - return 0, nil, nil, err - } - hdrlen := int(nb[0]&0x0f) << 2 - copy(b, nb[hdrlen:]) - n -= hdrlen - default: - return 0, nil, nil, &net.OpError{Op: "read", Net: c.LocalAddr().Network(), Source: c.LocalAddr(), Err: errInvalidConnType} - } - if nn > 0 { - cm = new(ControlMessage) - if err = cm.Parse(oob[:nn]); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - } - if cm != nil { - cm.Src = netAddrToIP4(src) - } - return -} - -func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { - oob := cm.Marshal() - if dst == nil { - return 0, &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errMissingAddress} - } - switch c := c.PacketConn.(type) { - case *net.UDPConn: - n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr)) - case *net.IPConn: - n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr)) - default: - return 0, &net.OpError{Op: "write", Net: c.LocalAddr().Network(), Source: c.LocalAddr(), Addr: opAddr(dst), Err: errInvalidConnType} - } - return -} diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_9.go b/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_9.go deleted file mode 100644 index 2f1931183..000000000 --- a/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_9.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.9 -// +build !nacl,!plan9,!windows - -package ipv4 - -import ( - "net" - - "golang.org/x/net/internal/socket" -) - -func (c *payloadHandler) readFrom(b []byte) (int, *ControlMessage, net.Addr, error) { - c.rawOpt.RLock() - m := socket.Message{ - OOB: NewControlMessage(c.rawOpt.cflags), - } - c.rawOpt.RUnlock() - switch c.PacketConn.(type) { - case *net.UDPConn: - m.Buffers = [][]byte{b} - if err := c.RecvMsg(&m, 0); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - case *net.IPConn: - h := make([]byte, HeaderLen) - m.Buffers = [][]byte{h, b} - if err := c.RecvMsg(&m, 0); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - hdrlen := int(h[0]&0x0f) << 2 - if hdrlen > len(h) { - d := hdrlen - len(h) - copy(b, b[d:]) - m.N -= d - } else { - m.N -= hdrlen - } - default: - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType} - } - var cm *ControlMessage - if m.NN > 0 { - cm = new(ControlMessage) - if err := cm.Parse(m.OOB[:m.NN]); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - cm.Src = netAddrToIP4(m.Addr) - } - return m.N, cm, m.Addr, nil -} - -func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (int, error) { - m := socket.Message{ - Buffers: [][]byte{b}, - OOB: cm.Marshal(), - Addr: dst, - } - err := c.SendMsg(&m, 0) - if err != nil { - err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err} - } - return m.N, err -} diff --git a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go index 3926de70b..1116256f2 100644 --- a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go +++ b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go @@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build nacl plan9 windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris package ipv4 -import ( - "net" - "syscall" -) +import "net" // ReadFrom reads a payload of the received IPv4 datagram, from the // endpoint c, copying the payload into b. It returns the number of @@ -17,7 +14,7 @@ import ( // src of the received datagram. func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { if !c.ok() { - return 0, nil, nil, syscall.EINVAL + return 0, nil, nil, errInvalidConn } if n, src, err = c.PacketConn.ReadFrom(b); err != nil { return 0, nil, nil, err @@ -33,7 +30,7 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. // control of the outgoing datagram is not required. func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } if dst == nil { return 0, errMissingAddress diff --git a/vendor/golang.org/x/net/ipv4/sockopt_posix.go b/vendor/golang.org/x/net/ipv4/sockopt_posix.go index e96955bc1..dea64519d 100644 --- a/vendor/golang.org/x/net/ipv4/sockopt_posix.go +++ b/vendor/golang.org/x/net/ipv4/sockopt_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows package ipv4 @@ -39,7 +39,7 @@ func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) { return nil, err } if n != sizeofICMPFilter { - return nil, errOpNoSupport + return nil, errNotImplemented } return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil } @@ -58,7 +58,7 @@ func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) erro case ssoTypeGroupReq: return so.setGroupReq(c, ifi, grp) default: - return errOpNoSupport + return errNotImplemented } } diff --git a/vendor/golang.org/x/net/ipv4/sockopt_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_stub.go index 23249b782..37d4806b3 100644 --- a/vendor/golang.org/x/net/ipv4/sockopt_stub.go +++ b/vendor/golang.org/x/net/ipv4/sockopt_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package ipv4 @@ -14,29 +14,29 @@ import ( ) func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) { - return nil, errOpNoSupport + return nil, errNotImplemented } func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) { - return nil, errOpNoSupport + return nil, errNotImplemented } func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv4/sys_aix.go b/vendor/golang.org/x/net/ipv4/sys_aix.go new file mode 100644 index 000000000..3d1201e6d --- /dev/null +++ b/vendor/golang.org/x/net/ipv4/sys_aix.go @@ -0,0 +1,38 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Added for go1.11 compatibility +// +build aix + +package ipv4 + +import ( + "net" + "syscall" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/socket" +) + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL}, + ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, + ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, + } + + sockOpts = map[int]*sockOpt{ + ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}}, + ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}}, + ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}}, + ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}}, + ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}}, + ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}}, + ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}}, + ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}}, + ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}}, + ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, + ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, + } +) diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq.go b/vendor/golang.org/x/net/ipv4/sys_asmreq.go index 0388cba00..c5eaafe96 100644 --- a/vendor/golang.org/x/net/ipv4/sys_asmreq.go +++ b/vendor/golang.org/x/net/ipv4/sys_asmreq.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd netbsd openbsd solaris windows package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go index f3919208b..6dc339ce6 100644 --- a/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go +++ b/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows package ipv4 @@ -13,13 +13,13 @@ import ( ) func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) { - return nil, errOpNoSupport + return nil, errNotImplemented } func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go index 0711d3d78..48ef55624 100644 --- a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go +++ b/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go @@ -13,9 +13,9 @@ import ( ) func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) { - return nil, errOpNoSupport + return nil, errNotImplemented } func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go index 9a2132093..5c9864271 100644 --- a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go +++ b/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go @@ -12,5 +12,5 @@ import ( ) func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv4/sys_darwin.go b/vendor/golang.org/x/net/ipv4/sys_darwin.go index e8fb19169..ac213c735 100644 --- a/vendor/golang.org/x/net/ipv4/sys_darwin.go +++ b/vendor/golang.org/x/net/ipv4/sys_darwin.go @@ -6,8 +6,6 @@ package ipv4 import ( "net" - "strconv" - "strings" "syscall" "unsafe" @@ -17,59 +15,33 @@ import ( var ( ctlOpts = [ctlMax]ctlOpt{ - ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL}, - ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, - ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, + ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL}, + ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, + ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, + ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo}, } sockOpts = map[int]*sockOpt{ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}}, ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}}, ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}}, + ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn}, ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}}, ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}}, ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}}, ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}}, ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}}, ssoStripHeader: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_STRIPHDR, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, + ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, + ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, + ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, + ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, + ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, + ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, + ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}}, } ) -func init() { - // Seems like kern.osreldate is veiled on latest OS X. We use - // kern.osrelease instead. - s, err := syscall.Sysctl("kern.osrelease") - if err != nil { - return - } - ss := strings.Split(s, ".") - if len(ss) == 0 { - return - } - // The IP_PKTINFO and protocol-independent multicast API were - // introduced in OS X 10.7 (Darwin 11). But it looks like - // those features require OS X 10.8 (Darwin 12) or above. - // See http://support.apple.com/kb/HT1633. - if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 12 { - return - } - ctlOpts[ctlPacketInfo].name = sysIP_PKTINFO - ctlOpts[ctlPacketInfo].length = sizeofInetPktinfo - ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo - ctlOpts[ctlPacketInfo].parse = parsePacketInfo - sockOpts[ssoPacketInfo] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}} - sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn} - sockOpts[ssoJoinGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq} - sockOpts[ssoLeaveGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq} - sockOpts[ssoJoinSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq} - sockOpts[ssoLeaveSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq} - sockOpts[ssoBlockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq} - sockOpts[ssoUnblockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq} -} - func (pi *inetPktinfo) setIfindex(i int) { pi.Ifindex = uint32(i) } diff --git a/vendor/golang.org/x/net/ipv4/sys_freebsd.go b/vendor/golang.org/x/net/ipv4/sys_freebsd.go index b80032454..482873d9a 100644 --- a/vendor/golang.org/x/net/ipv4/sys_freebsd.go +++ b/vendor/golang.org/x/net/ipv4/sys_freebsd.go @@ -50,7 +50,7 @@ func init() { archs, _ := syscall.Sysctl("kern.supported_archs") for _, s := range strings.Fields(archs) { if s == "amd64" { - freebsd32o64 = true + compatFreeBSD32 = true break } } diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq.go index ae5704e77..eeced7f31 100644 --- a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go +++ b/vendor/golang.org/x/net/ipv4/sys_ssmreq.go @@ -13,8 +13,6 @@ import ( "golang.org/x/net/internal/socket" ) -var freebsd32o64 bool - func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { var gr groupReq if ifi != nil { @@ -22,7 +20,7 @@ func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) e } gr.setGroup(grp) var b []byte - if freebsd32o64 { + if compatFreeBSD32 { var d [sizeofGroupReq + 4]byte s := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr)) copy(d[:4], s[:4]) @@ -41,7 +39,7 @@ func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, sr } gsr.setSourceGroup(grp, src) var b []byte - if freebsd32o64 { + if compatFreeBSD32 { var d [sizeofGroupSourceReq + 4]byte s := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr)) copy(d[:4], s[:4]) diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go index e6b7623d0..c0921674b 100644 --- a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go +++ b/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go @@ -13,9 +13,9 @@ import ( ) func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv4/sys_stub.go b/vendor/golang.org/x/net/ipv4/sys_stub.go index 4f076473b..b9c85b334 100644 --- a/vendor/golang.org/x/net/ipv4/sys_stub.go +++ b/vendor/golang.org/x/net/ipv4/sys_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go new file mode 100644 index 000000000..c741d5c8e --- /dev/null +++ b/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go @@ -0,0 +1,33 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_aix.go + +// Added for go1.11 compatibility +// +build aix + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x20 + sysIP_RECVTTL = 0x22 + + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + + sizeofIPMreq = 0x8 +) + +type ipMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} diff --git a/vendor/golang.org/x/net/ipv4/zsys_darwin.go b/vendor/golang.org/x/net/ipv4/zsys_darwin.go index c07cc883f..e05a251ba 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_darwin.go +++ b/vendor/golang.org/x/net/ipv4/zsys_darwin.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_darwin.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go b/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go index c4365e9e7..6d65e9fcb 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go +++ b/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_dragonfly.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go index 8c4aec94c..136e2b8f1 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go +++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go index 4b10b7c57..4f730f19e 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go +++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go index 4b10b7c57..4f730f19e 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go +++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_386.go b/vendor/golang.org/x/net/ipv4/zsys_linux_386.go index c0260f0ce..43ef8e592 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_386.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_386.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go index 9c967eaa6..ee8204da4 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go index c0260f0ce..43ef8e592 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go index 9c967eaa6..ee8204da4 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go index c0260f0ce..43ef8e592 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go index 9c967eaa6..ee8204da4 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go index 9c967eaa6..ee8204da4 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go index c0260f0ce..43ef8e592 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go index f65bd9a7a..fa1b6bc61 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go index 9c967eaa6..ee8204da4 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go index 9c967eaa6..ee8204da4 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go new file mode 100644 index 000000000..0c0d48012 --- /dev/null +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go @@ -0,0 +1,151 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_linux.go + +// +build riscv64 + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSOL_SOCKET = 0x1 + sysSO_ATTACH_FILTER = 0x1a + + sizeofKernelSockaddrStorage = 0x80 + sizeofSockaddrInet = 0x10 + sizeofInetPktinfo = 0xc + sizeofSockExtendedErr = 0x10 + + sizeofIPMreq = 0x8 + sizeofIPMreqn = 0xc + sizeofIPMreqSource = 0xc + sizeofGroupReq = 0x88 + sizeofGroupSourceReq = 0x108 + + sizeofICMPFilter = 0x4 + + sizeofSockFprog = 0x10 +) + +type kernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type inetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type ipMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type ipMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type ipMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type groupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group kernelSockaddrStorage +} + +type groupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group kernelSockaddrStorage + Source kernelSockaddrStorage +} + +type icmpFilter struct { + Data uint32 +} + +type sockFProg struct { + Len uint16 + Filter *sockFilter +} + +type sockFilter struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go b/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go index 9c967eaa6..ee8204da4 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go +++ b/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_netbsd.go b/vendor/golang.org/x/net/ipv4/zsys_netbsd.go index fd3624d93..8cfc648ad 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_netbsd.go +++ b/vendor/golang.org/x/net/ipv4/zsys_netbsd.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_netbsd.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_openbsd.go b/vendor/golang.org/x/net/ipv4/zsys_openbsd.go index 12f36be75..37629cb0a 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_openbsd.go +++ b/vendor/golang.org/x/net/ipv4/zsys_openbsd.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_openbsd.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv4/zsys_solaris.go b/vendor/golang.org/x/net/ipv4/zsys_solaris.go index 0a3875cc4..cb80a308b 100644 --- a/vendor/golang.org/x/net/ipv4/zsys_solaris.go +++ b/vendor/golang.org/x/net/ipv4/zsys_solaris.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_solaris.go package ipv4 diff --git a/vendor/golang.org/x/net/ipv6/batch.go b/vendor/golang.org/x/net/ipv6/batch.go index 4f5fe683d..2ccb9849c 100644 --- a/vendor/golang.org/x/net/ipv6/batch.go +++ b/vendor/golang.org/x/net/ipv6/batch.go @@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.9 - package ipv6 import ( "net" "runtime" - "syscall" "golang.org/x/net/internal/socket" ) @@ -67,7 +64,7 @@ type Message = socket.Message // On other platforms, this method will read only a single message. func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": @@ -98,7 +95,7 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { // On other platforms, this method will write only a single message. func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": diff --git a/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go b/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go index eec529c20..8c221b598 100644 --- a/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go +++ b/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/control_stub.go b/vendor/golang.org/x/net/ipv6/control_stub.go index a045f28f7..1d773cbcc 100644 --- a/vendor/golang.org/x/net/ipv6/control_stub.go +++ b/vendor/golang.org/x/net/ipv6/control_stub.go @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package ipv6 import "golang.org/x/net/internal/socket" func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv6/control_unix.go b/vendor/golang.org/x/net/ipv6/control_unix.go index 66515060a..0971a008b 100644 --- a/vendor/golang.org/x/net/ipv6/control_unix.go +++ b/vendor/golang.org/x/net/ipv6/control_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/control_windows.go b/vendor/golang.org/x/net/ipv6/control_windows.go index ef2563b3f..8882d8193 100644 --- a/vendor/golang.org/x/net/ipv6/control_windows.go +++ b/vendor/golang.org/x/net/ipv6/control_windows.go @@ -4,13 +4,9 @@ package ipv6 -import ( - "syscall" - - "golang.org/x/net/internal/socket" -) +import "golang.org/x/net/internal/socket" func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { // TODO(mikio): implement this - return syscall.EWINDOWS + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv6/defs_aix.go b/vendor/golang.org/x/net/ipv6/defs_aix.go new file mode 100644 index 000000000..ea396a3cb --- /dev/null +++ b/vendor/golang.org/x/net/ipv6/defs_aix.go @@ -0,0 +1,82 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package ipv6 + +/* +#include +#include + +#include +#include +*/ +import "C" + +const ( + sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS + sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF + sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS + sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP + sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP + sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP + sysICMP6_FILTER = C.ICMP6_FILTER + + sysIPV6_CHECKSUM = C.IPV6_CHECKSUM + sysIPV6_V6ONLY = C.IPV6_V6ONLY + + sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS + + sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO + sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT + sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR + sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS + sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS + + sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU + sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU + sysIPV6_PATHMTU = C.IPV6_PATHMTU + + sysIPV6_PKTINFO = C.IPV6_PKTINFO + sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT + sysIPV6_NEXTHOP = C.IPV6_NEXTHOP + sysIPV6_HOPOPTS = C.IPV6_HOPOPTS + sysIPV6_DSTOPTS = C.IPV6_DSTOPTS + sysIPV6_RTHDR = C.IPV6_RTHDR + + sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS + + sysIPV6_TCLASS = C.IPV6_TCLASS + sysIPV6_DONTFRAG = C.IPV6_DONTFRAG + + sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage + sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 + sizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo + sizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo + + sizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq + sizeofGroupReq = C.sizeof_struct_group_req + sizeofGroupSourceReq = C.sizeof_struct_group_source_req + + sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter +) + +type sockaddrStorage C.struct_sockaddr_storage + +type sockaddrInet6 C.struct_sockaddr_in6 + +type inet6Pktinfo C.struct_in6_pktinfo + +type ipv6Mtuinfo C.struct_ip6_mtuinfo + +type ipv6Mreq C.struct_ipv6_mreq + +type icmpv6Filter C.struct_icmp6_filter + +type groupReq C.struct_group_req + +type groupSourceReq C.struct_group_source_req diff --git a/vendor/golang.org/x/net/ipv6/dgramopt.go b/vendor/golang.org/x/net/ipv6/dgramopt.go index 703dafe84..1f422e71d 100644 --- a/vendor/golang.org/x/net/ipv6/dgramopt.go +++ b/vendor/golang.org/x/net/ipv6/dgramopt.go @@ -6,7 +6,6 @@ package ipv6 import ( "net" - "syscall" "golang.org/x/net/bpf" ) @@ -15,11 +14,11 @@ import ( // multicast packets. func (c *dgramOpt) MulticastHopLimit() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoMulticastHopLimit] if !ok { - return 0, errOpNoSupport + return 0, errNotImplemented } return so.GetInt(c.Conn) } @@ -28,11 +27,11 @@ func (c *dgramOpt) MulticastHopLimit() (int, error) { // outgoing multicast packets. func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastHopLimit] if !ok { - return errOpNoSupport + return errNotImplemented } return so.SetInt(c.Conn, hoplim) } @@ -41,11 +40,11 @@ func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error { // packet transmissions. func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { if !c.ok() { - return nil, syscall.EINVAL + return nil, errInvalidConn } so, ok := sockOpts[ssoMulticastInterface] if !ok { - return nil, errOpNoSupport + return nil, errNotImplemented } return so.getMulticastInterface(c.Conn) } @@ -54,11 +53,11 @@ func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { // multicast packet transmissions. func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastInterface] if !ok { - return errOpNoSupport + return errNotImplemented } return so.setMulticastInterface(c.Conn, ifi) } @@ -67,11 +66,11 @@ func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { // should be copied and send back to the originator. func (c *dgramOpt) MulticastLoopback() (bool, error) { if !c.ok() { - return false, syscall.EINVAL + return false, errInvalidConn } so, ok := sockOpts[ssoMulticastLoopback] if !ok { - return false, errOpNoSupport + return false, errNotImplemented } on, err := so.GetInt(c.Conn) if err != nil { @@ -84,11 +83,11 @@ func (c *dgramOpt) MulticastLoopback() (bool, error) { // should be copied and send back to the originator. func (c *dgramOpt) SetMulticastLoopback(on bool) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastLoopback] if !ok { - return errOpNoSupport + return errNotImplemented } return so.SetInt(c.Conn, boolint(on)) } @@ -104,11 +103,11 @@ func (c *dgramOpt) SetMulticastLoopback(on bool) error { // configuration. func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoJoinGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP16(group) if grp == nil { @@ -122,11 +121,11 @@ func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { // source-specific group. func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoLeaveGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP16(group) if grp == nil { @@ -143,11 +142,11 @@ func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { // routing configuration. func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoJoinSourceGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP16(group) if grp == nil { @@ -164,11 +163,11 @@ func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net // interface ifi. func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoLeaveSourceGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP16(group) if grp == nil { @@ -186,11 +185,11 @@ func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source ne // ifi. func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoBlockSourceGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP16(group) if grp == nil { @@ -207,11 +206,11 @@ func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source // group by ExcludeSourceSpecificGroup again on the interface ifi. func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoUnblockSourceGroup] if !ok { - return errOpNoSupport + return errNotImplemented } grp := netAddrToIP16(group) if grp == nil { @@ -230,11 +229,11 @@ func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source // field is located. func (c *dgramOpt) Checksum() (on bool, offset int, err error) { if !c.ok() { - return false, 0, syscall.EINVAL + return false, 0, errInvalidConn } so, ok := sockOpts[ssoChecksum] if !ok { - return false, 0, errOpNoSupport + return false, 0, errNotImplemented } offset, err = so.GetInt(c.Conn) if err != nil { @@ -251,11 +250,11 @@ func (c *dgramOpt) Checksum() (on bool, offset int, err error) { // checksum field is located. func (c *dgramOpt) SetChecksum(on bool, offset int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoChecksum] if !ok { - return errOpNoSupport + return errNotImplemented } if !on { offset = -1 @@ -266,11 +265,11 @@ func (c *dgramOpt) SetChecksum(on bool, offset int) error { // ICMPFilter returns an ICMP filter. func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { if !c.ok() { - return nil, syscall.EINVAL + return nil, errInvalidConn } so, ok := sockOpts[ssoICMPFilter] if !ok { - return nil, errOpNoSupport + return nil, errNotImplemented } return so.getICMPFilter(c.Conn) } @@ -278,11 +277,11 @@ func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { // SetICMPFilter deploys the ICMP filter. func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoICMPFilter] if !ok { - return errOpNoSupport + return errNotImplemented } return so.setICMPFilter(c.Conn, f) } @@ -292,11 +291,11 @@ func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { // Only supported on Linux. func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoAttachFilter] if !ok { - return errOpNoSupport + return errNotImplemented } return so.setBPF(c.Conn, filter) } diff --git a/vendor/golang.org/x/net/ipv6/doc.go b/vendor/golang.org/x/net/ipv6/doc.go index 664a97dea..e0be9d50d 100644 --- a/vendor/golang.org/x/net/ipv6/doc.go +++ b/vendor/golang.org/x/net/ipv6/doc.go @@ -56,7 +56,7 @@ // Multicasting // // The options for multicasting are available for net.UDPConn and -// net.IPconn which are created as network connections that use the +// net.IPConn which are created as network connections that use the // IPv6 transport. A few network facilities must be prepared before // you begin multicasting, at a minimum joining network interfaces and // multicast groups. @@ -240,4 +240,4 @@ // IncludeSourceSpecificGroup may return an error. package ipv6 // import "golang.org/x/net/ipv6" -// BUG(mikio): This package is not implemented on NaCl and Plan 9. +// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9. diff --git a/vendor/golang.org/x/net/ipv6/endpoint.go b/vendor/golang.org/x/net/ipv6/endpoint.go index 0624c1740..f534a0bf3 100644 --- a/vendor/golang.org/x/net/ipv6/endpoint.go +++ b/vendor/golang.org/x/net/ipv6/endpoint.go @@ -6,7 +6,6 @@ package ipv6 import ( "net" - "syscall" "time" "golang.org/x/net/internal/socket" @@ -34,11 +33,11 @@ func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil } // with the endpoint. func (c *Conn) PathMTU() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoPathMTU] if !ok { - return 0, errOpNoSupport + return 0, errNotImplemented } _, mtu, err := so.getMTUInfo(c.Conn) if err != nil { @@ -76,7 +75,7 @@ func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil } // socket options. func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on) } @@ -85,7 +84,7 @@ func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { // endpoint. func (c *PacketConn) SetDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.SetDeadline(t) } @@ -94,7 +93,7 @@ func (c *PacketConn) SetDeadline(t time.Time) error { // endpoint. func (c *PacketConn) SetReadDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.SetReadDeadline(t) } @@ -103,7 +102,7 @@ func (c *PacketConn) SetReadDeadline(t time.Time) error { // endpoint. func (c *PacketConn) SetWriteDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.SetWriteDeadline(t) } @@ -111,7 +110,7 @@ func (c *PacketConn) SetWriteDeadline(t time.Time) error { // Close closes the endpoint. func (c *PacketConn) Close() error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.Close() } diff --git a/vendor/golang.org/x/net/ipv6/genericopt.go b/vendor/golang.org/x/net/ipv6/genericopt.go index e9dbc2e18..0326aed6d 100644 --- a/vendor/golang.org/x/net/ipv6/genericopt.go +++ b/vendor/golang.org/x/net/ipv6/genericopt.go @@ -4,17 +4,15 @@ package ipv6 -import "syscall" - // TrafficClass returns the traffic class field value for outgoing // packets. func (c *genericOpt) TrafficClass() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoTrafficClass] if !ok { - return 0, errOpNoSupport + return 0, errNotImplemented } return so.GetInt(c.Conn) } @@ -23,11 +21,11 @@ func (c *genericOpt) TrafficClass() (int, error) { // outgoing packets. func (c *genericOpt) SetTrafficClass(tclass int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoTrafficClass] if !ok { - return errOpNoSupport + return errNotImplemented } return so.SetInt(c.Conn, tclass) } @@ -35,11 +33,11 @@ func (c *genericOpt) SetTrafficClass(tclass int) error { // HopLimit returns the hop limit field value for outgoing packets. func (c *genericOpt) HopLimit() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoHopLimit] if !ok { - return 0, errOpNoSupport + return 0, errNotImplemented } return so.GetInt(c.Conn) } @@ -48,11 +46,11 @@ func (c *genericOpt) HopLimit() (int, error) { // packets. func (c *genericOpt) SetHopLimit(hoplim int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoHopLimit] if !ok { - return errOpNoSupport + return errNotImplemented } return so.SetInt(c.Conn, hoplim) } diff --git a/vendor/golang.org/x/net/ipv6/helper.go b/vendor/golang.org/x/net/ipv6/helper.go index 259740132..f767b1f5d 100644 --- a/vendor/golang.org/x/net/ipv6/helper.go +++ b/vendor/golang.org/x/net/ipv6/helper.go @@ -7,14 +7,16 @@ package ipv6 import ( "errors" "net" + "runtime" ) var ( + errInvalidConn = errors.New("invalid connection") errMissingAddress = errors.New("missing address") errHeaderTooShort = errors.New("header too short") errInvalidConnType = errors.New("invalid conn type") - errOpNoSupport = errors.New("operation not supported") errNoSuchInterface = errors.New("no such interface") + errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH) ) func boolint(b bool) int { diff --git a/vendor/golang.org/x/net/ipv6/icmp_bsd.go b/vendor/golang.org/x/net/ipv6/icmp_bsd.go index e1a791de4..b03025cdc 100644 --- a/vendor/golang.org/x/net/ipv6/icmp_bsd.go +++ b/vendor/golang.org/x/net/ipv6/icmp_bsd.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd netbsd openbsd +// +build aix darwin dragonfly freebsd netbsd openbsd package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/icmp_stub.go b/vendor/golang.org/x/net/ipv6/icmp_stub.go index c4b9be6db..370e51acd 100644 --- a/vendor/golang.org/x/net/ipv6/icmp_stub.go +++ b/vendor/golang.org/x/net/ipv6/icmp_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg.go b/vendor/golang.org/x/net/ipv6/payload_cmsg.go index 4ee4b062c..284a04278 100644 --- a/vendor/golang.org/x/net/ipv6/payload_cmsg.go +++ b/vendor/golang.org/x/net/ipv6/payload_cmsg.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !nacl,!plan9,!windows +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package ipv6 import ( "net" - "syscall" + + "golang.org/x/net/internal/socket" ) // ReadFrom reads a payload of the received IPv6 datagram, from the @@ -17,9 +18,34 @@ import ( // src of the received datagram. func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { if !c.ok() { - return 0, nil, nil, syscall.EINVAL + return 0, nil, nil, errInvalidConn } - return c.readFrom(b) + c.rawOpt.RLock() + m := socket.Message{ + Buffers: [][]byte{b}, + OOB: NewControlMessage(c.rawOpt.cflags), + } + c.rawOpt.RUnlock() + switch c.PacketConn.(type) { + case *net.UDPConn: + if err := c.RecvMsg(&m, 0); err != nil { + return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} + } + case *net.IPConn: + if err := c.RecvMsg(&m, 0); err != nil { + return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} + } + default: + return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType} + } + if m.NN > 0 { + cm = new(ControlMessage) + if err := cm.Parse(m.OOB[:m.NN]); err != nil { + return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} + } + cm.Src = netAddrToIP16(m.Addr) + } + return m.N, cm, m.Addr, nil } // WriteTo writes a payload of the IPv6 datagram, to the destination @@ -29,7 +55,16 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. // cm may be nil if control of the outgoing datagram is not required. func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } - return c.writeTo(b, cm, dst) + m := socket.Message{ + Buffers: [][]byte{b}, + OOB: cm.Marshal(), + Addr: dst, + } + err = c.SendMsg(&m, 0) + if err != nil { + err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err} + } + return m.N, err } diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_8.go b/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_8.go deleted file mode 100644 index fdc6c3994..000000000 --- a/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_8.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 -// +build !nacl,!plan9,!windows - -package ipv6 - -import "net" - -func (c *payloadHandler) readFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { - c.rawOpt.RLock() - oob := NewControlMessage(c.rawOpt.cflags) - c.rawOpt.RUnlock() - var nn int - switch c := c.PacketConn.(type) { - case *net.UDPConn: - if n, nn, _, src, err = c.ReadMsgUDP(b, oob); err != nil { - return 0, nil, nil, err - } - case *net.IPConn: - if n, nn, _, src, err = c.ReadMsgIP(b, oob); err != nil { - return 0, nil, nil, err - } - default: - return 0, nil, nil, &net.OpError{Op: "read", Net: c.LocalAddr().Network(), Source: c.LocalAddr(), Err: errInvalidConnType} - } - if nn > 0 { - cm = new(ControlMessage) - if err = cm.Parse(oob[:nn]); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - } - if cm != nil { - cm.Src = netAddrToIP16(src) - } - return -} - -func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { - oob := cm.Marshal() - if dst == nil { - return 0, &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errMissingAddress} - } - switch c := c.PacketConn.(type) { - case *net.UDPConn: - n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr)) - case *net.IPConn: - n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr)) - default: - return 0, &net.OpError{Op: "write", Net: c.LocalAddr().Network(), Source: c.LocalAddr(), Addr: opAddr(dst), Err: errInvalidConnType} - } - return -} diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_9.go b/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_9.go deleted file mode 100644 index 8f6d02e2f..000000000 --- a/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_9.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.9 -// +build !nacl,!plan9,!windows - -package ipv6 - -import ( - "net" - - "golang.org/x/net/internal/socket" -) - -func (c *payloadHandler) readFrom(b []byte) (int, *ControlMessage, net.Addr, error) { - c.rawOpt.RLock() - m := socket.Message{ - Buffers: [][]byte{b}, - OOB: NewControlMessage(c.rawOpt.cflags), - } - c.rawOpt.RUnlock() - switch c.PacketConn.(type) { - case *net.UDPConn: - if err := c.RecvMsg(&m, 0); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - case *net.IPConn: - if err := c.RecvMsg(&m, 0); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - default: - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType} - } - var cm *ControlMessage - if m.NN > 0 { - cm = new(ControlMessage) - if err := cm.Parse(m.OOB[:m.NN]); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - cm.Src = netAddrToIP16(m.Addr) - } - return m.N, cm, m.Addr, nil -} - -func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (int, error) { - m := socket.Message{ - Buffers: [][]byte{b}, - OOB: cm.Marshal(), - Addr: dst, - } - err := c.SendMsg(&m, 0) - if err != nil { - err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err} - } - return m.N, err -} diff --git a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go index 99a43542b..c5a4c9675 100644 --- a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go +++ b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go @@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build nacl plan9 windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris package ipv6 -import ( - "net" - "syscall" -) +import "net" // ReadFrom reads a payload of the received IPv6 datagram, from the // endpoint c, copying the payload into b. It returns the number of @@ -17,7 +14,7 @@ import ( // src of the received datagram. func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { if !c.ok() { - return 0, nil, nil, syscall.EINVAL + return 0, nil, nil, errInvalidConn } if n, src, err = c.PacketConn.ReadFrom(b); err != nil { return 0, nil, nil, err @@ -32,7 +29,7 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. // cm may be nil if control of the outgoing datagram is not required. func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } if dst == nil { return 0, errMissingAddress diff --git a/vendor/golang.org/x/net/ipv6/sockopt_posix.go b/vendor/golang.org/x/net/ipv6/sockopt_posix.go index 0eac86eb8..824c623cc 100644 --- a/vendor/golang.org/x/net/ipv6/sockopt_posix.go +++ b/vendor/golang.org/x/net/ipv6/sockopt_posix.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows package ipv6 import ( "net" + "runtime" "unsafe" "golang.org/x/net/bpf" @@ -37,7 +38,7 @@ func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) { return nil, err } if n != sizeofICMPv6Filter { - return nil, errOpNoSupport + return nil, errNotImplemented } return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil } @@ -54,10 +55,11 @@ func (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) { return nil, 0, err } if n != sizeofIPv6Mtuinfo { - return nil, 0, errOpNoSupport + return nil, 0, errNotImplemented } mi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0])) - if mi.Addr.Scope_id == 0 { + if mi.Addr.Scope_id == 0 || runtime.GOOS == "aix" { + // AIX kernel might return a wrong address. return nil, int(mi.Mtu), nil } ifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id)) @@ -74,7 +76,7 @@ func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) erro case ssoTypeGroupReq: return so.setGroupReq(c, ifi, grp) default: - return errOpNoSupport + return errNotImplemented } } diff --git a/vendor/golang.org/x/net/ipv6/sockopt_stub.go b/vendor/golang.org/x/net/ipv6/sockopt_stub.go index 1f4a273e4..0a87a93bb 100644 --- a/vendor/golang.org/x/net/ipv6/sockopt_stub.go +++ b/vendor/golang.org/x/net/ipv6/sockopt_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package ipv6 @@ -14,33 +14,33 @@ import ( ) func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) { - return nil, errOpNoSupport + return nil, errNotImplemented } func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) { - return nil, errOpNoSupport + return nil, errNotImplemented } func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) { - return nil, 0, errOpNoSupport + return nil, 0, errNotImplemented } func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv6/sys_aix.go b/vendor/golang.org/x/net/ipv6/sys_aix.go new file mode 100644 index 000000000..bce7091fb --- /dev/null +++ b/vendor/golang.org/x/net/ipv6/sys_aix.go @@ -0,0 +1,77 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Added for go1.11 compatibility +// +build aix + +package ipv6 + +import ( + "net" + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/socket" +) + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass}, + ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit}, + ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo}, + ctlNextHop: {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop}, + ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU}, + } + + sockOpts = map[int]*sockOpt{ + ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}}, + ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}}, + ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}}, + ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}}, + ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}}, + ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}}, + ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}}, + ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}}, + ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}}, + ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}}, + ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}}, + ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}}, + ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq}, + ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq}, + } +) + +func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) { + sa.Len = sizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], ip) + sa.Scope_id = uint32(i) +} + +func (pi *inet6Pktinfo) setIfindex(i int) { + pi.Ifindex = int32(i) +} + +func (mreq *ipv6Mreq) setIfindex(i int) { + mreq.Interface = uint32(i) +} + +func (gr *groupReq) setGroup(grp net.IP) { + sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4)) + sa.Len = sizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], grp) +} + +func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) { + sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4)) + sa.Len = sizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], grp) + sa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132)) + sa.Len = sizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], src) +} diff --git a/vendor/golang.org/x/net/ipv6/sys_asmreq.go b/vendor/golang.org/x/net/ipv6/sys_asmreq.go index b0510c0b5..8c3934c3e 100644 --- a/vendor/golang.org/x/net/ipv6/sys_asmreq.go +++ b/vendor/golang.org/x/net/ipv6/sys_asmreq.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go index eece96187..87ae48181 100644 --- a/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go +++ b/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package ipv6 @@ -13,5 +13,5 @@ import ( ) func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go index 676bea555..eb9f83162 100644 --- a/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go +++ b/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go @@ -12,5 +12,5 @@ import ( ) func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv6/sys_darwin.go b/vendor/golang.org/x/net/ipv6/sys_darwin.go index e3d044392..12cc5cb2c 100644 --- a/vendor/golang.org/x/net/ipv6/sys_darwin.go +++ b/vendor/golang.org/x/net/ipv6/sys_darwin.go @@ -6,8 +6,6 @@ package ipv6 import ( "net" - "strconv" - "strings" "syscall" "unsafe" @@ -17,61 +15,35 @@ import ( var ( ctlOpts = [ctlMax]ctlOpt{ - ctlHopLimit: {sysIPV6_2292HOPLIMIT, 4, marshal2292HopLimit, parseHopLimit}, - ctlPacketInfo: {sysIPV6_2292PKTINFO, sizeofInet6Pktinfo, marshal2292PacketInfo, parsePacketInfo}, + ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass}, + ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit}, + ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo}, + ctlNextHop: {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop}, + ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU}, } sockOpts = map[int]*sockOpt{ - ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}}, - ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}}, - ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_2292HOPLIMIT, Len: 4}}, - ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_2292PKTINFO, Len: 4}}, - ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}}, - ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq}, + ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}}, + ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}}, + ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}}, + ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}}, + ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}}, + ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}}, + ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}}, + ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}}, + ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}}, + ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}}, + ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}}, + ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}}, + ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, + ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, + ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, + ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, + ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, + ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, } ) -func init() { - // Seems like kern.osreldate is veiled on latest OS X. We use - // kern.osrelease instead. - s, err := syscall.Sysctl("kern.osrelease") - if err != nil { - return - } - ss := strings.Split(s, ".") - if len(ss) == 0 { - return - } - // The IP_PKTINFO and protocol-independent multicast API were - // introduced in OS X 10.7 (Darwin 11). But it looks like - // those features require OS X 10.8 (Darwin 12) or above. - // See http://support.apple.com/kb/HT1633. - if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 12 { - return - } - ctlOpts[ctlTrafficClass] = ctlOpt{sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass} - ctlOpts[ctlHopLimit] = ctlOpt{sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit} - ctlOpts[ctlPacketInfo] = ctlOpt{sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo} - ctlOpts[ctlNextHop] = ctlOpt{sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop} - ctlOpts[ctlPathMTU] = ctlOpt{sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU} - sockOpts[ssoTrafficClass] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}} - sockOpts[ssoReceiveTrafficClass] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}} - sockOpts[ssoReceiveHopLimit] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}} - sockOpts[ssoReceivePacketInfo] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}} - sockOpts[ssoReceivePathMTU] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}} - sockOpts[ssoPathMTU] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}} - sockOpts[ssoJoinGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq} - sockOpts[ssoLeaveGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq} - sockOpts[ssoJoinSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq} - sockOpts[ssoLeaveSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq} - sockOpts[ssoBlockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq} - sockOpts[ssoUnblockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq} -} - func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) { sa.Len = sizeofSockaddrInet6 sa.Family = syscall.AF_INET6 diff --git a/vendor/golang.org/x/net/ipv6/sys_freebsd.go b/vendor/golang.org/x/net/ipv6/sys_freebsd.go index e9349dc2c..85a9f5d07 100644 --- a/vendor/golang.org/x/net/ipv6/sys_freebsd.go +++ b/vendor/golang.org/x/net/ipv6/sys_freebsd.go @@ -51,7 +51,7 @@ func init() { archs, _ := syscall.Sysctl("kern.supported_archs") for _, s := range strings.Fields(archs) { if s == "amd64" { - freebsd32o64 = true + compatFreeBSD32 = true break } } diff --git a/vendor/golang.org/x/net/ipv6/sys_ssmreq.go b/vendor/golang.org/x/net/ipv6/sys_ssmreq.go index add8ccc0b..9b52e978c 100644 --- a/vendor/golang.org/x/net/ipv6/sys_ssmreq.go +++ b/vendor/golang.org/x/net/ipv6/sys_ssmreq.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin freebsd linux solaris +// +build aix darwin freebsd linux solaris package ipv6 @@ -13,7 +13,7 @@ import ( "golang.org/x/net/internal/socket" ) -var freebsd32o64 bool +var compatFreeBSD32 bool // 386 emulation on amd64 func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { var gr groupReq @@ -22,7 +22,7 @@ func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) e } gr.setGroup(grp) var b []byte - if freebsd32o64 { + if compatFreeBSD32 { var d [sizeofGroupReq + 4]byte s := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr)) copy(d[:4], s[:4]) @@ -41,7 +41,7 @@ func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, sr } gsr.setSourceGroup(grp, src) var b []byte - if freebsd32o64 { + if compatFreeBSD32 { var d [sizeofGroupSourceReq + 4]byte s := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr)) copy(d[:4], s[:4]) diff --git a/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go index 581ee490f..d5bc1108c 100644 --- a/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go +++ b/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!freebsd,!linux,!solaris +// +build !aix,!darwin,!freebsd,!linux,!solaris package ipv6 @@ -13,9 +13,9 @@ import ( ) func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errOpNoSupport + return errNotImplemented } func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { - return errOpNoSupport + return errNotImplemented } diff --git a/vendor/golang.org/x/net/ipv6/sys_stub.go b/vendor/golang.org/x/net/ipv6/sys_stub.go index b845388ea..4f252d09f 100644 --- a/vendor/golang.org/x/net/ipv6/sys_stub.go +++ b/vendor/golang.org/x/net/ipv6/sys_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go new file mode 100644 index 000000000..bf44e338b --- /dev/null +++ b/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go @@ -0,0 +1,103 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_aix.go + +// Added for go1.11 compatibility +// +build aix + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysICMP6_FILTER = 0x26 + + sysIPV6_CHECKSUM = 0x27 + sysIPV6_V6ONLY = 0x25 + + sysIPV6_RTHDRDSTOPTS = 0x37 + + sysIPV6_RECVPKTINFO = 0x23 + sysIPV6_RECVHOPLIMIT = 0x29 + sysIPV6_RECVRTHDR = 0x33 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_RECVDSTOPTS = 0x38 + + sysIPV6_USE_MIN_MTU = 0x2c + sysIPV6_RECVPATHMTU = 0x2f + sysIPV6_PATHMTU = 0x2e + + sysIPV6_PKTINFO = 0x21 + sysIPV6_HOPLIMIT = 0x28 + sysIPV6_NEXTHOP = 0x30 + sysIPV6_HOPOPTS = 0x34 + sysIPV6_DSTOPTS = 0x36 + sysIPV6_RTHDR = 0x32 + + sysIPV6_RECVTCLASS = 0x2a + + sysIPV6_TCLASS = 0x2b + sysIPV6_DONTFRAG = 0x2d + + sizeofSockaddrStorage = 0x508 + sizeofSockaddrInet6 = 0x1c + sizeofInet6Pktinfo = 0x14 + sizeofIPv6Mtuinfo = 0x20 + + sizeofIPv6Mreq = 0x14 + sizeofGroupReq = 0x510 + sizeofGroupSourceReq = 0xa18 + + sizeofICMPv6Filter = 0x20 +) + +type sockaddrStorage struct { + X__ss_len uint8 + Family uint8 + X__ss_pad1 [6]uint8 + X__ss_align int64 + X__ss_pad2 [1265]uint8 + Pad_cgo_0 [7]byte +} + +type sockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type ipv6Mtuinfo struct { + Addr sockaddrInet6 + Mtu uint32 +} + +type ipv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type icmpv6Filter struct { + Filt [8]uint32 +} + +type groupReq struct { + Interface uint32 + Group sockaddrStorage +} + +type groupSourceReq struct { + Interface uint32 + Group sockaddrStorage + Source sockaddrStorage +} diff --git a/vendor/golang.org/x/net/ipv6/zsys_darwin.go b/vendor/golang.org/x/net/ipv6/zsys_darwin.go index 6aab1dfab..555744afd 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_darwin.go +++ b/vendor/golang.org/x/net/ipv6/zsys_darwin.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_darwin.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go b/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go index d2de804d8..cf3cc1024 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go +++ b/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_dragonfly.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go index 919e572d4..73f31b260 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go +++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go index cb8141f9c..490ce7cf1 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go +++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go index cb8141f9c..490ce7cf1 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go +++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_freebsd.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_386.go b/vendor/golang.org/x/net/ipv6/zsys_linux_386.go index 73aa8c6df..14155dec2 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_386.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_386.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go index b64f0157d..9566d7646 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go b/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go index 73aa8c6df..14155dec2 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go index b64f0157d..9566d7646 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go index 73aa8c6df..14155dec2 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go index b64f0157d..9566d7646 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go index b64f0157d..9566d7646 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go index 73aa8c6df..14155dec2 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go index c9bf6a87e..a51e142b4 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go index b64f0157d..9566d7646 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go index b64f0157d..9566d7646 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go new file mode 100644 index 000000000..1ee237b2b --- /dev/null +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go @@ -0,0 +1,173 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_linux.go + +// +build riscv64 + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSOL_SOCKET = 0x1 + sysSO_ATTACH_FILTER = 0x1a + + sizeofKernelSockaddrStorage = 0x80 + sizeofSockaddrInet6 = 0x1c + sizeofInet6Pktinfo = 0x14 + sizeofIPv6Mtuinfo = 0x20 + sizeofIPv6FlowlabelReq = 0x20 + + sizeofIPv6Mreq = 0x14 + sizeofGroupReq = 0x88 + sizeofGroupSourceReq = 0x108 + + sizeofICMPv6Filter = 0x20 + + sizeofSockFprog = 0x10 +) + +type kernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type ipv6Mtuinfo struct { + Addr sockaddrInet6 + Mtu uint32 +} + +type ipv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type ipv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type groupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group kernelSockaddrStorage +} + +type groupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group kernelSockaddrStorage + Source kernelSockaddrStorage +} + +type icmpv6Filter struct { + Data [8]uint32 +} + +type sockFProg struct { + Len uint16 + Filter *sockFilter +} + +type sockFilter struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go b/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go index b64f0157d..9566d7646 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go +++ b/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_linux.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_netbsd.go b/vendor/golang.org/x/net/ipv6/zsys_netbsd.go index bcada13b7..e39571e07 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_netbsd.go +++ b/vendor/golang.org/x/net/ipv6/zsys_netbsd.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_netbsd.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_openbsd.go b/vendor/golang.org/x/net/ipv6/zsys_openbsd.go index 86cf3c637..cc1899a63 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_openbsd.go +++ b/vendor/golang.org/x/net/ipv6/zsys_openbsd.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_openbsd.go package ipv6 diff --git a/vendor/golang.org/x/net/ipv6/zsys_solaris.go b/vendor/golang.org/x/net/ipv6/zsys_solaris.go index cf1837dd2..690eef934 100644 --- a/vendor/golang.org/x/net/ipv6/zsys_solaris.go +++ b/vendor/golang.org/x/net/ipv6/zsys_solaris.go @@ -1,4 +1,4 @@ -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs defs_solaris.go package ipv6 diff --git a/vendor/golang.org/x/net/proxy/dial.go b/vendor/golang.org/x/net/proxy/dial.go new file mode 100644 index 000000000..811c2e4e9 --- /dev/null +++ b/vendor/golang.org/x/net/proxy/dial.go @@ -0,0 +1,54 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proxy + +import ( + "context" + "net" +) + +// A ContextDialer dials using a context. +type ContextDialer interface { + DialContext(ctx context.Context, network, address string) (net.Conn, error) +} + +// Dial works like DialContext on net.Dialer but using a dialer returned by FromEnvironment. +// +// The passed ctx is only used for returning the Conn, not the lifetime of the Conn. +// +// Custom dialers (registered via RegisterDialerType) that do not implement ContextDialer +// can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout. +// +// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed. +func Dial(ctx context.Context, network, address string) (net.Conn, error) { + d := FromEnvironment() + if xd, ok := d.(ContextDialer); ok { + return xd.DialContext(ctx, network, address) + } + return dialContext(ctx, d, network, address) +} + +// WARNING: this can leak a goroutine for as long as the underlying Dialer implementation takes to timeout +// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed. +func dialContext(ctx context.Context, d Dialer, network, address string) (net.Conn, error) { + var ( + conn net.Conn + done = make(chan struct{}, 1) + err error + ) + go func() { + conn, err = d.Dial(network, address) + close(done) + if conn != nil && ctx.Err() != nil { + conn.Close() + } + }() + select { + case <-ctx.Done(): + err = ctx.Err() + case <-done: + } + return conn, err +} diff --git a/vendor/golang.org/x/net/proxy/direct.go b/vendor/golang.org/x/net/proxy/direct.go index 4c5ad88b1..3d66bdef9 100644 --- a/vendor/golang.org/x/net/proxy/direct.go +++ b/vendor/golang.org/x/net/proxy/direct.go @@ -5,14 +5,27 @@ package proxy import ( + "context" "net" ) type direct struct{} -// Direct is a direct proxy: one that makes network connections directly. +// Direct implements Dialer by making network connections directly using net.Dial or net.DialContext. var Direct = direct{} +var ( + _ Dialer = Direct + _ ContextDialer = Direct +) + +// Dial directly invokes net.Dial with the supplied parameters. func (direct) Dial(network, addr string) (net.Conn, error) { return net.Dial(network, addr) } + +// DialContext instantiates a net.Dialer and invokes its DialContext receiver with the supplied parameters. +func (direct) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { + var d net.Dialer + return d.DialContext(ctx, network, addr) +} diff --git a/vendor/golang.org/x/net/proxy/per_host.go b/vendor/golang.org/x/net/proxy/per_host.go index 0689bb6a7..573fe79e8 100644 --- a/vendor/golang.org/x/net/proxy/per_host.go +++ b/vendor/golang.org/x/net/proxy/per_host.go @@ -5,6 +5,7 @@ package proxy import ( + "context" "net" "strings" ) @@ -41,6 +42,20 @@ func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) { return p.dialerForRequest(host).Dial(network, addr) } +// DialContext connects to the address addr on the given network through either +// defaultDialer or bypass. +func (p *PerHost) DialContext(ctx context.Context, network, addr string) (c net.Conn, err error) { + host, _, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + d := p.dialerForRequest(host) + if x, ok := d.(ContextDialer); ok { + return x.DialContext(ctx, network, addr) + } + return dialContext(ctx, d, network, addr) +} + func (p *PerHost) dialerForRequest(host string) Dialer { if ip := net.ParseIP(host); ip != nil { for _, net := range p.bypassNetworks { diff --git a/vendor/golang.org/x/net/proxy/proxy.go b/vendor/golang.org/x/net/proxy/proxy.go index 553ead7cf..9ff4b9a77 100644 --- a/vendor/golang.org/x/net/proxy/proxy.go +++ b/vendor/golang.org/x/net/proxy/proxy.go @@ -15,6 +15,7 @@ import ( ) // A Dialer is a means to establish a connection. +// Custom dialers should also implement ContextDialer. type Dialer interface { // Dial connects to the given address via the proxy. Dial(network, addr string) (c net.Conn, err error) @@ -25,21 +26,30 @@ type Auth struct { User, Password string } -// FromEnvironment returns the dialer specified by the proxy related variables in -// the environment. +// FromEnvironment returns the dialer specified by the proxy-related +// variables in the environment and makes underlying connections +// directly. func FromEnvironment() Dialer { + return FromEnvironmentUsing(Direct) +} + +// FromEnvironmentUsing returns the dialer specify by the proxy-related +// variables in the environment and makes underlying connections +// using the provided forwarding Dialer (for instance, a *net.Dialer +// with desired configuration). +func FromEnvironmentUsing(forward Dialer) Dialer { allProxy := allProxyEnv.Get() if len(allProxy) == 0 { - return Direct + return forward } proxyURL, err := url.Parse(allProxy) if err != nil { - return Direct + return forward } - proxy, err := FromURL(proxyURL, Direct) + proxy, err := FromURL(proxyURL, forward) if err != nil { - return Direct + return forward } noProxy := noProxyEnv.Get() @@ -47,7 +57,7 @@ func FromEnvironment() Dialer { return proxy } - perHost := NewPerHost(proxy, Direct) + perHost := NewPerHost(proxy, forward) perHost.AddFromString(noProxy) return perHost } @@ -79,8 +89,13 @@ func FromURL(u *url.URL, forward Dialer) (Dialer, error) { } switch u.Scheme { - case "socks5": - return SOCKS5("tcp", u.Host, auth, forward) + case "socks5", "socks5h": + addr := u.Hostname() + port := u.Port() + if port == "" { + port = "1080" + } + return SOCKS5("tcp", net.JoinHostPort(addr, port), auth, forward) } // If the scheme doesn't match any of the built-in schemes, see if it diff --git a/vendor/golang.org/x/net/proxy/socks5.go b/vendor/golang.org/x/net/proxy/socks5.go index 56345ec8b..c91651f96 100644 --- a/vendor/golang.org/x/net/proxy/socks5.go +++ b/vendor/golang.org/x/net/proxy/socks5.go @@ -17,8 +17,14 @@ import ( func SOCKS5(network, address string, auth *Auth, forward Dialer) (Dialer, error) { d := socks.NewDialer(network, address) if forward != nil { - d.ProxyDial = func(_ context.Context, network string, address string) (net.Conn, error) { - return forward.Dial(network, address) + if f, ok := forward.(ContextDialer); ok { + d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) { + return f.DialContext(ctx, network, address) + } + } else { + d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) { + return dialContext(ctx, forward, network, address) + } } } if auth != nil { diff --git a/vendor/golang.org/x/net/publicsuffix/gen.go b/vendor/golang.org/x/net/publicsuffix/gen.go index f85a3c32b..372ffbb24 100644 --- a/vendor/golang.org/x/net/publicsuffix/gen.go +++ b/vendor/golang.org/x/net/publicsuffix/gen.go @@ -100,6 +100,7 @@ var ( labelsList = []string{} labelsMap = map[string]bool{} rules = []string{} + numICANNRules = 0 // validSuffixRE is used to check that the entries in the public suffix // list are in canonical form (after Punycode encoding). Specifically, @@ -167,11 +168,14 @@ func main1() error { } s = strings.TrimSpace(s) if strings.Contains(s, "BEGIN ICANN DOMAINS") { + if len(rules) != 0 { + return fmt.Errorf(`expected no rules before "BEGIN ICANN DOMAINS"`) + } icann = true continue } if strings.Contains(s, "END ICANN DOMAINS") { - icann = false + icann, numICANNRules = false, len(rules) continue } if s == "" || strings.HasPrefix(s, "//") { @@ -287,7 +291,7 @@ func gitCommit() (sha, date string, retErr error) { func printTest(w io.Writer, n *node) error { fmt.Fprintf(w, "// generated by go run gen.go; DO NOT EDIT\n\n") - fmt.Fprintf(w, "package publicsuffix\n\nvar rules = [...]string{\n") + fmt.Fprintf(w, "package publicsuffix\n\nconst numICANNRules = %d\n\nvar rules = [...]string{\n", numICANNRules) for _, rule := range rules { fmt.Fprintf(w, "%q,\n", rule) } diff --git a/vendor/golang.org/x/net/publicsuffix/list.go b/vendor/golang.org/x/net/publicsuffix/list.go index 8bbf3bcd7..200617ea8 100644 --- a/vendor/golang.org/x/net/publicsuffix/list.go +++ b/vendor/golang.org/x/net/publicsuffix/list.go @@ -5,8 +5,43 @@ //go:generate go run gen.go // Package publicsuffix provides a public suffix list based on data from -// http://publicsuffix.org/. A public suffix is one under which Internet users -// can directly register names. +// https://publicsuffix.org/ +// +// A public suffix is one under which Internet users can directly register +// names. It is related to, but different from, a TLD (top level domain). +// +// "com" is a TLD (top level domain). Top level means it has no dots. +// +// "com" is also a public suffix. Amazon and Google have registered different +// siblings under that domain: "amazon.com" and "google.com". +// +// "au" is another TLD, again because it has no dots. But it's not "amazon.au". +// Instead, it's "amazon.com.au". +// +// "com.au" isn't an actual TLD, because it's not at the top level (it has +// dots). But it is an eTLD (effective TLD), because that's the branching point +// for domain name registrars. +// +// Another name for "an eTLD" is "a public suffix". Often, what's more of +// interest is the eTLD+1, or one more label than the public suffix. For +// example, browsers partition read/write access to HTTP cookies according to +// the eTLD+1. Web pages served from "amazon.com.au" can't read cookies from +// "google.com.au", but web pages served from "maps.google.com" can share +// cookies from "www.google.com", so you don't have to sign into Google Maps +// separately from signing into Google Web Search. Note that all four of those +// domains have 3 labels and 2 dots. The first two domains are each an eTLD+1, +// the last two are not (but share the same eTLD+1: "google.com"). +// +// All of these domains have the same eTLD+1: +// - "www.books.amazon.co.uk" +// - "books.amazon.co.uk" +// - "amazon.co.uk" +// Specifically, the eTLD+1 is "amazon.co.uk", because the eTLD is "co.uk". +// +// There is no closed form algorithm to calculate the eTLD of a domain. +// Instead, the calculation is data driven. This package provides a +// pre-compiled snapshot of Mozilla's PSL (Public Suffix List) data at +// https://publicsuffix.org/ package publicsuffix // import "golang.org/x/net/publicsuffix" // TODO: specify case sensitivity and leading/trailing dot behavior for @@ -37,20 +72,24 @@ func (list) String() string { // publicsuffix.org database compiled into the library. // // icann is whether the public suffix is managed by the Internet Corporation -// for Assigned Names and Numbers. If not, the public suffix is privately -// managed. For example, foo.org and foo.co.uk are ICANN domains, -// foo.dyndns.org and foo.blogspot.co.uk are private domains. +// for Assigned Names and Numbers. If not, the public suffix is either a +// privately managed domain (and in practice, not a top level domain) or an +// unmanaged top level domain (and not explicitly mentioned in the +// publicsuffix.org list). For example, "foo.org" and "foo.co.uk" are ICANN +// domains, "foo.dyndns.org" and "foo.blogspot.co.uk" are private domains and +// "cromulent" is an unmanaged top level domain. // -// Use cases for distinguishing ICANN domains like foo.com from private -// domains like foo.appspot.com can be found at +// Use cases for distinguishing ICANN domains like "foo.com" from private +// domains like "foo.appspot.com" can be found at // https://wiki.mozilla.org/Public_Suffix_List/Use_Cases func PublicSuffix(domain string) (publicSuffix string, icann bool) { lo, hi := uint32(0), uint32(numTLD) - s, suffix, wildcard := domain, len(domain), false + s, suffix, icannNode, wildcard := domain, len(domain), false, false loop: for { dot := strings.LastIndex(s, ".") if wildcard { + icann = icannNode suffix = 1 + dot } if lo == hi { @@ -62,7 +101,7 @@ loop: } u := nodes[f] >> (nodesBitsTextOffset + nodesBitsTextLength) - icann = u&(1<>= nodesBitsICANN u = children[u&(1<>= childrenBitsNodeType wildcard = u&(1< Date: Mon, 1 Jul 2019 15:28:04 +0200 Subject: [PATCH 10/11] Add gRPC user guide --- .github/ISSUE_TEMPLATE.md | 1 - .github/ISSUE_TEMPLATE/Bug_report.md | 1 - .github/ISSUE_TEMPLATE/Feature_request.md | 1 - README.md | 1 - docs/.markdownlint.json | 1 + docs/content/assets/img/user-guides/grpc.svg | 4 + docs/content/assets/js/hljs/highlight.pack.js | 4 +- .../content/contributing/submitting-issues.md | 1 - docs/content/user-guides/grpc.md | 252 ++++++++++++++++++ docs/mkdocs.yml | 1 + 10 files changed, 260 insertions(+), 7 deletions(-) create mode 100644 docs/content/assets/img/user-guides/grpc.svg create mode 100644 docs/content/user-guides/grpc.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 0ac139f29..a5331e0c3 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -4,7 +4,6 @@ DO NOT FILE ISSUES FOR GENERAL SUPPORT QUESTIONS. The issue tracker is for reporting bugs and feature requests only. For end-user related support questions, please refer to one of the following: -- Stack Overflow (using the "traefik" tag): https://stackoverflow.com/questions/tagged/traefik - the Traefik community forum: https://community.containo.us/ --> diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index a8b0d8dc9..b782a8a35 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -10,7 +10,6 @@ DO NOT FILE ISSUES FOR GENERAL SUPPORT QUESTIONS. The issue tracker is for reporting bugs and feature requests only. For end-user related support questions, please refer to one of the following: -- Stack Overflow (using the "traefik" tag): https://stackoverflow.com/questions/tagged/traefik - the Traefik community forum: https://community.containo.us/ --> diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md index c855b1dbc..f071f0931 100644 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -10,7 +10,6 @@ DO NOT FILE ISSUES FOR GENERAL SUPPORT QUESTIONS. The issue tracker is for reporting bugs and feature requests only. For end-user related support questions, please refer to one of the following: -- Stack Overflow (using the "traefik" tag): https://stackoverflow.com/questions/tagged/traefik - the Traefik community forum: https://community.containo.us/ --> diff --git a/README.md b/README.md index 9e92a1f28..e55fa5880 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,6 @@ A collection of contributions around Traefik can be found at [https://awesome.tr To get community support, you can: - join the Traefik community forum: [![Join the chat at https://community.containo.us/](https://img.shields.io/badge/style-register-green.svg?style=social&label=Discourse)](https://community.containo.us/) -- use [Stack Overflow](https://stackoverflow.com/questions/tagged/traefik) (using the `traefik` tag) If you need commercial support, please contact [Containo.us](https://containo.us) by mail: . diff --git a/docs/.markdownlint.json b/docs/.markdownlint.json index 0f5b86211..c10d547d3 100644 --- a/docs/.markdownlint.json +++ b/docs/.markdownlint.json @@ -3,6 +3,7 @@ "MD007": { "indent": 4 }, "MD009": false, "MD013": false, + "MD024": false, "MD026": false, "MD033": false, "MD034": false, diff --git a/docs/content/assets/img/user-guides/grpc.svg b/docs/content/assets/img/user-guides/grpc.svg new file mode 100644 index 000000000..3f1d53c76 --- /dev/null +++ b/docs/content/assets/img/user-guides/grpc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/content/assets/js/hljs/highlight.pack.js b/docs/content/assets/js/hljs/highlight.pack.js index d939b924d..ae87f0202 100644 --- a/docs/content/assets/js/hljs/highlight.pack.js +++ b/docs/content/assets/js/hljs/highlight.pack.js @@ -1,2 +1,2 @@ -/*! highlight.js v9.14.2 | BSD3 License | git.io/hljslicense */ -!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=M.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function c(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function u(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"===e.event?o:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function l(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):B(a.k).forEach(function(e){c(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.endSameAsBegin&&(a.e=a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return s("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var u=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=u.length?t(u.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e){return new RegExp(e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")}function c(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t].endSameAsBegin&&(n.c[t].eR=o(n.c[t].bR.exec(e)[0])),n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function s(e,n){return!a&&r(n.iR,e)}function p(e,n){var t=R.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function d(e,n,t,r){var a=r?"":j.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=p(E,r),e?(M+=e[1],a+=d(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function b(){var e="string"==typeof E.sL;if(e&&!L[E.sL])return n(k);var t=e?f(E.sL,k,!0,B[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(B[E.sL]=t.top),d(t.language,t.value,!1,!0)}function v(){y+=null!=E.sL?b():h(),k=""}function m(e){y+=e.cN?d(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function N(e,n){if(k+=e,null==n)return v(),0;var t=c(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),v(),t.rB||t.eB||(k=n)),m(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),v(),a.eE&&(k=n));do E.cN&&(y+=I),E.skip||E.sL||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),m(r.starts,"")),a.rE?0:n.length}if(s(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var R=w(e);if(!R)throw new Error('Unknown language: "'+e+'"');l(R);var x,E=i||R,B={},y="";for(x=E;x!==R;x=x.parent)x.cN&&(y=d(x.cN,"",!0)+y);var k="",M=0;try{for(var C,A,S=0;;){if(E.t.lastIndex=S,C=E.t.exec(t),!C)break;A=N(t.substring(S,C.index),C[0]),S=C.index+A}for(N(t.substr(S)),x=E;x.parent;x=x.parent)x.cN&&(y+=I);return{r:M,value:y,language:e,top:E}}catch(O){if(O.message&&-1!==O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function g(e,t){t=t||j.languages||B(L);var r={r:0,value:n(e)},a=r;return t.filter(w).filter(x).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return j.tabReplace||j.useBR?e.replace(C,function(e,n){return j.useBR&&"\n"===e?"
":j.tabReplace?n.replace(/\t/g,j.tabReplace):""}):e}function d(e,n,t){var r=n?y[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function h(e){var n,t,r,o,s,l=i(e);a(l)||(j.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=l?f(l,s,!0):g(s),t=c(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=u(t,c(o),s)),r.value=p(r.value),e.innerHTML=r.value,e.className=d(e.className,l,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){j=o(j,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,h)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=L[n]=t(e);r.aliases&&r.aliases.forEach(function(e){y[e]=n})}function R(){return B(L)}function w(e){return e=(e||"").toLowerCase(),L[e]||L[y[e]]}function x(e){var n=w(e);return n&&!n.disableAutodetect}var E=[],B=Object.keys,L={},y={},k=/^(no-?highlight|plain|text)$/i,M=/\blang(?:uage)?-([\w-]+)\b/i,C=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,I="
",j={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=h,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.autoDetection=x,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},i=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{sL:"javascript",eB:!0,eE:!0,v:[{b:"```",e:"```"},{b:"`",e:"`"}]}];r.c=i;var s=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(i)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:i.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[s,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[s]},s]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("properties",function(r){var t="[ \\t\\f]*",e="[ \\t\\f]+",s="("+t+"[:=]"+t+"|"+e+")",n="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",c={e:s,r:0,starts:{cN:"string",e:/$/,r:0,c:[{b:"\\\\\\n"}]}};return{cI:!0,i:/\S/,c:[r.C("^\\s*[!#]","$"),{b:n+s,rB:!0,c:[{cN:"attr",b:n,endsParent:!0,r:0}],starts:c},{b:a+s,rB:!0,r:0,c:[{cN:"meta",b:a,endsParent:!0,r:0}],starts:c},{cN:"attr",r:0,b:a+t+"$"}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},s.inherit(s.ASM,{i:null,cN:null,c:null,skip:!0}),s.inherit(s.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],o=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=o,s.c=o,{aliases:["pl","pm"],l:/[\w\.]+/,k:t,c:o}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t,e.HCM]},e.CBCM,t,e.HCM]}});hljs.registerLanguage("php",function(e){var c={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},i={cN:"meta",b:/<\?(php)?|\?>/},t={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a={v:[e.BNM,e.CNM]};return{aliases:["php","php3","php4","php5","php6","php7"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[i]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},i,{cN:"keyword",b:/\$this\b/},c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,t,a]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},t,a]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(w).concat(d)}});hljs.registerLanguage("yaml",function(e){var b="true false yes no null",a="^[ \\-]*",r="[a-zA-Z_][\\w\\-]*",t={cN:"attr",v:[{b:a+r+":"},{b:a+'"'+r+'":'},{b:a+"'"+r+"':"}]},c={cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]},l={cN:"string",r:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/\S+/}],c:[e.BE,c]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[t,{cN:"meta",b:"^---s*$",r:10},{cN:"string",b:"[\\|>] *$",rE:!0,c:l.c,e:t.v[0].b},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,r:0},{cN:"type",b:"!"+e.UIR},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"^ *-",r:0},e.HCM,{bK:b,k:{literal:b}},e.CNM,l]}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("makefile",function(e){var i={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@%]*>/,e:/$/,i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e,{b:/\(/,e:/\)/,k:c,r:0,c:["self",t.CLCM,t.CBCM,r,s,e]}]},t.CLCM,t.CBCM,i]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b://,c:["self"]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},i=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:_,l:i,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:i,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},r={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},t={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},a=e.inherit(t,{i:/\n/}),c={cN:"subst",b:"{",e:"}",k:i},n=e.inherit(c,{i:/\n/}),s={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,n]},b={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},c]},l=e.inherit(b,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},n]});c.c=[b,s,t,e.ASM,e.QSM,r,e.CBCM],n.c=[l,s,a,e.ASM,e.QSM,r,e.inherit(e.CBCM,{i:/\n/})];var o={v:[b,s,t,e.ASM,e.QSM]},d=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp","c#"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},o,r,{bK:"class interface",e:/[{;=]/,i:/[^\s:,]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+d+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/\s*[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[o,r,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("python",function(e){var r={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},b={cN:"meta",b:/^(>>>|\.\.\.) /},c={cN:"subst",b:/\{/,e:/\}/,k:r,i:/#/},a={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[e.BE,b],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[e.BE,b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[e.BE,b,c]},{b:/(fr|rf|f)"""/,e:/"""/,c:[e.BE,b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[e.BE,c]},{b:/(fr|rf|f)"/,e:/"/,c:[e.BE,c]},e.ASM,e.QSM]},i={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},n={cN:"params",b:/\(/,e:/\)/,c:["self",b,i,a]};return c.c=[a,i,b],{aliases:["py","gyp","ipython"],k:r,i:/(<\/|->|\?)|=>/,c:[b,i,a,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,n,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor get set",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("dockerfile",function(e){return{aliases:["docker"],cI:!0,k:"from maintainer expose env arg user onbuild stopsignal",c:[e.HCM,e.ASM,e.QSM,e.NM,{bK:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{e:/[^\\]$/,sL:"bash"}}],i:"]+>|\t|)+|(?:\n)))/gm,r={case_insensitive:"cI",lexemes:"l",contains:"c",keywords:"k",subLanguage:"sL",className:"cN",begin:"b",beginKeywords:"bK",end:"e",endsWithParent:"eW",illegal:"i",excludeBegin:"eB",excludeEnd:"eE",returnBegin:"rB",returnEnd:"rE",relevance:"r",variants:"v",IDENT_RE:"IR",UNDERSCORE_IDENT_RE:"UIR",NUMBER_RE:"NR",C_NUMBER_RE:"CNR",BINARY_NUMBER_RE:"BNR",RE_STARTERS_RE:"RSR",BACKSLASH_ESCAPE:"BE",APOS_STRING_MODE:"ASM",QUOTE_STRING_MODE:"QSM",PHRASAL_WORDS_MODE:"PWM",C_LINE_COMMENT_MODE:"CLCM",C_BLOCK_COMMENT_MODE:"CBCM",HASH_COMMENT_MODE:"HCM",NUMBER_MODE:"NM",C_NUMBER_MODE:"CNM",BINARY_NUMBER_MODE:"BNM",CSS_NUMBER_MODE:"CSSNM",REGEXP_MODE:"RM",TITLE_MODE:"TM",UNDERSCORE_TITLE_MODE:"UTM",COMMENT:"C",beginRe:"bR",endRe:"eR",illegalRe:"iR",lexemesRe:"lR",terminators:"t",terminator_end:"tE"},b="",h={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function _(e){return e.replace(/&/g,"&").replace(//g,">")}function E(e){return e.nodeName.toLowerCase()}function v(e,n){var t=e&&e.exec(n);return t&&0===t.index}function l(e){return n.test(e)}function g(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function R(e){var a=[];return function e(n,t){for(var r=n.firstChild;r;r=r.nextSibling)3===r.nodeType?t+=r.nodeValue.length:1===r.nodeType&&(a.push({event:"start",offset:t,node:r}),t=e(r,t),E(r).match(/br|hr|img|input/)||a.push({event:"stop",offset:t,node:r}));return t}(e,0),a}function i(e){if(r&&!e.langApiRestored){for(var n in e.langApiRestored=!0,r)e[n]&&(e[r[n]]=e[n]);(e.c||[]).concat(e.v||[]).forEach(i)}}function m(o){function s(e){return e&&e.source||e}function c(e,n){return new RegExp(s(e),"m"+(o.cI?"i":"")+(n?"g":""))}!function n(t,e){if(!t.compiled){if(t.compiled=!0,t.k=t.k||t.bK,t.k){function r(t,e){o.cI&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var n=e.split("|");a[n[0]]=[t,n[1]?Number(n[1]):1]})}var a={};"string"==typeof t.k?r("keyword",t.k):u(t.k).forEach(function(e){r(e,t.k[e])}),t.k=a}t.lR=c(t.l||/\w+/,!0),e&&(t.bK&&(t.b="\\b("+t.bK.split(" ").join("|")+")\\b"),t.b||(t.b=/\B|\b/),t.bR=c(t.b),t.endSameAsBegin&&(t.e=t.b),t.e||t.eW||(t.e=/\B|\b/),t.e&&(t.eR=c(t.e)),t.tE=s(t.e)||"",t.eW&&e.tE&&(t.tE+=(t.e?"|":"")+e.tE)),t.i&&(t.iR=c(t.i)),null==t.r&&(t.r=1),t.c||(t.c=[]),t.c=Array.prototype.concat.apply([],t.c.map(function(e){return function(n){return n.v&&!n.cached_variants&&(n.cached_variants=n.v.map(function(e){return g(n,{v:null},e)})),n.cached_variants||n.eW&&[g(n)]||[n]}("self"===e?t:e)})),t.c.forEach(function(e){n(e,t)}),t.starts&&n(t.starts,e);var i=t.c.map(function(e){return e.bK?"\\.?(?:"+e.b+")\\.?":e.b}).concat([t.tE,t.i]).map(s).filter(Boolean);t.t=i.length?c(function(e,n){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i')+n+(t?"":b):n}function o(){E+=null!=l.sL?function(){var e="string"==typeof l.sL;if(e&&!N[l.sL])return _(g);var n=e?C(l.sL,g,!0,f[l.sL]):O(g,l.sL.length?l.sL:void 0);return 0")+'"');return g+=n,n.length||1}var s=B(e);if(!s)throw new Error('Unknown language: "'+e+'"');m(s);var a,l=t||s,f={},E="";for(a=l;a!==s;a=a.parent)a.cN&&(E=c(a.cN,"",!0)+E);var g="",R=0;try{for(var d,p,M=0;l.t.lastIndex=M,d=l.t.exec(n);)p=r(n.substring(M,d.index),d[0]),M=d.index+p;for(r(n.substr(M)),a=l;a.parent;a=a.parent)a.cN&&(E+=b);return{r:R,value:E,language:e,top:l}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{r:0,value:_(n)};throw e}}function O(t,e){e=e||h.languages||u(N);var r={r:0,value:_(t)},a=r;return e.filter(B).filter(M).forEach(function(e){var n=C(e,t,!1);n.language=e,n.r>a.r&&(a=n),n.r>r.r&&(a=r,r=n)}),a.language&&(r.second_best=a),r}function d(e){return h.tabReplace||h.useBR?e.replace(t,function(e,n){return h.useBR&&"\n"===e?"
":h.tabReplace?n.replace(/\t/g,h.tabReplace):""}):e}function o(e){var n,t,r,a,i,o=function(e){var n,t,r,a,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=s.exec(i))return B(t[1])?t[1]:"no-highlight";for(n=0,r=(i=i.split(/\s+/)).length;n/g,"\n"):n=e,i=n.textContent,r=o?C(o,i,!0):O(i),(t=R(n)).length&&((a=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=r.value,r.value=function(e,n,t){var r=0,a="",i=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function u(e){a+=""}function s(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var l=o();if(a+=_(t.substring(r,l[0].offset)),r=l[0].offset,l===e){for(i.reverse().forEach(u);s(l.splice(0,1)[0]),(l=o())===e&&l.length&&l[0].offset===r;);i.reverse().forEach(c)}else"start"===l[0].event?i.push(l[0].node):i.pop(),s(l.splice(0,1)[0])}return a+_(t.substr(r))}(t,R(a),i)),r.value=d(r.value),e.innerHTML=r.value,e.className=function(e,n,t){var r=n?c[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}(e.className,o,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function p(){if(!p.called){p.called=!0;var e=document.querySelectorAll("pre code");f.forEach.call(e,o)}}function B(e){return e=(e||"").toLowerCase(),N[e]||N[c[e]]}function M(e){var n=B(e);return n&&!n.disableAutodetect}return a.highlight=C,a.highlightAuto=O,a.fixMarkup=d,a.highlightBlock=o,a.configure=function(e){h=g(h,e)},a.initHighlighting=p,a.initHighlightingOnLoad=function(){addEventListener("DOMContentLoaded",p,!1),addEventListener("load",p,!1)},a.registerLanguage=function(n,e){var t=N[n]=e(a);i(t),t.aliases&&t.aliases.forEach(function(e){c[e]=n})},a.listLanguages=function(){return u(N)},a.getLanguage=B,a.autoDetection=M,a.inherit=g,a.IR=a.IDENT_RE="[a-zA-Z]\\w*",a.UIR=a.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",a.NR=a.NUMBER_RE="\\b\\d+(\\.\\d+)?",a.CNR=a.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",a.BNR=a.BINARY_NUMBER_RE="\\b(0b[01]+)",a.RSR=a.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",a.BE=a.BACKSLASH_ESCAPE={b:"\\\\[\\s\\S]",r:0},a.ASM=a.APOS_STRING_MODE={cN:"string",b:"'",e:"'",i:"\\n",c:[a.BE]},a.QSM=a.QUOTE_STRING_MODE={cN:"string",b:'"',e:'"',i:"\\n",c:[a.BE]},a.PWM=a.PHRASAL_WORDS_MODE={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},a.C=a.COMMENT=function(e,n,t){var r=a.inherit({cN:"comment",b:e,e:n,c:[]},t||{});return r.c.push(a.PWM),r.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),r},a.CLCM=a.C_LINE_COMMENT_MODE=a.C("//","$"),a.CBCM=a.C_BLOCK_COMMENT_MODE=a.C("/\\*","\\*/"),a.HCM=a.HASH_COMMENT_MODE=a.C("#","$"),a.NM=a.NUMBER_MODE={cN:"number",b:a.NR,r:0},a.CNM=a.C_NUMBER_MODE={cN:"number",b:a.CNR,r:0},a.BNM=a.BINARY_NUMBER_MODE={cN:"number",b:a.BNR,r:0},a.CSSNM=a.CSS_NUMBER_MODE={cN:"number",b:a.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},a.RM=a.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[a.BE,{b:/\[/,e:/\]/,r:0,c:[a.BE]}]},a.TM=a.TITLE_MODE={cN:"title",b:a.IR,r:0},a.UTM=a.UNDERSCORE_TITLE_MODE={cN:"title",b:a.UIR,r:0},a.METHOD_GUARD={b:"\\.\\s*"+a.UIR,r:0},a});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",a={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},t={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:a,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,t,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:a,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,t,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:a,c:s}]}]},{cN:"",b:/\s/,e:/\s*/,skip:!0},{b://,sL:"xml",c:[{b:/<[A-Za-z0-9\\._:-]+\s*\/>/,skip:!0},{b:/<[A-Za-z0-9\\._:-]+/,e:/(\/[A-Za-z0-9\\._:-]+|[A-Za-z0-9\\._:-]+\/)>/,skip:!0,c:[{b:/<[A-Za-z0-9\\._:-]+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor get set",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,{cN:"string",b:/'/,e:/'/},t]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("\x3c!--","--\x3e",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},s.inherit(s.ASM,{i:null,cN:null,c:null,skip:!0}),s.inherit(s.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[e],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[e],starts:{e:"<\/script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},e]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^\\s*([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}|\t)",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("makefile",function(e){var i={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@%>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d;var l=[{b:/^\s*=>/,starts:{e:"$",c:i.c=d}},{cN:"meta",b:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(l).concat(d)}});hljs.registerLanguage("yaml",function(e){var b="true false yes no null",a="^[ \\-]*",r="[a-zA-Z_][\\w\\-]*",t={cN:"attr",v:[{b:a+r+":"},{b:a+'"'+r+'":'},{b:a+"'"+r+"':"}]},c={cN:"string",r:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/\S+/}],c:[e.BE,{cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]}]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[t,{cN:"meta",b:"^---s*$",r:10},{cN:"string",b:"[\\|>] *$",rE:!0,c:c.c,e:t.v[0].b},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,r:0},{cN:"type",b:"!"+e.UIR},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"^ *-",r:0},e.HCM,{bK:b,k:{literal:b}},e.CNM,c]}});hljs.registerLanguage("dockerfile",function(e){return{aliases:["docker"],cI:!0,k:"from maintainer expose env arg user onbuild stopsignal",c:[e.HCM,e.ASM,e.QSM,e.NM,{bK:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{e:/[^\\]$/,sL:"bash"}}],i:"",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("css",function(e){var c={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:"[a-zA-Z-][a-zA-Z0-9_-]*",r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,c]}]}}); \ No newline at end of file diff --git a/docs/content/contributing/submitting-issues.md b/docs/content/contributing/submitting-issues.md index 1f4285b3f..4370eda67 100644 --- a/docs/content/contributing/submitting-issues.md +++ b/docs/content/contributing/submitting-issues.md @@ -15,7 +15,6 @@ To save us some time and get quicker feedback, be sure to follow the guide lines For end-user related support questions, try using first: - the Traefik community forum: [![Join the chat at https://community.containo.us/](https://img.shields.io/badge/style-register-green.svg?style=social&label=Discourse)](https://community.containo.us/) - - [Stack Overflow](https://stackoverflow.com/questions/tagged/traefik) (using the `traefik` tag) ## Issue Title diff --git a/docs/content/user-guides/grpc.md b/docs/content/user-guides/grpc.md new file mode 100644 index 000000000..9f8d586f6 --- /dev/null +++ b/docs/content/user-guides/grpc.md @@ -0,0 +1,252 @@ +# gRPC Examples + +## With HTTP (h2c) + +This section explains how to use Traefik as reverse proxy for gRPC application. + +### Traefik Configuration + +```toml tab="TOML" +## static configuration ## + +[entryPoints] + [entryPoints.http] + address = ":80" + +[api] + +[providers.file] + +## dynamic configuration ## + +[http] + + [http.routers] + [http.routers.routerTest] + service = "srv-grpc" + rule = "Host(`frontend.local`)" + + [http.services] + [http.services.srv-grpc] + [http.services.srv-grpc.loadBalancer] + [[http.services.srv-grpc.loadBalancer.servers]] + url = "h2c://backend.local:8080" +``` + +```yaml tab="YAML" +## static configuration ## + +entryPoints: + http: + address: :80 + +providers: + file: {} + +api: {} + +## dynamic configuration ## + +http: + routers: + routerTest: + service: srv-grpc + rule: Host(`frontend.local`) + + services: + srv-grpc: + loadBalancer: + servers: + - url: h2c://backend.local:8080 +``` + +!!! warning + For providers with labels, you will have to specify the `traefik.http.services..loadbalancer.server.scheme=h2c` + +### Conclusion + +We don't need specific configuration to use gRPC in Traefik, we just need to use `h2c` protocol, or use HTTPS communications to have HTTP2 with the backend. + +## With HTTPS + +This section explains how to use Traefik as reverse proxy for gRPC application with self-signed certificates. + +![gRPC architecture](../assets/img/user-guides/grpc.svg) + +### gRPC Server Certificate + +In order to secure the gRPC server, we generate a self-signed certificate for service url: + +```bash +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./backend.key -out ./backend.cert +``` + +That will prompt for information, the important answer is: + +```txt +Common Name (e.g. server FQDN or YOUR name) []: backend.local +``` + +### gRPC Client Certificate + +Generate your self-signed certificate for router url: + +```bash +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./frontend.key -out ./frontend.cert +``` + +with + +```txt +Common Name (e.g. server FQDN or YOUR name) []: frontend.local +``` + +### Traefik Configuration + +At last, we configure our Traefik instance to use both self-signed certificates. + +```toml tab="TOML" +## static configuration ## + +[entryPoints] + [entryPoints.https] + address = ":4443" + + +[serversTransport] + # For secure connection on backend.local + rootCAs = [ "./backend.cert" ] + +[api] + +[provider.file] + +## dynamic configuration ## + +[http] + + [http.routers] + [http.routers.routerTest] + service = "srv-grpc" + rule = "Host(`frontend.local`)" + + [http.services] + [http.services.srv-grpc] + [http.services.srv-grpc.loadBalancer] + [[http.services.srv-grpc.loadBalancer.servers]] + # Access on backend with HTTPS + url = "https://backend.local:8080" + +[tls] + + # For secure connection on frontend.local + [[tls.certificates]] + certFile = "./frontend.cert" + keyFile = "./frontend.key" +``` + +```yaml tab="YAML" +## static configuration ## + +entryPoints: + https: + address: :4443 + +serversTransport: + # For secure connection on backend.local + rootCAs: + - ./backend.cert + +providers: + file: {} + +api: {} + +## dynamic configuration ## + +http: + routers: + routerTest: + service: srv-grpc + rule: Host(`frontend.local`) + services: + srv-grpc: + loadBalancer: + servers: + # Access on backend with HTTPS + - url: https://backend.local:8080 +tls: + # For secure connection on frontend.local + certificates: + - certfile: ./frontend.cert + keyfile: ./frontend.key +``` + +!!! warning + With some services, the server URLs use the IP, so you may need to configure `insecureSkipVerify` instead of the `rootCAs` to activate HTTPS without hostname verification. + +### A gRPC example in go (modify for https) + +We use the gRPC greeter example in [grpc-go](https://github.com/grpc/grpc-go/tree/master/examples/helloworld) + +!!! warning + In order to use this gRPC example, we need to modify it to use HTTPS + +So we modify the "gRPC server example" to use our own self-signed certificate: + +```go +// ... + +// Read cert and key file +backendCert, _ := ioutil.ReadFile("./backend.cert") +backendKey, _ := ioutil.ReadFile("./backend.key") + +// Generate Certificate struct +cert, err := tls.X509KeyPair(backendCert, backendKey) +if err != nil { + log.Fatalf("failed to parse certificate: %v", err) +} + +// Create credentials +creds := credentials.NewServerTLSFromCert(&cert) + +// Use Credentials in gRPC server options +serverOption := grpc.Creds(creds) +var s *grpc.Server = grpc.NewServer(serverOption) +defer s.Stop() + +pb.RegisterGreeterServer(s, &server{}) +err := s.Serve(lis) + +// ... +``` + +Next we will modify gRPC Client to use our Traefik self-signed certificate: + +```go +// ... + +// Read cert file +frontendCert, _ := ioutil.ReadFile("./frontend.cert") + +// Create CertPool +roots := x509.NewCertPool() +roots.AppendCertsFromPEM(frontendCert) + +// Create credentials +credsClient := credentials.NewClientTLSFromCert(roots, "") + +// Dial with specific Transport (with credentials) +conn, err := grpc.Dial("frontend.local:4443", grpc.WithTransportCredentials(credsClient)) +if err != nil { + log.Fatalf("did not connect: %v", err) +} + +defer conn.Close() +client := pb.NewGreeterClient(conn) + +name := "World" +r, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: name}) + +// ... +``` diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 7234bfa92..fe9216ff4 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -128,6 +128,7 @@ nav: - 'Haystack': 'observability/tracing/haystack.md' - 'User Guides': - 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md' + - 'gRPC Examples': 'user-guides/grpc.md' - 'Marathon': 'user-guides/marathon.md' - 'Contributing': - 'Thank You!': 'contributing/thank-you.md' From 49814b92feb30dc55586b3874f6b54754bf0ebb8 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 1 Jul 2019 19:36:04 +0200 Subject: [PATCH 11/11] Prepare release v2.0.0-alpha8 --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4c855118..9d38e0d33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Change Log +## [v2.0.0-alpha8](https://github.com/containous/traefik/tree/v2.0.0-alpha8) (2019-07-01) +[All Commits](https://github.com/containous/traefik/compare/v2.0.0-alpha7...v2.0.0-alpha8) + +**Enhancements:** +- **[api]** Adding content-header to api endpoints ([#5019](https://github.com/containous/traefik/pull/5019) by [dalanmiller](https://github.com/dalanmiller)) +- **[file]** Support YAML for the dynamic configuration. ([#5024](https://github.com/containous/traefik/pull/5024) by [ldez](https://github.com/ldez)) +- **[logs]** Drop headers by default in access logs. ([#5034](https://github.com/containous/traefik/pull/5034) by [ldez](https://github.com/ldez)) +- **[middleware,k8s/crd]** Handle cross-provider middleware in kubernetes CRD ([#5009](https://github.com/containous/traefik/pull/5009) by [mpl](https://github.com/mpl)) +- **[server]** Use h2c from x/net to handle h2c requests ([#5045](https://github.com/containous/traefik/pull/5045) by [juliens](https://github.com/juliens)) +- **[server]** Make HTTP Keep-Alive timeout configurable for backend connections ([#4983](https://github.com/containous/traefik/pull/4983) by [mszabo-wikia](https://github.com/mszabo-wikia)) +- **[tls]** Define a TLS section to group TLS, TLSOptions, and TLSStores. ([#5031](https://github.com/containous/traefik/pull/5031) by [ldez](https://github.com/ldez)) +- **[tracing]** Improve tracing ([#5010](https://github.com/containous/traefik/pull/5010) by [mmatur](https://github.com/mmatur)) + +**Bug fixes:** +- **[cli]** Change the loading resource order ([#5007](https://github.com/containous/traefik/pull/5007) by [ldez](https://github.com/ldez)) +- **[logs]** fix: error log message. ([#5020](https://github.com/containous/traefik/pull/5020) by [ldez](https://github.com/ldez)) + +**Documentation:** +- **[acme]** doc/crd-acme: specify required kubectl version ([#5015](https://github.com/containous/traefik/pull/5015) by [mpl](https://github.com/mpl)) +- **[middleware]** Improve middleware documentation. ([#5003](https://github.com/containous/traefik/pull/5003) by [ldez](https://github.com/ldez)) +- **[server]** Add gRPC user guide ([#5042](https://github.com/containous/traefik/pull/5042) by [ldez](https://github.com/ldez)) +- Use the same case everywhere ([#5043](https://github.com/containous/traefik/pull/5043) by [ldez](https://github.com/ldez)) + ## [v2.0.0-alpha7](https://github.com/containous/traefik/tree/v2.0.0-alpha7) (2019-06-21) [All Commits](https://github.com/containous/traefik/compare/v2.0.0-alpha6...v2.0.0-alpha7)