aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/net
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net')
-rw-r--r--vendor/golang.org/x/net/AUTHORS3
-rw-r--r--vendor/golang.org/x/net/CONTRIBUTORS3
-rw-r--r--vendor/golang.org/x/net/context/context.go54
-rw-r--r--vendor/golang.org/x/net/context/go17.go72
-rw-r--r--vendor/golang.org/x/net/context/go19.go20
-rw-r--r--vendor/golang.org/x/net/context/pre_go17.go300
-rw-r--r--vendor/golang.org/x/net/context/pre_go19.go109
-rw-r--r--vendor/golang.org/x/net/html/atom/gen.go709
-rw-r--r--vendor/golang.org/x/net/html/atom/table.go1468
-rw-r--r--vendor/golang.org/x/net/html/const.go4
-rw-r--r--vendor/golang.org/x/net/http2/.gitignore2
-rw-r--r--vendor/golang.org/x/net/http2/Dockerfile51
-rw-r--r--vendor/golang.org/x/net/http2/Makefile3
-rw-r--r--vendor/golang.org/x/net/http2/README20
-rw-r--r--vendor/golang.org/x/net/http2/ciphers.go641
-rw-r--r--vendor/golang.org/x/net/http2/client_conn_pool.go256
-rw-r--r--vendor/golang.org/x/net/http2/configure_transport.go80
-rw-r--r--vendor/golang.org/x/net/http2/databuffer.go146
-rw-r--r--vendor/golang.org/x/net/http2/errors.go133
-rw-r--r--vendor/golang.org/x/net/http2/flow.go50
-rw-r--r--vendor/golang.org/x/net/http2/frame.go1579
-rw-r--r--vendor/golang.org/x/net/http2/go16.go16
-rw-r--r--vendor/golang.org/x/net/http2/go17.go106
-rw-r--r--vendor/golang.org/x/net/http2/go17_not18.go36
-rw-r--r--vendor/golang.org/x/net/http2/go18.go56
-rw-r--r--vendor/golang.org/x/net/http2/go19.go16
-rw-r--r--vendor/golang.org/x/net/http2/gotrack.go170
-rw-r--r--vendor/golang.org/x/net/http2/headermap.go78
-rw-r--r--vendor/golang.org/x/net/http2/hpack/encode.go240
-rw-r--r--vendor/golang.org/x/net/http2/hpack/hpack.go490
-rw-r--r--vendor/golang.org/x/net/http2/hpack/huffman.go212
-rw-r--r--vendor/golang.org/x/net/http2/hpack/tables.go479
-rw-r--r--vendor/golang.org/x/net/http2/http2.go391
-rw-r--r--vendor/golang.org/x/net/http2/not_go16.go21
-rw-r--r--vendor/golang.org/x/net/http2/not_go17.go87
-rw-r--r--vendor/golang.org/x/net/http2/not_go18.go29
-rw-r--r--vendor/golang.org/x/net/http2/not_go19.go16
-rw-r--r--vendor/golang.org/x/net/http2/pipe.go163
-rw-r--r--vendor/golang.org/x/net/http2/server.go2857
-rw-r--r--vendor/golang.org/x/net/http2/transport.go2275
-rw-r--r--vendor/golang.org/x/net/http2/write.go370
-rw-r--r--vendor/golang.org/x/net/http2/writesched.go242
-rw-r--r--vendor/golang.org/x/net/http2/writesched_priority.go452
-rw-r--r--vendor/golang.org/x/net/http2/writesched_random.go72
-rw-r--r--vendor/golang.org/x/net/idna/idna.go680
-rw-r--r--vendor/golang.org/x/net/idna/punycode.go203
-rw-r--r--vendor/golang.org/x/net/idna/tables.go4477
-rw-r--r--vendor/golang.org/x/net/idna/trie.go72
-rw-r--r--vendor/golang.org/x/net/idna/trieval.go114
-rw-r--r--vendor/golang.org/x/net/internal/timeseries/timeseries.go525
-rw-r--r--vendor/golang.org/x/net/lex/httplex/httplex.go351
-rw-r--r--vendor/golang.org/x/net/trace/events.go532
-rw-r--r--vendor/golang.org/x/net/trace/histogram.go365
-rw-r--r--vendor/golang.org/x/net/trace/trace.go1082
-rw-r--r--vendor/golang.org/x/net/trace/trace_go16.go21
-rw-r--r--vendor/golang.org/x/net/trace/trace_go17.go21
56 files changed, 22317 insertions, 703 deletions
diff --git a/vendor/golang.org/x/net/AUTHORS b/vendor/golang.org/x/net/AUTHORS
new file mode 100644
index 0000000..15167cd
--- /dev/null
+++ b/vendor/golang.org/x/net/AUTHORS
@@ -0,0 +1,3 @@
1# This source code refers to The Go Authors for copyright purposes.
2# The master list of authors is in the main Go distribution,
3# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/net/CONTRIBUTORS b/vendor/golang.org/x/net/CONTRIBUTORS
new file mode 100644
index 0000000..1c4577e
--- /dev/null
+++ b/vendor/golang.org/x/net/CONTRIBUTORS
@@ -0,0 +1,3 @@
1# This source code was written by the Go contributors.
2# The master list of contributors is in the main Go distribution,
3# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go
new file mode 100644
index 0000000..d3681ab
--- /dev/null
+++ b/vendor/golang.org/x/net/context/context.go
@@ -0,0 +1,54 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package context defines the Context type, which carries deadlines,
6// cancelation signals, and other request-scoped values across API boundaries
7// and between processes.
8//
9// Incoming requests to a server should create a Context, and outgoing calls to
10// servers should accept a Context. The chain of function calls between must
11// propagate the Context, optionally replacing it with a modified copy created
12// using WithDeadline, WithTimeout, WithCancel, or WithValue.
13//
14// Programs that use Contexts should follow these rules to keep interfaces
15// consistent across packages and enable static analysis tools to check context
16// propagation:
17//
18// Do not store Contexts inside a struct type; instead, pass a Context
19// explicitly to each function that needs it. The Context should be the first
20// parameter, typically named ctx:
21//
22// func DoSomething(ctx context.Context, arg Arg) error {
23// // ... use ctx ...
24// }
25//
26// Do not pass a nil Context, even if a function permits it. Pass context.TODO
27// if you are unsure about which Context to use.
28//
29// Use context Values only for request-scoped data that transits processes and
30// APIs, not for passing optional parameters to functions.
31//
32// The same Context may be passed to functions running in different goroutines;
33// Contexts are safe for simultaneous use by multiple goroutines.
34//
35// See http://blog.golang.org/context for example code for a server that uses
36// Contexts.
37package context // import "golang.org/x/net/context"
38
39// Background returns a non-nil, empty Context. It is never canceled, has no
40// values, and has no deadline. It is typically used by the main function,
41// initialization, and tests, and as the top-level Context for incoming
42// requests.
43func Background() Context {
44 return background
45}
46
47// TODO returns a non-nil, empty Context. Code should use context.TODO when
48// it's unclear which Context to use or it is not yet available (because the
49// surrounding function has not yet been extended to accept a Context
50// parameter). TODO is recognized by static analysis tools that determine
51// whether Contexts are propagated correctly in a program.
52func TODO() Context {
53 return todo
54}
diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go
new file mode 100644
index 0000000..d20f52b
--- /dev/null
+++ b/vendor/golang.org/x/net/context/go17.go
@@ -0,0 +1,72 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.7
6
7package context
8
9import (
10 "context" // standard library's context, as of Go 1.7
11 "time"
12)
13
14var (
15 todo = context.TODO()
16 background = context.Background()
17)
18
19// Canceled is the error returned by Context.Err when the context is canceled.
20var Canceled = context.Canceled
21
22// DeadlineExceeded is the error returned by Context.Err when the context's
23// deadline passes.
24var DeadlineExceeded = context.DeadlineExceeded
25
26// WithCancel returns a copy of parent with a new Done channel. The returned
27// context's Done channel is closed when the returned cancel function is called
28// or when the parent context's Done channel is closed, whichever happens first.
29//
30// Canceling this context releases resources associated with it, so code should
31// call cancel as soon as the operations running in this Context complete.
32func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
33 ctx, f := context.WithCancel(parent)
34 return ctx, CancelFunc(f)
35}
36
37// WithDeadline returns a copy of the parent context with the deadline adjusted
38// to be no later than d. If the parent's deadline is already earlier than d,
39// WithDeadline(parent, d) is semantically equivalent to parent. The returned
40// context's Done channel is closed when the deadline expires, when the returned
41// cancel function is called, or when the parent context's Done channel is
42// closed, whichever happens first.
43//
44// Canceling this context releases resources associated with it, so code should
45// call cancel as soon as the operations running in this Context complete.
46func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
47 ctx, f := context.WithDeadline(parent, deadline)
48 return ctx, CancelFunc(f)
49}
50
51// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
52//
53// Canceling this context releases resources associated with it, so code should
54// call cancel as soon as the operations running in this Context complete:
55//
56// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
57// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
58// defer cancel() // releases resources if slowOperation completes before timeout elapses
59// return slowOperation(ctx)
60// }
61func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
62 return WithDeadline(parent, time.Now().Add(timeout))
63}
64
65// WithValue returns a copy of parent in which the value associated with key is
66// val.
67//
68// Use context Values only for request-scoped data that transits processes and
69// APIs, not for passing optional parameters to functions.
70func WithValue(parent Context, key interface{}, val interface{}) Context {
71 return context.WithValue(parent, key, val)
72}
diff --git a/vendor/golang.org/x/net/context/go19.go b/vendor/golang.org/x/net/context/go19.go
new file mode 100644
index 0000000..d88bd1d
--- /dev/null
+++ b/vendor/golang.org/x/net/context/go19.go
@@ -0,0 +1,20 @@
1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.9
6
7package context
8
9import "context" // standard library's context, as of Go 1.7
10
11// A Context carries a deadline, a cancelation signal, and other values across
12// API boundaries.
13//
14// Context's methods may be called by multiple goroutines simultaneously.
15type Context = context.Context
16
17// A CancelFunc tells an operation to abandon its work.
18// A CancelFunc does not wait for the work to stop.
19// After the first call, subsequent calls to a CancelFunc do nothing.
20type CancelFunc = context.CancelFunc
diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go
new file mode 100644
index 0000000..0f35592
--- /dev/null
+++ b/vendor/golang.org/x/net/context/pre_go17.go
@@ -0,0 +1,300 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build !go1.7
6
7package context
8
9import (
10 "errors"
11 "fmt"
12 "sync"
13 "time"
14)
15
16// An emptyCtx is never canceled, has no values, and has no deadline. It is not
17// struct{}, since vars of this type must have distinct addresses.
18type emptyCtx int
19
20func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
21 return
22}
23
24func (*emptyCtx) Done() <-chan struct{} {
25 return nil
26}
27
28func (*emptyCtx) Err() error {
29 return nil
30}
31
32func (*emptyCtx) Value(key interface{}) interface{} {
33 return nil
34}
35
36func (e *emptyCtx) String() string {
37 switch e {
38 case background:
39 return "context.Background"
40 case todo:
41 return "context.TODO"
42 }
43 return "unknown empty Context"
44}
45
46var (
47 background = new(emptyCtx)
48 todo = new(emptyCtx)
49)
50
51// Canceled is the error returned by Context.Err when the context is canceled.
52var Canceled = errors.New("context canceled")
53
54// DeadlineExceeded is the error returned by Context.Err when the context's
55// deadline passes.
56var DeadlineExceeded = errors.New("context deadline exceeded")
57
58// WithCancel returns a copy of parent with a new Done channel. The returned
59// context's Done channel is closed when the returned cancel function is called
60// or when the parent context's Done channel is closed, whichever happens first.
61//
62// Canceling this context releases resources associated with it, so code should
63// call cancel as soon as the operations running in this Context complete.
64func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
65 c := newCancelCtx(parent)
66 propagateCancel(parent, c)
67 return c, func() { c.cancel(true, Canceled) }
68}
69
70// newCancelCtx returns an initialized cancelCtx.
71func newCancelCtx(parent Context) *cancelCtx {
72 return &cancelCtx{
73 Context: parent,
74 done: make(chan struct{}),
75 }
76}
77
78// propagateCancel arranges for child to be canceled when parent is.
79func propagateCancel(parent Context, child canceler) {
80 if parent.Done() == nil {
81 return // parent is never canceled
82 }
83 if p, ok := parentCancelCtx(parent); ok {
84 p.mu.Lock()
85 if p.err != nil {
86 // parent has already been canceled
87 child.cancel(false, p.err)
88 } else {
89 if p.children == nil {
90 p.children = make(map[canceler]bool)
91 }
92 p.children[child] = true
93 }
94 p.mu.Unlock()
95 } else {
96 go func() {
97 select {
98 case <-parent.Done():
99 child.cancel(false, parent.Err())
100 case <-child.Done():
101 }
102 }()
103 }
104}
105
106// parentCancelCtx follows a chain of parent references until it finds a
107// *cancelCtx. This function understands how each of the concrete types in this
108// package represents its parent.
109func parentCancelCtx(parent Context) (*cancelCtx, bool) {
110 for {
111 switch c := parent.(type) {
112 case *cancelCtx:
113 return c, true
114 case *timerCtx:
115 return c.cancelCtx, true
116 case *valueCtx:
117 parent = c.Context
118 default:
119 return nil, false
120 }
121 }
122}
123
124// removeChild removes a context from its parent.
125func removeChild(parent Context, child canceler) {
126 p, ok := parentCancelCtx(parent)
127 if !ok {
128 return
129 }
130 p.mu.Lock()
131 if p.children != nil {
132 delete(p.children, child)
133 }
134 p.mu.Unlock()
135}
136
137// A canceler is a context type that can be canceled directly. The
138// implementations are *cancelCtx and *timerCtx.
139type canceler interface {
140 cancel(removeFromParent bool, err error)
141 Done() <-chan struct{}
142}
143
144// A cancelCtx can be canceled. When canceled, it also cancels any children
145// that implement canceler.
146type cancelCtx struct {
147 Context
148
149 done chan struct{} // closed by the first cancel call.
150
151 mu sync.Mutex
152 children map[canceler]bool // set to nil by the first cancel call
153 err error // set to non-nil by the first cancel call
154}
155
156func (c *cancelCtx) Done() <-chan struct{} {
157 return c.done
158}
159
160func (c *cancelCtx) Err() error {
161 c.mu.Lock()
162 defer c.mu.Unlock()
163 return c.err
164}
165
166func (c *cancelCtx) String() string {
167 return fmt.Sprintf("%v.WithCancel", c.Context)
168}
169
170// cancel closes c.done, cancels each of c's children, and, if
171// removeFromParent is true, removes c from its parent's children.
172func (c *cancelCtx) cancel(removeFromParent bool, err error) {
173 if err == nil {
174 panic("context: internal error: missing cancel error")
175 }
176 c.mu.Lock()
177 if c.err != nil {
178 c.mu.Unlock()
179 return // already canceled
180 }
181 c.err = err
182 close(c.done)
183 for child := range c.children {
184 // NOTE: acquiring the child's lock while holding parent's lock.
185 child.cancel(false, err)
186 }
187 c.children = nil
188 c.mu.Unlock()
189
190 if removeFromParent {
191 removeChild(c.Context, c)
192 }
193}
194
195// WithDeadline returns a copy of the parent context with the deadline adjusted
196// to be no later than d. If the parent's deadline is already earlier than d,
197// WithDeadline(parent, d) is semantically equivalent to parent. The returned
198// context's Done channel is closed when the deadline expires, when the returned
199// cancel function is called, or when the parent context's Done channel is
200// closed, whichever happens first.
201//
202// Canceling this context releases resources associated with it, so code should
203// call cancel as soon as the operations running in this Context complete.
204func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
205 if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
206 // The current deadline is already sooner than the new one.
207 return WithCancel(parent)
208 }
209 c := &timerCtx{
210 cancelCtx: newCancelCtx(parent),
211 deadline: deadline,
212 }
213 propagateCancel(parent, c)
214 d := deadline.Sub(time.Now())
215 if d <= 0 {
216 c.cancel(true, DeadlineExceeded) // deadline has already passed
217 return c, func() { c.cancel(true, Canceled) }
218 }
219 c.mu.Lock()
220 defer c.mu.Unlock()
221 if c.err == nil {
222 c.timer = time.AfterFunc(d, func() {
223 c.cancel(true, DeadlineExceeded)
224 })
225 }
226 return c, func() { c.cancel(true, Canceled) }
227}
228
229// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
230// implement Done and Err. It implements cancel by stopping its timer then
231// delegating to cancelCtx.cancel.
232type timerCtx struct {
233 *cancelCtx
234 timer *time.Timer // Under cancelCtx.mu.
235
236 deadline time.Time
237}
238
239func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
240 return c.deadline, true
241}
242
243func (c *timerCtx) String() string {
244 return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
245}
246
247func (c *timerCtx) cancel(removeFromParent bool, err error) {
248 c.cancelCtx.cancel(false, err)
249 if removeFromParent {
250 // Remove this timerCtx from its parent cancelCtx's children.
251 removeChild(c.cancelCtx.Context, c)
252 }
253 c.mu.Lock()
254 if c.timer != nil {
255 c.timer.Stop()
256 c.timer = nil
257 }
258 c.mu.Unlock()
259}
260
261// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
262//
263// Canceling this context releases resources associated with it, so code should
264// call cancel as soon as the operations running in this Context complete:
265//
266// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
267// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
268// defer cancel() // releases resources if slowOperation completes before timeout elapses
269// return slowOperation(ctx)
270// }
271func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
272 return WithDeadline(parent, time.Now().Add(timeout))
273}
274
275// WithValue returns a copy of parent in which the value associated with key is
276// val.
277//
278// Use context Values only for request-scoped data that transits processes and
279// APIs, not for passing optional parameters to functions.
280func WithValue(parent Context, key interface{}, val interface{}) Context {
281 return &valueCtx{parent, key, val}
282}
283
284// A valueCtx carries a key-value pair. It implements Value for that key and
285// delegates all other calls to the embedded Context.
286type valueCtx struct {
287 Context
288 key, val interface{}
289}
290
291func (c *valueCtx) String() string {
292 return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
293}
294
295func (c *valueCtx) Value(key interface{}) interface{} {
296 if c.key == key {
297 return c.val
298 }
299 return c.Context.Value(key)
300}
diff --git a/vendor/golang.org/x/net/context/pre_go19.go b/vendor/golang.org/x/net/context/pre_go19.go
new file mode 100644
index 0000000..b105f80
--- /dev/null
+++ b/vendor/golang.org/x/net/context/pre_go19.go
@@ -0,0 +1,109 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build !go1.9
6
7package context
8
9import "time"
10
11// A Context carries a deadline, a cancelation signal, and other values across
12// API boundaries.
13//
14// Context's methods may be called by multiple goroutines simultaneously.
15type Context interface {
16 // Deadline returns the time when work done on behalf of this context
17 // should be canceled. Deadline returns ok==false when no deadline is
18 // set. Successive calls to Deadline return the same results.
19 Deadline() (deadline time.Time, ok bool)
20
21 // Done returns a channel that's closed when work done on behalf of this
22 // context should be canceled. Done may return nil if this context can
23 // never be canceled. Successive calls to Done return the same value.
24 //
25 // WithCancel arranges for Done to be closed when cancel is called;
26 // WithDeadline arranges for Done to be closed when the deadline
27 // expires; WithTimeout arranges for Done to be closed when the timeout
28 // elapses.
29 //
30 // Done is provided for use in select statements:
31 //
32 // // Stream generates values with DoSomething and sends them to out
33 // // until DoSomething returns an error or ctx.Done is closed.
34 // func Stream(ctx context.Context, out chan<- Value) error {
35 // for {
36 // v, err := DoSomething(ctx)
37 // if err != nil {
38 // return err
39 // }
40 // select {
41 // case <-ctx.Done():
42 // return ctx.Err()
43 // case out <- v:
44 // }
45 // }
46 // }
47 //
48 // See http://blog.golang.org/pipelines for more examples of how to use
49 // a Done channel for cancelation.
50 Done() <-chan struct{}
51
52 // Err returns a non-nil error value after Done is closed. Err returns
53 // Canceled if the context was canceled or DeadlineExceeded if the
54 // context's deadline passed. No other values for Err are defined.
55 // After Done is closed, successive calls to Err return the same value.
56 Err() error
57
58 // Value returns the value associated with this context for key, or nil
59 // if no value is associated with key. Successive calls to Value with
60 // the same key returns the same result.
61 //
62 // Use context values only for request-scoped data that transits
63 // processes and API boundaries, not for passing optional parameters to
64 // functions.
65 //
66 // A key identifies a specific value in a Context. Functions that wish
67 // to store values in Context typically allocate a key in a global
68 // variable then use that key as the argument to context.WithValue and
69 // Context.Value. A key can be any type that supports equality;
70 // packages should define keys as an unexported type to avoid
71 // collisions.
72 //
73 // Packages that define a Context key should provide type-safe accessors
74 // for the values stores using that key:
75 //
76 // // Package user defines a User type that's stored in Contexts.
77 // package user
78 //
79 // import "golang.org/x/net/context"
80 //
81 // // User is the type of value stored in the Contexts.
82 // type User struct {...}
83 //
84 // // key is an unexported type for keys defined in this package.
85 // // This prevents collisions with keys defined in other packages.
86 // type key int
87 //
88 // // userKey is the key for user.User values in Contexts. It is
89 // // unexported; clients use user.NewContext and user.FromContext
90 // // instead of using this key directly.
91 // var userKey key = 0
92 //
93 // // NewContext returns a new Context that carries value u.
94 // func NewContext(ctx context.Context, u *User) context.Context {
95 // return context.WithValue(ctx, userKey, u)
96 // }
97 //
98 // // FromContext returns the User value stored in ctx, if any.
99 // func FromContext(ctx context.Context) (*User, bool) {
100 // u, ok := ctx.Value(userKey).(*User)
101 // return u, ok
102 // }
103 Value(key interface{}) interface{}
104}
105
106// A CancelFunc tells an operation to abandon its work.
107// A CancelFunc does not wait for the work to stop.
108// After the first call, subsequent calls to a CancelFunc do nothing.
109type CancelFunc func()
diff --git a/vendor/golang.org/x/net/html/atom/gen.go b/vendor/golang.org/x/net/html/atom/gen.go
new file mode 100644
index 0000000..cc5dc5d
--- /dev/null
+++ b/vendor/golang.org/x/net/html/atom/gen.go
@@ -0,0 +1,709 @@
1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build ignore
6
7//go:generate go run gen.go
8//go:generate go run gen.go -test
9
10package main
11
12import (
13 "bytes"
14 "flag"
15 "fmt"
16 "go/format"
17 "io/ioutil"
18 "math/rand"
19 "os"
20 "sort"
21 "strings"
22)
23
24// identifier converts s to a Go exported identifier.
25// It converts "div" to "Div" and "accept-charset" to "AcceptCharset".
26func identifier(s string) string {
27 b := make([]byte, 0, len(s))
28 cap := true
29 for _, c := range s {
30 if c == '-' {
31 cap = true
32 continue
33 }
34 if cap && 'a' <= c && c <= 'z' {
35 c -= 'a' - 'A'
36 }
37 cap = false
38 b = append(b, byte(c))
39 }
40 return string(b)
41}
42
43var test = flag.Bool("test", false, "generate table_test.go")
44
45func genFile(name string, buf *bytes.Buffer) {
46 b, err := format.Source(buf.Bytes())
47 if err != nil {
48 fmt.Fprintln(os.Stderr, err)
49 os.Exit(1)
50 }
51 if err := ioutil.WriteFile(name, b, 0644); err != nil {
52 fmt.Fprintln(os.Stderr, err)
53 os.Exit(1)
54 }
55}
56
57func main() {
58 flag.Parse()
59
60 var all []string
61 all = append(all, elements...)
62 all = append(all, attributes...)
63 all = append(all, eventHandlers...)
64 all = append(all, extra...)
65 sort.Strings(all)
66
67 // uniq - lists have dups
68 w := 0
69 for _, s := range all {
70 if w == 0 || all[w-1] != s {
71 all[w] = s
72 w++
73 }
74 }
75 all = all[:w]
76
77 if *test {
78 var buf bytes.Buffer
79 fmt.Fprintln(&buf, "// Code generated by go generate gen.go; DO NOT EDIT.\n")
80 fmt.Fprintln(&buf, "//go:generate go run gen.go -test\n")
81 fmt.Fprintln(&buf, "package atom\n")
82 fmt.Fprintln(&buf, "var testAtomList = []string{")
83 for _, s := range all {
84 fmt.Fprintf(&buf, "\t%q,\n", s)
85 }
86 fmt.Fprintln(&buf, "}")
87
88 genFile("table_test.go", &buf)
89 return
90 }
91
92 // Find hash that minimizes table size.
93 var best *table
94 for i := 0; i < 1000000; i++ {
95 if best != nil && 1<<(best.k-1) < len(all) {
96 break
97 }
98 h := rand.Uint32()
99 for k := uint(0); k <= 16; k++ {
100 if best != nil && k >= best.k {
101 break
102 }
103 var t table
104 if t.init(h, k, all) {
105 best = &t
106 break
107 }
108 }
109 }
110 if best == nil {
111 fmt.Fprintf(os.Stderr, "failed to construct string table\n")
112 os.Exit(1)
113 }
114
115 // Lay out strings, using overlaps when possible.
116 layout := append([]string{}, all...)
117
118 // Remove strings that are substrings of other strings
119 for changed := true; changed; {
120 changed = false
121 for i, s := range layout {
122 if s == "" {
123 continue
124 }
125 for j, t := range layout {
126 if i != j && t != "" && strings.Contains(s, t) {
127 changed = true
128 layout[j] = ""
129 }
130 }
131 }
132 }
133
134 // Join strings where one suffix matches another prefix.
135 for {
136 // Find best i, j, k such that layout[i][len-k:] == layout[j][:k],
137 // maximizing overlap length k.
138 besti := -1
139 bestj := -1
140 bestk := 0
141 for i, s := range layout {
142 if s == "" {
143 continue
144 }
145 for j, t := range layout {
146 if i == j {
147 continue
148 }
149 for k := bestk + 1; k <= len(s) && k <= len(t); k++ {
150 if s[len(s)-k:] == t[:k] {
151 besti = i
152 bestj = j
153 bestk = k
154 }
155 }
156 }
157 }
158 if bestk > 0 {
159 layout[besti] += layout[bestj][bestk:]
160 layout[bestj] = ""
161 continue
162 }
163 break
164 }
165
166 text := strings.Join(layout, "")
167
168 atom := map[string]uint32{}
169 for _, s := range all {
170 off := strings.Index(text, s)
171 if off < 0 {
172 panic("lost string " + s)
173 }
174 atom[s] = uint32(off<<8 | len(s))
175 }
176
177 var buf bytes.Buffer
178 // Generate the Go code.
179 fmt.Fprintln(&buf, "// Code generated by go generate gen.go; DO NOT EDIT.\n")
180 fmt.Fprintln(&buf, "//go:generate go run gen.go\n")
181 fmt.Fprintln(&buf, "package atom\n\nconst (")
182
183 // compute max len
184 maxLen := 0
185 for _, s := range all {
186 if maxLen < len(s) {
187 maxLen = len(s)
188 }
189 fmt.Fprintf(&buf, "\t%s Atom = %#x\n", identifier(s), atom[s])
190 }
191 fmt.Fprintln(&buf, ")\n")
192
193 fmt.Fprintf(&buf, "const hash0 = %#x\n\n", best.h0)
194 fmt.Fprintf(&buf, "const maxAtomLen = %d\n\n", maxLen)
195
196 fmt.Fprintf(&buf, "var table = [1<<%d]Atom{\n", best.k)
197 for i, s := range best.tab {
198 if s == "" {
199 continue
200 }
201 fmt.Fprintf(&buf, "\t%#x: %#x, // %s\n", i, atom[s], s)
202 }
203 fmt.Fprintf(&buf, "}\n")
204 datasize := (1 << best.k) * 4
205
206 fmt.Fprintln(&buf, "const atomText =")
207 textsize := len(text)
208 for len(text) > 60 {
209 fmt.Fprintf(&buf, "\t%q +\n", text[:60])
210 text = text[60:]
211 }
212 fmt.Fprintf(&buf, "\t%q\n\n", text)
213
214 genFile("table.go", &buf)
215
216 fmt.Fprintf(os.Stdout, "%d atoms; %d string bytes + %d tables = %d total data\n", len(all), textsize, datasize, textsize+datasize)
217}
218
219type byLen []string
220
221func (x byLen) Less(i, j int) bool { return len(x[i]) > len(x[j]) }
222func (x byLen) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
223func (x byLen) Len() int { return len(x) }
224
225// fnv computes the FNV hash with an arbitrary starting value h.
226func fnv(h uint32, s string) uint32 {
227 for i := 0; i < len(s); i++ {
228 h ^= uint32(s[i])
229 h *= 16777619
230 }
231 return h
232}
233
234// A table represents an attempt at constructing the lookup table.
235// The lookup table uses cuckoo hashing, meaning that each string
236// can be found in one of two positions.
237type table struct {
238 h0 uint32
239 k uint
240 mask uint32
241 tab []string
242}
243
244// hash returns the two hashes for s.
245func (t *table) hash(s string) (h1, h2 uint32) {
246 h := fnv(t.h0, s)
247 h1 = h & t.mask
248 h2 = (h >> 16) & t.mask
249 return
250}
251
252// init initializes the table with the given parameters.
253// h0 is the initial hash value,
254// k is the number of bits of hash value to use, and
255// x is the list of strings to store in the table.
256// init returns false if the table cannot be constructed.
257func (t *table) init(h0 uint32, k uint, x []string) bool {
258 t.h0 = h0
259 t.k = k
260 t.tab = make([]string, 1<<k)
261 t.mask = 1<<k - 1
262 for _, s := range x {
263 if !t.insert(s) {
264 return false
265 }
266 }
267 return true
268}
269
270// insert inserts s in the table.
271func (t *table) insert(s string) bool {
272 h1, h2 := t.hash(s)
273 if t.tab[h1] == "" {
274 t.tab[h1] = s
275 return true
276 }
277 if t.tab[h2] == "" {
278 t.tab[h2] = s
279 return true
280 }
281 if t.push(h1, 0) {
282 t.tab[h1] = s
283 return true
284 }
285 if t.push(h2, 0) {
286 t.tab[h2] = s
287 return true
288 }
289 return false
290}
291
292// push attempts to push aside the entry in slot i.
293func (t *table) push(i uint32, depth int) bool {
294 if depth > len(t.tab) {
295 return false
296 }
297 s := t.tab[i]
298 h1, h2 := t.hash(s)
299 j := h1 + h2 - i
300 if t.tab[j] != "" && !t.push(j, depth+1) {
301 return false
302 }
303 t.tab[j] = s
304 return true
305}
306
307// The lists of element names and attribute keys were taken from
308// https://html.spec.whatwg.org/multipage/indices.html#index
309// as of the "HTML Living Standard - Last Updated 18 September 2017" version.
310
311// "command", "keygen" and "menuitem" have been removed from the spec,
312// but are kept here for backwards compatibility.
313var elements = []string{
314 "a",
315 "abbr",
316 "address",
317 "area",
318 "article",
319 "aside",
320 "audio",
321 "b",
322 "base",
323 "bdi",
324 "bdo",
325 "blockquote",
326 "body",
327 "br",
328 "button",
329 "canvas",
330 "caption",
331 "cite",
332 "code",
333 "col",
334 "colgroup",
335 "command",
336 "data",
337 "datalist",
338 "dd",
339 "del",
340 "details",
341 "dfn",
342 "dialog",
343 "div",
344 "dl",
345 "dt",
346 "em",
347 "embed",
348 "fieldset",
349 "figcaption",
350 "figure",
351 "footer",
352 "form",
353 "h1",
354 "h2",
355 "h3",
356 "h4",
357 "h5",
358 "h6",
359 "head",
360 "header",
361 "hgroup",
362 "hr",
363 "html",
364 "i",
365 "iframe",
366 "img",
367 "input",
368 "ins",
369 "kbd",
370 "keygen",
371 "label",
372 "legend",
373 "li",
374 "link",
375 "main",
376 "map",
377 "mark",
378 "menu",
379 "menuitem",
380 "meta",
381 "meter",
382 "nav",
383 "noscript",
384 "object",
385 "ol",
386 "optgroup",
387 "option",
388 "output",
389 "p",
390 "param",
391 "picture",
392 "pre",
393 "progress",
394 "q",
395 "rp",
396 "rt",
397 "ruby",
398 "s",
399 "samp",
400 "script",
401 "section",
402 "select",
403 "slot",
404 "small",
405 "source",
406 "span",
407 "strong",
408 "style",
409 "sub",
410 "summary",
411 "sup",
412 "table",
413 "tbody",
414 "td",
415 "template",
416 "textarea",
417 "tfoot",
418 "th",
419 "thead",
420 "time",
421 "title",
422 "tr",
423 "track",
424 "u",
425 "ul",
426 "var",
427 "video",
428 "wbr",
429}
430
431// https://html.spec.whatwg.org/multipage/indices.html#attributes-3
432//
433// "challenge", "command", "contextmenu", "dropzone", "icon", "keytype", "mediagroup",
434// "radiogroup", "spellcheck", "scoped", "seamless", "sortable" and "sorted" have been removed from the spec,
435// but are kept here for backwards compatibility.
436var attributes = []string{
437 "abbr",
438 "accept",
439 "accept-charset",
440 "accesskey",
441 "action",
442 "allowfullscreen",
443 "allowpaymentrequest",
444 "allowusermedia",
445 "alt",
446 "as",
447 "async",
448 "autocomplete",
449 "autofocus",
450 "autoplay",
451 "challenge",
452 "charset",
453 "checked",
454 "cite",
455 "class",
456 "color",
457 "cols",
458 "colspan",
459 "command",
460 "content",
461 "contenteditable",
462 "contextmenu",
463 "controls",
464 "coords",
465 "crossorigin",
466 "data",
467 "datetime",
468 "default",
469 "defer",
470 "dir",
471 "dirname",
472 "disabled",
473 "download",
474 "draggable",
475 "dropzone",
476 "enctype",
477 "for",
478 "form",
479 "formaction",
480 "formenctype",
481 "formmethod",
482 "formnovalidate",
483 "formtarget",
484 "headers",
485 "height",
486 "hidden",
487 "high",
488 "href",
489 "hreflang",
490 "http-equiv",
491 "icon",
492 "id",
493 "inputmode",
494 "integrity",
495 "is",
496 "ismap",
497 "itemid",
498 "itemprop",
499 "itemref",
500 "itemscope",
501 "itemtype",
502 "keytype",
503 "kind",
504 "label",
505 "lang",
506 "list",
507 "loop",
508 "low",
509 "manifest",
510 "max",
511 "maxlength",
512 "media",
513 "mediagroup",
514 "method",
515 "min",
516 "minlength",
517 "multiple",
518 "muted",
519 "name",
520 "nomodule",
521 "nonce",
522 "novalidate",
523 "open",
524 "optimum",
525 "pattern",
526 "ping",
527 "placeholder",
528 "playsinline",
529 "poster",
530 "preload",
531 "radiogroup",
532 "readonly",
533 "referrerpolicy",
534 "rel",
535 "required",
536 "reversed",
537 "rows",
538 "rowspan",
539 "sandbox",
540 "spellcheck",
541 "scope",
542 "scoped",
543 "seamless",
544 "selected",
545 "shape",
546 "size",
547 "sizes",
548 "sortable",
549 "sorted",
550 "slot",
551 "span",
552 "spellcheck",
553 "src",
554 "srcdoc",
555 "srclang",
556 "srcset",
557 "start",
558 "step",
559 "style",
560 "tabindex",
561 "target",
562 "title",
563 "translate",
564 "type",
565 "typemustmatch",
566 "updateviacache",
567 "usemap",
568 "value",
569 "width",
570 "workertype",
571 "wrap",
572}
573
574// "onautocomplete", "onautocompleteerror", "onmousewheel",
575// "onshow" and "onsort" have been removed from the spec,
576// but are kept here for backwards compatibility.
577var eventHandlers = []string{
578 "onabort",
579 "onautocomplete",
580 "onautocompleteerror",
581 "onauxclick",
582 "onafterprint",
583 "onbeforeprint",
584 "onbeforeunload",
585 "onblur",
586 "oncancel",
587 "oncanplay",
588 "oncanplaythrough",
589 "onchange",
590 "onclick",
591 "onclose",
592 "oncontextmenu",
593 "oncopy",
594 "oncuechange",
595 "oncut",
596 "ondblclick",
597 "ondrag",
598 "ondragend",
599 "ondragenter",
600 "ondragexit",
601 "ondragleave",
602 "ondragover",
603 "ondragstart",
604 "ondrop",
605 "ondurationchange",
606 "onemptied",
607 "onended",
608 "onerror",
609 "onfocus",
610 "onhashchange",
611 "oninput",
612 "oninvalid",
613 "onkeydown",
614 "onkeypress",
615 "onkeyup",
616 "onlanguagechange",
617 "onload",
618 "onloadeddata",
619 "onloadedmetadata",
620 "onloadend",
621 "onloadstart",
622 "onmessage",
623 "onmessageerror",
624 "onmousedown",
625 "onmouseenter",
626 "onmouseleave",
627 "onmousemove",
628 "onmouseout",
629 "onmouseover",
630 "onmouseup",
631 "onmousewheel",
632 "onwheel",
633 "onoffline",
634 "ononline",
635 "onpagehide",
636 "onpageshow",
637 "onpaste",
638 "onpause",
639 "onplay",
640 "onplaying",
641 "onpopstate",
642 "onprogress",
643 "onratechange",
644 "onreset",
645 "onresize",
646 "onrejectionhandled",
647 "onscroll",
648 "onsecuritypolicyviolation",
649 "onseeked",
650 "onseeking",
651 "onselect",
652 "onshow",
653 "onsort",
654 "onstalled",
655 "onstorage",
656 "onsubmit",
657 "onsuspend",
658 "ontimeupdate",
659 "ontoggle",
660 "onunhandledrejection",
661 "onunload",
662 "onvolumechange",
663 "onwaiting",
664}
665
666// extra are ad-hoc values not covered by any of the lists above.
667var extra = []string{
668 "align",
669 "annotation",
670 "annotation-xml",
671 "applet",
672 "basefont",
673 "bgsound",
674 "big",
675 "blink",
676 "center",
677 "color",
678 "desc",
679 "face",
680 "font",
681 "foreignObject", // HTML is case-insensitive, but SVG-embedded-in-HTML is case-sensitive.
682 "foreignobject",
683 "frame",
684 "frameset",
685 "image",
686 "isindex",
687 "listing",
688 "malignmark",
689 "marquee",
690 "math",
691 "mglyph",
692 "mi",
693 "mn",
694 "mo",
695 "ms",
696 "mtext",
697 "nobr",
698 "noembed",
699 "noframes",
700 "plaintext",
701 "prompt",
702 "public",
703 "spacer",
704 "strike",
705 "svg",
706 "system",
707 "tt",
708 "xmp",
709}
diff --git a/vendor/golang.org/x/net/html/atom/table.go b/vendor/golang.org/x/net/html/atom/table.go
index 2605ba3..f74018e 100644
--- a/vendor/golang.org/x/net/html/atom/table.go
+++ b/vendor/golang.org/x/net/html/atom/table.go
@@ -1,713 +1,777 @@
1// generated by go run gen.go; DO NOT EDIT 1// Code generated by go generate gen.go; DO NOT EDIT.
2
3//go:generate go run gen.go
2 4
3package atom 5package atom
4 6
5const ( 7const (
6 A Atom = 0x1 8 A Atom = 0x1
7 Abbr Atom = 0x4 9 Abbr Atom = 0x4
8 Accept Atom = 0x2106 10 Accept Atom = 0x1a06
9 AcceptCharset Atom = 0x210e 11 AcceptCharset Atom = 0x1a0e
10 Accesskey Atom = 0x3309 12 Accesskey Atom = 0x2c09
11 Action Atom = 0x1f606 13 Action Atom = 0x25a06
12 Address Atom = 0x4f307 14 Address Atom = 0x6ed07
13 Align Atom = 0x1105 15 Align Atom = 0x6d405
14 Alt Atom = 0x4503 16 Allowfullscreen Atom = 0x1f00f
15 Annotation Atom = 0x1670a 17 Allowpaymentrequest Atom = 0x6913
16 AnnotationXml Atom = 0x1670e 18 Allowusermedia Atom = 0x850e
17 Applet Atom = 0x2b306 19 Alt Atom = 0xb003
18 Area Atom = 0x2fa04 20 Annotation Atom = 0x1b90a
19 Article Atom = 0x38807 21 AnnotationXml Atom = 0x1b90e
20 Aside Atom = 0x8305 22 Applet Atom = 0x30106
21 Async Atom = 0x7b05 23 Area Atom = 0x34a04
22 Audio Atom = 0xa605 24 Article Atom = 0x3f007
23 Autocomplete Atom = 0x1fc0c 25 As Atom = 0xb902
24 Autofocus Atom = 0xb309 26 Aside Atom = 0xc105
25 Autoplay Atom = 0xce08 27 Async Atom = 0xb905
26 B Atom = 0x101 28 Audio Atom = 0xcf05
27 Base Atom = 0xd604 29 Autocomplete Atom = 0x2600c
28 Basefont Atom = 0xd608 30 Autofocus Atom = 0xeb09
29 Bdi Atom = 0x1a03 31 Autoplay Atom = 0x10608
30 Bdo Atom = 0xe703 32 B Atom = 0x101
31 Bgsound Atom = 0x11807 33 Base Atom = 0x11504
32 Big Atom = 0x12403 34 Basefont Atom = 0x11508
33 Blink Atom = 0x12705 35 Bdi Atom = 0x16103
34 Blockquote Atom = 0x12c0a 36 Bdo Atom = 0x13403
35 Body Atom = 0x2f04 37 Bgsound Atom = 0x14707
36 Br Atom = 0x202 38 Big Atom = 0x15903
37 Button Atom = 0x13606 39 Blink Atom = 0x15c05
38 Canvas Atom = 0x7f06 40 Blockquote Atom = 0x1680a
39 Caption Atom = 0x1bb07 41 Body Atom = 0x2804
40 Center Atom = 0x5b506 42 Br Atom = 0x202
41 Challenge Atom = 0x21f09 43 Button Atom = 0x17206
42 Charset Atom = 0x2807 44 Canvas Atom = 0xbd06
43 Checked Atom = 0x32807 45 Caption Atom = 0x21907
44 Cite Atom = 0x3c804 46 Center Atom = 0x20806
45 Class Atom = 0x4de05 47 Challenge Atom = 0x28309
46 Code Atom = 0x14904 48 Charset Atom = 0x2107
47 Col Atom = 0x15003 49 Checked Atom = 0x46d07
48 Colgroup Atom = 0x15008 50 Cite Atom = 0x55804
49 Color Atom = 0x15d05 51 Class Atom = 0x5b905
50 Cols Atom = 0x16204 52 Code Atom = 0x19004
51 Colspan Atom = 0x16207 53 Col Atom = 0x19703
52 Command Atom = 0x17507 54 Colgroup Atom = 0x19708
53 Content Atom = 0x42307 55 Color Atom = 0x1af05
54 Contenteditable Atom = 0x4230f 56 Cols Atom = 0x1b404
55 Contextmenu Atom = 0x3310b 57 Colspan Atom = 0x1b407
56 Controls Atom = 0x18808 58 Command Atom = 0x1c707
57 Coords Atom = 0x19406 59 Content Atom = 0x57f07
58 Crossorigin Atom = 0x19f0b 60 Contenteditable Atom = 0x57f0f
59 Data Atom = 0x44a04 61 Contextmenu Atom = 0x3740b
60 Datalist Atom = 0x44a08 62 Controls Atom = 0x1ce08
61 Datetime Atom = 0x23c08 63 Coords Atom = 0x1da06
62 Dd Atom = 0x26702 64 Crossorigin Atom = 0x1e30b
63 Default Atom = 0x8607 65 Data Atom = 0x49904
64 Defer Atom = 0x14b05 66 Datalist Atom = 0x49908
65 Del Atom = 0x3ef03 67 Datetime Atom = 0x2a008
66 Desc Atom = 0x4db04 68 Dd Atom = 0x2bf02
67 Details Atom = 0x4807 69 Default Atom = 0xc407
68 Dfn Atom = 0x6103 70 Defer Atom = 0x19205
69 Dialog Atom = 0x1b06 71 Del Atom = 0x44603
70 Dir Atom = 0x6903 72 Desc Atom = 0x55504
71 Dirname Atom = 0x6907 73 Details Atom = 0x4607
72 Disabled Atom = 0x10c08 74 Dfn Atom = 0x5f03
73 Div Atom = 0x11303 75 Dialog Atom = 0x16206
74 Dl Atom = 0x11e02 76 Dir Atom = 0xa303
75 Download Atom = 0x40008 77 Dirname Atom = 0xa307
76 Draggable Atom = 0x17b09 78 Disabled Atom = 0x14d08
77 Dropzone Atom = 0x39108 79 Div Atom = 0x15403
78 Dt Atom = 0x50902 80 Dl Atom = 0x5e202
79 Em Atom = 0x6502 81 Download Atom = 0x45708
80 Embed Atom = 0x6505 82 Draggable Atom = 0x18309
81 Enctype Atom = 0x21107 83 Dropzone Atom = 0x3f908
82 Face Atom = 0x5b304 84 Dt Atom = 0x64702
83 Fieldset Atom = 0x1b008 85 Em Atom = 0x4202
84 Figcaption Atom = 0x1b80a 86 Embed Atom = 0x4205
85 Figure Atom = 0x1cc06 87 Enctype Atom = 0x27507
86 Font Atom = 0xda04 88 Face Atom = 0x20604
87 Footer Atom = 0x8d06 89 Fieldset Atom = 0x20e08
88 For Atom = 0x1d803 90 Figcaption Atom = 0x2160a
89 ForeignObject Atom = 0x1d80d 91 Figure Atom = 0x23006
90 Foreignobject Atom = 0x1e50d 92 Font Atom = 0x11904
91 Form Atom = 0x1f204 93 Footer Atom = 0xb306
92 Formaction Atom = 0x1f20a 94 For Atom = 0x23c03
93 Formenctype Atom = 0x20d0b 95 ForeignObject Atom = 0x23c0d
94 Formmethod Atom = 0x2280a 96 Foreignobject Atom = 0x2490d
95 Formnovalidate Atom = 0x2320e 97 Form Atom = 0x25604
96 Formtarget Atom = 0x2470a 98 Formaction Atom = 0x2560a
97 Frame Atom = 0x9a05 99 Formenctype Atom = 0x2710b
98 Frameset Atom = 0x9a08 100 Formmethod Atom = 0x28c0a
99 H1 Atom = 0x26e02 101 Formnovalidate Atom = 0x2960e
100 H2 Atom = 0x29402 102 Formtarget Atom = 0x2a80a
101 H3 Atom = 0x2a702 103 Frame Atom = 0x5705
102 H4 Atom = 0x2e902 104 Frameset Atom = 0x5708
103 H5 Atom = 0x2f302 105 H1 Atom = 0x14502
104 H6 Atom = 0x50b02 106 H2 Atom = 0x2c602
105 Head Atom = 0x2d504 107 H3 Atom = 0x2f502
106 Header Atom = 0x2d506 108 H4 Atom = 0x33902
107 Headers Atom = 0x2d507 109 H5 Atom = 0x34302
108 Height Atom = 0x25106 110 H6 Atom = 0x64902
109 Hgroup Atom = 0x25906 111 Head Atom = 0x32504
110 Hidden Atom = 0x26506 112 Header Atom = 0x32506
111 High Atom = 0x26b04 113 Headers Atom = 0x32507
112 Hr Atom = 0x27002 114 Height Atom = 0x12c06
113 Href Atom = 0x27004 115 Hgroup Atom = 0x2b206
114 Hreflang Atom = 0x27008 116 Hidden Atom = 0x2bd06
115 Html Atom = 0x25504 117 High Atom = 0x2c304
116 HttpEquiv Atom = 0x2780a 118 Hr Atom = 0x14002
117 I Atom = 0x601 119 Href Atom = 0x2c804
118 Icon Atom = 0x42204 120 Hreflang Atom = 0x2c808
119 Id Atom = 0x8502 121 Html Atom = 0x13004
120 Iframe Atom = 0x29606 122 HttpEquiv Atom = 0x2d00a
121 Image Atom = 0x29c05 123 I Atom = 0x601
122 Img Atom = 0x2a103 124 Icon Atom = 0x57e04
123 Input Atom = 0x3e805 125 Id Atom = 0xc302
124 Inputmode Atom = 0x3e809 126 Iframe Atom = 0x2e406
125 Ins Atom = 0x1a803 127 Image Atom = 0x2ea05
126 Isindex Atom = 0x2a907 128 Img Atom = 0x2ef03
127 Ismap Atom = 0x2b005 129 Input Atom = 0x43f05
128 Itemid Atom = 0x33c06 130 Inputmode Atom = 0x43f09
129 Itemprop Atom = 0x3c908 131 Ins Atom = 0x1ec03
130 Itemref Atom = 0x5ad07 132 Integrity Atom = 0x22709
131 Itemscope Atom = 0x2b909 133 Is Atom = 0x14e02
132 Itemtype Atom = 0x2c308 134 Isindex Atom = 0x2f707
133 Kbd Atom = 0x1903 135 Ismap Atom = 0x2fe05
134 Keygen Atom = 0x3906 136 Itemid Atom = 0x37f06
135 Keytype Atom = 0x53707 137 Itemprop Atom = 0x55908
136 Kind Atom = 0x10904 138 Itemref Atom = 0x3c107
137 Label Atom = 0xf005 139 Itemscope Atom = 0x66d09
138 Lang Atom = 0x27404 140 Itemtype Atom = 0x30708
139 Legend Atom = 0x18206 141 Kbd Atom = 0x16003
140 Li Atom = 0x1202 142 Keygen Atom = 0x3206
141 Link Atom = 0x12804 143 Keytype Atom = 0x7e07
142 List Atom = 0x44e04 144 Kind Atom = 0x18004
143 Listing Atom = 0x44e07 145 Label Atom = 0xda05
144 Loop Atom = 0xf404 146 Lang Atom = 0x2cc04
145 Low Atom = 0x11f03 147 Legend Atom = 0x18a06
146 Malignmark Atom = 0x100a 148 Li Atom = 0x11102
147 Manifest Atom = 0x5f108 149 Link Atom = 0x15d04
148 Map Atom = 0x2b203 150 List Atom = 0x49d04
149 Mark Atom = 0x1604 151 Listing Atom = 0x49d07
150 Marquee Atom = 0x2cb07 152 Loop Atom = 0xde04
151 Math Atom = 0x2d204 153 Low Atom = 0x6b03
152 Max Atom = 0x2e103 154 Main Atom = 0x1004
153 Maxlength Atom = 0x2e109 155 Malignmark Atom = 0x6d30a
154 Media Atom = 0x6e05 156 Manifest Atom = 0x30f08
155 Mediagroup Atom = 0x6e0a 157 Map Atom = 0x30003
156 Menu Atom = 0x33804 158 Mark Atom = 0x6d904
157 Menuitem Atom = 0x33808 159 Marquee Atom = 0x31b07
158 Meta Atom = 0x45d04 160 Math Atom = 0x32204
159 Meter Atom = 0x24205 161 Max Atom = 0x33103
160 Method Atom = 0x22c06 162 Maxlength Atom = 0x33109
161 Mglyph Atom = 0x2a206 163 Media Atom = 0x8e05
162 Mi Atom = 0x2eb02 164 Mediagroup Atom = 0x8e0a
163 Min Atom = 0x2eb03 165 Menu Atom = 0x37b04
164 Minlength Atom = 0x2eb09 166 Menuitem Atom = 0x37b08
165 Mn Atom = 0x23502 167 Meta Atom = 0x4ac04
166 Mo Atom = 0x3ed02 168 Meter Atom = 0xa805
167 Ms Atom = 0x2bc02 169 Method Atom = 0x29006
168 Mtext Atom = 0x2f505 170 Mglyph Atom = 0x2f006
169 Multiple Atom = 0x30308 171 Mi Atom = 0x33b02
170 Muted Atom = 0x30b05 172 Min Atom = 0x33b03
171 Name Atom = 0x6c04 173 Minlength Atom = 0x33b09
172 Nav Atom = 0x3e03 174 Mn Atom = 0x29902
173 Nobr Atom = 0x5704 175 Mo Atom = 0x6302
174 Noembed Atom = 0x6307 176 Ms Atom = 0x67002
175 Noframes Atom = 0x9808 177 Mtext Atom = 0x34505
176 Noscript Atom = 0x3d208 178 Multiple Atom = 0x35308
177 Novalidate Atom = 0x2360a 179 Muted Atom = 0x35b05
178 Object Atom = 0x1ec06 180 Name Atom = 0xa604
179 Ol Atom = 0xc902 181 Nav Atom = 0x1303
180 Onabort Atom = 0x13a07 182 Nobr Atom = 0x3704
181 Onafterprint Atom = 0x1c00c 183 Noembed Atom = 0x4007
182 Onautocomplete Atom = 0x1fa0e 184 Noframes Atom = 0x5508
183 Onautocompleteerror Atom = 0x1fa13 185 Nomodule Atom = 0x6108
184 Onbeforeprint Atom = 0x6040d 186 Nonce Atom = 0x56205
185 Onbeforeunload Atom = 0x4e70e 187 Noscript Atom = 0x1fe08
186 Onblur Atom = 0xaa06 188 Novalidate Atom = 0x29a0a
187 Oncancel Atom = 0xe908 189 Object Atom = 0x25006
188 Oncanplay Atom = 0x28509 190 Ol Atom = 0x10102
189 Oncanplaythrough Atom = 0x28510 191 Onabort Atom = 0x17607
190 Onchange Atom = 0x3a708 192 Onafterprint Atom = 0x21e0c
191 Onclick Atom = 0x31007 193 Onautocomplete Atom = 0x25e0e
192 Onclose Atom = 0x31707 194 Onautocompleteerror Atom = 0x25e13
193 Oncontextmenu Atom = 0x32f0d 195 Onauxclick Atom = 0x61b0a
194 Oncuechange Atom = 0x3420b 196 Onbeforeprint Atom = 0x69a0d
195 Ondblclick Atom = 0x34d0a 197 Onbeforeunload Atom = 0x6e10e
196 Ondrag Atom = 0x35706 198 Onblur Atom = 0x5c206
197 Ondragend Atom = 0x35709 199 Oncancel Atom = 0xd308
198 Ondragenter Atom = 0x3600b 200 Oncanplay Atom = 0x13609
199 Ondragleave Atom = 0x36b0b 201 Oncanplaythrough Atom = 0x13610
200 Ondragover Atom = 0x3760a 202 Onchange Atom = 0x40f08
201 Ondragstart Atom = 0x3800b 203 Onclick Atom = 0x2dd07
202 Ondrop Atom = 0x38f06 204 Onclose Atom = 0x36007
203 Ondurationchange Atom = 0x39f10 205 Oncontextmenu Atom = 0x3720d
204 Onemptied Atom = 0x39609 206 Oncopy Atom = 0x38506
205 Onended Atom = 0x3af07 207 Oncuechange Atom = 0x38b0b
206 Onerror Atom = 0x3b607 208 Oncut Atom = 0x39605
207 Onfocus Atom = 0x3bd07 209 Ondblclick Atom = 0x39b0a
208 Onhashchange Atom = 0x3da0c 210 Ondrag Atom = 0x3a506
209 Oninput Atom = 0x3e607 211 Ondragend Atom = 0x3a509
210 Oninvalid Atom = 0x3f209 212 Ondragenter Atom = 0x3ae0b
211 Onkeydown Atom = 0x3fb09 213 Ondragexit Atom = 0x3b90a
212 Onkeypress Atom = 0x4080a 214 Ondragleave Atom = 0x3d30b
213 Onkeyup Atom = 0x41807 215 Ondragover Atom = 0x3de0a
214 Onlanguagechange Atom = 0x43210 216 Ondragstart Atom = 0x3e80b
215 Onload Atom = 0x44206 217 Ondrop Atom = 0x3f706
216 Onloadeddata Atom = 0x4420c 218 Ondurationchange Atom = 0x40710
217 Onloadedmetadata Atom = 0x45510 219 Onemptied Atom = 0x3fe09
218 Onloadstart Atom = 0x46b0b 220 Onended Atom = 0x41707
219 Onmessage Atom = 0x47609 221 Onerror Atom = 0x41e07
220 Onmousedown Atom = 0x47f0b 222 Onfocus Atom = 0x42507
221 Onmousemove Atom = 0x48a0b 223 Onhashchange Atom = 0x4310c
222 Onmouseout Atom = 0x4950a 224 Oninput Atom = 0x43d07
223 Onmouseover Atom = 0x4a20b 225 Oninvalid Atom = 0x44909
224 Onmouseup Atom = 0x4ad09 226 Onkeydown Atom = 0x45209
225 Onmousewheel Atom = 0x4b60c 227 Onkeypress Atom = 0x45f0a
226 Onoffline Atom = 0x4c209 228 Onkeyup Atom = 0x47407
227 Ononline Atom = 0x4cb08 229 Onlanguagechange Atom = 0x48110
228 Onpagehide Atom = 0x4d30a 230 Onload Atom = 0x49106
229 Onpageshow Atom = 0x4fe0a 231 Onloadeddata Atom = 0x4910c
230 Onpause Atom = 0x50d07 232 Onloadedmetadata Atom = 0x4a410
231 Onplay Atom = 0x51706 233 Onloadend Atom = 0x4ba09
232 Onplaying Atom = 0x51709 234 Onloadstart Atom = 0x4c30b
233 Onpopstate Atom = 0x5200a 235 Onmessage Atom = 0x4ce09
234 Onprogress Atom = 0x52a0a 236 Onmessageerror Atom = 0x4ce0e
235 Onratechange Atom = 0x53e0c 237 Onmousedown Atom = 0x4dc0b
236 Onreset Atom = 0x54a07 238 Onmouseenter Atom = 0x4e70c
237 Onresize Atom = 0x55108 239 Onmouseleave Atom = 0x4f30c
238 Onscroll Atom = 0x55f08 240 Onmousemove Atom = 0x4ff0b
239 Onseeked Atom = 0x56708 241 Onmouseout Atom = 0x50a0a
240 Onseeking Atom = 0x56f09 242 Onmouseover Atom = 0x5170b
241 Onselect Atom = 0x57808 243 Onmouseup Atom = 0x52209
242 Onshow Atom = 0x58206 244 Onmousewheel Atom = 0x5300c
243 Onsort Atom = 0x58b06 245 Onoffline Atom = 0x53c09
244 Onstalled Atom = 0x59509 246 Ononline Atom = 0x54508
245 Onstorage Atom = 0x59e09 247 Onpagehide Atom = 0x54d0a
246 Onsubmit Atom = 0x5a708 248 Onpageshow Atom = 0x5670a
247 Onsuspend Atom = 0x5bb09 249 Onpaste Atom = 0x57307
248 Ontimeupdate Atom = 0xdb0c 250 Onpause Atom = 0x58e07
249 Ontoggle Atom = 0x5c408 251 Onplay Atom = 0x59806
250 Onunload Atom = 0x5cc08 252 Onplaying Atom = 0x59809
251 Onvolumechange Atom = 0x5d40e 253 Onpopstate Atom = 0x5a10a
252 Onwaiting Atom = 0x5e209 254 Onprogress Atom = 0x5ab0a
253 Open Atom = 0x3cf04 255 Onratechange Atom = 0x5c80c
254 Optgroup Atom = 0xf608 256 Onrejectionhandled Atom = 0x5d412
255 Optimum Atom = 0x5eb07 257 Onreset Atom = 0x5e607
256 Option Atom = 0x60006 258 Onresize Atom = 0x5ed08
257 Output Atom = 0x49c06 259 Onscroll Atom = 0x5fc08
258 P Atom = 0xc01 260 Onsecuritypolicyviolation Atom = 0x60419
259 Param Atom = 0xc05 261 Onseeked Atom = 0x62508
260 Pattern Atom = 0x5107 262 Onseeking Atom = 0x62d09
261 Ping Atom = 0x7704 263 Onselect Atom = 0x63608
262 Placeholder Atom = 0xc30b 264 Onshow Atom = 0x64006
263 Plaintext Atom = 0xfd09 265 Onsort Atom = 0x64b06
264 Poster Atom = 0x15706 266 Onstalled Atom = 0x65509
265 Pre Atom = 0x25e03 267 Onstorage Atom = 0x65e09
266 Preload Atom = 0x25e07 268 Onsubmit Atom = 0x66708
267 Progress Atom = 0x52c08 269 Onsuspend Atom = 0x67709
268 Prompt Atom = 0x5fa06 270 Ontimeupdate Atom = 0x11a0c
269 Public Atom = 0x41e06 271 Ontoggle Atom = 0x68008
270 Q Atom = 0x13101 272 Onunhandledrejection Atom = 0x68814
271 Radiogroup Atom = 0x30a 273 Onunload Atom = 0x6a708
272 Readonly Atom = 0x2fb08 274 Onvolumechange Atom = 0x6af0e
273 Rel Atom = 0x25f03 275 Onwaiting Atom = 0x6bd09
274 Required Atom = 0x1d008 276 Onwheel Atom = 0x6c607
275 Reversed Atom = 0x5a08 277 Open Atom = 0x55f04
276 Rows Atom = 0x9204 278 Optgroup Atom = 0xe008
277 Rowspan Atom = 0x9207 279 Optimum Atom = 0x6cd07
278 Rp Atom = 0x1c602 280 Option Atom = 0x6dd06
279 Rt Atom = 0x13f02 281 Output Atom = 0x51106
280 Ruby Atom = 0xaf04 282 P Atom = 0xc01
281 S Atom = 0x2c01 283 Param Atom = 0xc05
282 Samp Atom = 0x4e04 284 Pattern Atom = 0x4f07
283 Sandbox Atom = 0xbb07 285 Picture Atom = 0x9707
284 Scope Atom = 0x2bd05 286 Ping Atom = 0xe704
285 Scoped Atom = 0x2bd06 287 Placeholder Atom = 0xfb0b
286 Script Atom = 0x3d406 288 Plaintext Atom = 0x19e09
287 Seamless Atom = 0x31c08 289 Playsinline Atom = 0x10a0b
288 Section Atom = 0x4e207 290 Poster Atom = 0x2b706
289 Select Atom = 0x57a06 291 Pre Atom = 0x46403
290 Selected Atom = 0x57a08 292 Preload Atom = 0x47a07
291 Shape Atom = 0x4f905 293 Progress Atom = 0x5ad08
292 Size Atom = 0x55504 294 Prompt Atom = 0x52a06
293 Sizes Atom = 0x55505 295 Public Atom = 0x57a06
294 Small Atom = 0x18f05 296 Q Atom = 0x7701
295 Sortable Atom = 0x58d08 297 Radiogroup Atom = 0x30a
296 Sorted Atom = 0x19906 298 Readonly Atom = 0x34b08
297 Source Atom = 0x1aa06 299 Referrerpolicy Atom = 0x3c50e
298 Spacer Atom = 0x2db06 300 Rel Atom = 0x47b03
299 Span Atom = 0x9504 301 Required Atom = 0x23408
300 Spellcheck Atom = 0x3230a 302 Reversed Atom = 0x9c08
301 Src Atom = 0x3c303 303 Rows Atom = 0x3a04
302 Srcdoc Atom = 0x3c306 304 Rowspan Atom = 0x3a07
303 Srclang Atom = 0x41107 305 Rp Atom = 0x22402
304 Start Atom = 0x38605 306 Rt Atom = 0x17b02
305 Step Atom = 0x5f704 307 Ruby Atom = 0xac04
306 Strike Atom = 0x53306 308 S Atom = 0x2501
307 Strong Atom = 0x55906 309 Samp Atom = 0x4c04
308 Style Atom = 0x61105 310 Sandbox Atom = 0xf307
309 Sub Atom = 0x5a903 311 Scope Atom = 0x67105
310 Summary Atom = 0x61607 312 Scoped Atom = 0x67106
311 Sup Atom = 0x61d03 313 Script Atom = 0x20006
312 Svg Atom = 0x62003 314 Seamless Atom = 0x36508
313 System Atom = 0x62306 315 Section Atom = 0x5bd07
314 Tabindex Atom = 0x46308 316 Select Atom = 0x63806
315 Table Atom = 0x42d05 317 Selected Atom = 0x63808
316 Target Atom = 0x24b06 318 Shape Atom = 0x1d505
317 Tbody Atom = 0x2e05 319 Size Atom = 0x5f104
318 Td Atom = 0x4702 320 Sizes Atom = 0x5f105
319 Template Atom = 0x62608 321 Slot Atom = 0x1df04
320 Textarea Atom = 0x2f608 322 Small Atom = 0x1ee05
321 Tfoot Atom = 0x8c05 323 Sortable Atom = 0x64d08
322 Th Atom = 0x22e02 324 Sorted Atom = 0x32b06
323 Thead Atom = 0x2d405 325 Source Atom = 0x36c06
324 Time Atom = 0xdd04 326 Spacer Atom = 0x42b06
325 Title Atom = 0xa105 327 Span Atom = 0x3d04
326 Tr Atom = 0x10502 328 Spellcheck Atom = 0x4680a
327 Track Atom = 0x10505 329 Src Atom = 0x5b403
328 Translate Atom = 0x14009 330 Srcdoc Atom = 0x5b406
329 Tt Atom = 0x5302 331 Srclang Atom = 0x5f507
330 Type Atom = 0x21404 332 Srcset Atom = 0x6f306
331 Typemustmatch Atom = 0x2140d 333 Start Atom = 0x3ee05
332 U Atom = 0xb01 334 Step Atom = 0x57704
333 Ul Atom = 0x8a02 335 Strike Atom = 0x7a06
334 Usemap Atom = 0x51106 336 Strong Atom = 0x31506
335 Value Atom = 0x4005 337 Style Atom = 0x6f905
336 Var Atom = 0x11503 338 Sub Atom = 0x66903
337 Video Atom = 0x28105 339 Summary Atom = 0x6fe07
338 Wbr Atom = 0x12103 340 Sup Atom = 0x70503
339 Width Atom = 0x50705 341 Svg Atom = 0x70803
340 Wrap Atom = 0x58704 342 System Atom = 0x70b06
341 Xmp Atom = 0xc103 343 Tabindex Atom = 0x4b208
344 Table Atom = 0x58905
345 Target Atom = 0x2ac06
346 Tbody Atom = 0x2705
347 Td Atom = 0x5e02
348 Template Atom = 0x70e08
349 Textarea Atom = 0x34608
350 Tfoot Atom = 0xb205
351 Th Atom = 0x13f02
352 Thead Atom = 0x32405
353 Time Atom = 0x11c04
354 Title Atom = 0xca05
355 Tr Atom = 0x7402
356 Track Atom = 0x17c05
357 Translate Atom = 0x1a609
358 Tt Atom = 0x5102
359 Type Atom = 0x8104
360 Typemustmatch Atom = 0x2780d
361 U Atom = 0xb01
362 Ul Atom = 0x6602
363 Updateviacache Atom = 0x1200e
364 Usemap Atom = 0x59206
365 Value Atom = 0x1505
366 Var Atom = 0x15603
367 Video Atom = 0x2d905
368 Wbr Atom = 0x57003
369 Width Atom = 0x64505
370 Workertype Atom = 0x7160a
371 Wrap Atom = 0x72004
372 Xmp Atom = 0xf903
342) 373)
343 374
344const hash0 = 0xc17da63e 375const hash0 = 0x81cdf10e
345 376
346const maxAtomLen = 19 377const maxAtomLen = 25
347 378
348var table = [1 << 9]Atom{ 379var table = [1 << 9]Atom{
349 0x1: 0x48a0b, // onmousemove 380 0x1: 0x8e0a, // mediagroup
350 0x2: 0x5e209, // onwaiting 381 0x2: 0x2cc04, // lang
351 0x3: 0x1fa13, // onautocompleteerror 382 0x4: 0x2c09, // accesskey
352 0x4: 0x5fa06, // prompt 383 0x5: 0x5708, // frameset
353 0x7: 0x5eb07, // optimum 384 0x7: 0x63608, // onselect
354 0x8: 0x1604, // mark 385 0x8: 0x70b06, // system
355 0xa: 0x5ad07, // itemref 386 0xa: 0x64505, // width
356 0xb: 0x4fe0a, // onpageshow 387 0xc: 0x2710b, // formenctype
357 0xc: 0x57a06, // select 388 0xd: 0x10102, // ol
358 0xd: 0x17b09, // draggable 389 0xe: 0x38b0b, // oncuechange
359 0xe: 0x3e03, // nav 390 0x10: 0x13403, // bdo
360 0xf: 0x17507, // command 391 0x11: 0xcf05, // audio
361 0x11: 0xb01, // u 392 0x12: 0x18309, // draggable
362 0x14: 0x2d507, // headers 393 0x14: 0x2d905, // video
363 0x15: 0x44a08, // datalist 394 0x15: 0x29902, // mn
364 0x17: 0x4e04, // samp 395 0x16: 0x37b04, // menu
365 0x1a: 0x3fb09, // onkeydown 396 0x17: 0x2b706, // poster
366 0x1b: 0x55f08, // onscroll 397 0x19: 0xb306, // footer
367 0x1c: 0x15003, // col 398 0x1a: 0x29006, // method
368 0x20: 0x3c908, // itemprop 399 0x1b: 0x2a008, // datetime
369 0x21: 0x2780a, // http-equiv 400 0x1c: 0x17607, // onabort
370 0x22: 0x61d03, // sup 401 0x1d: 0x1200e, // updateviacache
371 0x24: 0x1d008, // required 402 0x1e: 0xb905, // async
372 0x2b: 0x25e07, // preload 403 0x1f: 0x49106, // onload
373 0x2c: 0x6040d, // onbeforeprint 404 0x21: 0xd308, // oncancel
374 0x2d: 0x3600b, // ondragenter 405 0x22: 0x62508, // onseeked
375 0x2e: 0x50902, // dt 406 0x23: 0x2ea05, // image
376 0x2f: 0x5a708, // onsubmit 407 0x24: 0x5d412, // onrejectionhandled
377 0x30: 0x27002, // hr 408 0x26: 0x15d04, // link
378 0x31: 0x32f0d, // oncontextmenu 409 0x27: 0x51106, // output
379 0x33: 0x29c05, // image 410 0x28: 0x32504, // head
380 0x34: 0x50d07, // onpause 411 0x29: 0x4f30c, // onmouseleave
381 0x35: 0x25906, // hgroup 412 0x2a: 0x57307, // onpaste
382 0x36: 0x7704, // ping 413 0x2b: 0x59809, // onplaying
383 0x37: 0x57808, // onselect 414 0x2c: 0x1b407, // colspan
384 0x3a: 0x11303, // div 415 0x2f: 0x1af05, // color
385 0x3b: 0x1fa0e, // onautocomplete 416 0x30: 0x5f104, // size
386 0x40: 0x2eb02, // mi 417 0x31: 0x2d00a, // http-equiv
387 0x41: 0x31c08, // seamless 418 0x33: 0x601, // i
388 0x42: 0x2807, // charset 419 0x34: 0x54d0a, // onpagehide
389 0x43: 0x8502, // id 420 0x35: 0x68814, // onunhandledrejection
390 0x44: 0x5200a, // onpopstate 421 0x37: 0x41e07, // onerror
391 0x45: 0x3ef03, // del 422 0x3a: 0x11508, // basefont
392 0x46: 0x2cb07, // marquee 423 0x3f: 0x1303, // nav
393 0x47: 0x3309, // accesskey 424 0x40: 0x18004, // kind
394 0x49: 0x8d06, // footer 425 0x41: 0x34b08, // readonly
395 0x4a: 0x44e04, // list 426 0x42: 0x2f006, // mglyph
396 0x4b: 0x2b005, // ismap 427 0x44: 0x11102, // li
397 0x51: 0x33804, // menu 428 0x46: 0x2bd06, // hidden
398 0x52: 0x2f04, // body 429 0x47: 0x70803, // svg
399 0x55: 0x9a08, // frameset 430 0x48: 0x57704, // step
400 0x56: 0x54a07, // onreset 431 0x49: 0x22709, // integrity
401 0x57: 0x12705, // blink 432 0x4a: 0x57a06, // public
402 0x58: 0xa105, // title 433 0x4c: 0x19703, // col
403 0x59: 0x38807, // article 434 0x4d: 0x1680a, // blockquote
404 0x5b: 0x22e02, // th 435 0x4e: 0x34302, // h5
405 0x5d: 0x13101, // q 436 0x50: 0x5ad08, // progress
406 0x5e: 0x3cf04, // open 437 0x51: 0x5f105, // sizes
407 0x5f: 0x2fa04, // area 438 0x52: 0x33902, // h4
408 0x61: 0x44206, // onload 439 0x56: 0x32405, // thead
409 0x62: 0xda04, // font 440 0x57: 0x7e07, // keytype
410 0x63: 0xd604, // base 441 0x58: 0x5ab0a, // onprogress
411 0x64: 0x16207, // colspan 442 0x59: 0x43f09, // inputmode
412 0x65: 0x53707, // keytype 443 0x5a: 0x3a509, // ondragend
413 0x66: 0x11e02, // dl 444 0x5d: 0x39605, // oncut
414 0x68: 0x1b008, // fieldset 445 0x5e: 0x42b06, // spacer
415 0x6a: 0x2eb03, // min 446 0x5f: 0x19708, // colgroup
416 0x6b: 0x11503, // var 447 0x62: 0x14e02, // is
417 0x6f: 0x2d506, // header 448 0x65: 0xb902, // as
418 0x70: 0x13f02, // rt 449 0x66: 0x53c09, // onoffline
419 0x71: 0x15008, // colgroup 450 0x67: 0x32b06, // sorted
420 0x72: 0x23502, // mn 451 0x69: 0x48110, // onlanguagechange
421 0x74: 0x13a07, // onabort 452 0x6c: 0x4310c, // onhashchange
422 0x75: 0x3906, // keygen 453 0x6d: 0xa604, // name
423 0x76: 0x4c209, // onoffline 454 0x6e: 0xb205, // tfoot
424 0x77: 0x21f09, // challenge 455 0x6f: 0x55504, // desc
425 0x78: 0x2b203, // map 456 0x70: 0x33103, // max
426 0x7a: 0x2e902, // h4 457 0x72: 0x1da06, // coords
427 0x7b: 0x3b607, // onerror 458 0x73: 0x2f502, // h3
428 0x7c: 0x2e109, // maxlength 459 0x74: 0x6e10e, // onbeforeunload
429 0x7d: 0x2f505, // mtext 460 0x75: 0x3a04, // rows
430 0x7e: 0xbb07, // sandbox 461 0x76: 0x63806, // select
431 0x7f: 0x58b06, // onsort 462 0x77: 0xa805, // meter
432 0x80: 0x100a, // malignmark 463 0x78: 0x37f06, // itemid
433 0x81: 0x45d04, // meta 464 0x79: 0x5300c, // onmousewheel
434 0x82: 0x7b05, // async 465 0x7a: 0x5b406, // srcdoc
435 0x83: 0x2a702, // h3 466 0x7d: 0x17c05, // track
436 0x84: 0x26702, // dd 467 0x7f: 0x30708, // itemtype
437 0x85: 0x27004, // href 468 0x82: 0x6302, // mo
438 0x86: 0x6e0a, // mediagroup 469 0x83: 0x40f08, // onchange
439 0x87: 0x19406, // coords 470 0x84: 0x32507, // headers
440 0x88: 0x41107, // srclang 471 0x85: 0x5c80c, // onratechange
441 0x89: 0x34d0a, // ondblclick 472 0x86: 0x60419, // onsecuritypolicyviolation
442 0x8a: 0x4005, // value 473 0x88: 0x49908, // datalist
443 0x8c: 0xe908, // oncancel 474 0x89: 0x4dc0b, // onmousedown
444 0x8e: 0x3230a, // spellcheck 475 0x8a: 0x1df04, // slot
445 0x8f: 0x9a05, // frame 476 0x8b: 0x4a410, // onloadedmetadata
446 0x91: 0x12403, // big 477 0x8c: 0x1a06, // accept
447 0x94: 0x1f606, // action 478 0x8d: 0x25006, // object
448 0x95: 0x6903, // dir 479 0x91: 0x6af0e, // onvolumechange
449 0x97: 0x2fb08, // readonly 480 0x92: 0x2107, // charset
450 0x99: 0x42d05, // table 481 0x93: 0x25e13, // onautocompleteerror
451 0x9a: 0x61607, // summary 482 0x94: 0x6913, // allowpaymentrequest
452 0x9b: 0x12103, // wbr 483 0x95: 0x2804, // body
453 0x9c: 0x30a, // radiogroup 484 0x96: 0xc407, // default
454 0x9d: 0x6c04, // name 485 0x97: 0x63808, // selected
455 0x9f: 0x62306, // system 486 0x98: 0x20604, // face
456 0xa1: 0x15d05, // color 487 0x99: 0x1d505, // shape
457 0xa2: 0x7f06, // canvas 488 0x9b: 0x68008, // ontoggle
458 0xa3: 0x25504, // html 489 0x9e: 0x64702, // dt
459 0xa5: 0x56f09, // onseeking 490 0x9f: 0x6d904, // mark
460 0xac: 0x4f905, // shape 491 0xa1: 0xb01, // u
461 0xad: 0x25f03, // rel 492 0xa4: 0x6a708, // onunload
462 0xae: 0x28510, // oncanplaythrough 493 0xa5: 0xde04, // loop
463 0xaf: 0x3760a, // ondragover 494 0xa6: 0x14d08, // disabled
464 0xb0: 0x62608, // template 495 0xaa: 0x41707, // onended
465 0xb1: 0x1d80d, // foreignObject 496 0xab: 0x6d30a, // malignmark
466 0xb3: 0x9204, // rows 497 0xad: 0x67709, // onsuspend
467 0xb6: 0x44e07, // listing 498 0xae: 0x34505, // mtext
468 0xb7: 0x49c06, // output 499 0xaf: 0x64b06, // onsort
469 0xb9: 0x3310b, // contextmenu 500 0xb0: 0x55908, // itemprop
470 0xbb: 0x11f03, // low 501 0xb3: 0x66d09, // itemscope
471 0xbc: 0x1c602, // rp 502 0xb4: 0x15c05, // blink
472 0xbd: 0x5bb09, // onsuspend 503 0xb6: 0x3a506, // ondrag
473 0xbe: 0x13606, // button 504 0xb7: 0x6602, // ul
474 0xbf: 0x4db04, // desc 505 0xb8: 0x25604, // form
475 0xc1: 0x4e207, // section 506 0xb9: 0xf307, // sandbox
476 0xc2: 0x52a0a, // onprogress 507 0xba: 0x5705, // frame
477 0xc3: 0x59e09, // onstorage 508 0xbb: 0x1505, // value
478 0xc4: 0x2d204, // math 509 0xbc: 0x65e09, // onstorage
479 0xc5: 0x4503, // alt 510 0xc0: 0x17b02, // rt
480 0xc7: 0x8a02, // ul 511 0xc2: 0x202, // br
481 0xc8: 0x5107, // pattern 512 0xc3: 0x20e08, // fieldset
482 0xc9: 0x4b60c, // onmousewheel 513 0xc4: 0x2780d, // typemustmatch
483 0xca: 0x35709, // ondragend 514 0xc5: 0x6108, // nomodule
484 0xcb: 0xaf04, // ruby 515 0xc6: 0x4007, // noembed
485 0xcc: 0xc01, // p 516 0xc7: 0x69a0d, // onbeforeprint
486 0xcd: 0x31707, // onclose 517 0xc8: 0x17206, // button
487 0xce: 0x24205, // meter 518 0xc9: 0x2dd07, // onclick
488 0xcf: 0x11807, // bgsound 519 0xca: 0x6fe07, // summary
489 0xd2: 0x25106, // height 520 0xcd: 0xac04, // ruby
490 0xd4: 0x101, // b 521 0xce: 0x5b905, // class
491 0xd5: 0x2c308, // itemtype 522 0xcf: 0x3e80b, // ondragstart
492 0xd8: 0x1bb07, // caption 523 0xd0: 0x21907, // caption
493 0xd9: 0x10c08, // disabled 524 0xd4: 0x850e, // allowusermedia
494 0xdb: 0x33808, // menuitem 525 0xd5: 0x4c30b, // onloadstart
495 0xdc: 0x62003, // svg 526 0xd9: 0x15403, // div
496 0xdd: 0x18f05, // small 527 0xda: 0x49d04, // list
497 0xde: 0x44a04, // data 528 0xdb: 0x32204, // math
498 0xe0: 0x4cb08, // ononline 529 0xdc: 0x43f05, // input
499 0xe1: 0x2a206, // mglyph 530 0xdf: 0x3de0a, // ondragover
500 0xe3: 0x6505, // embed 531 0xe0: 0x2c602, // h2
501 0xe4: 0x10502, // tr 532 0xe2: 0x19e09, // plaintext
502 0xe5: 0x46b0b, // onloadstart 533 0xe4: 0x4e70c, // onmouseenter
503 0xe7: 0x3c306, // srcdoc 534 0xe7: 0x46d07, // checked
504 0xeb: 0x5c408, // ontoggle 535 0xe8: 0x46403, // pre
505 0xed: 0xe703, // bdo 536 0xea: 0x35308, // multiple
506 0xee: 0x4702, // td 537 0xeb: 0x16103, // bdi
507 0xef: 0x8305, // aside 538 0xec: 0x33109, // maxlength
508 0xf0: 0x29402, // h2 539 0xed: 0x7701, // q
509 0xf1: 0x52c08, // progress 540 0xee: 0x61b0a, // onauxclick
510 0xf2: 0x12c0a, // blockquote 541 0xf0: 0x57003, // wbr
511 0xf4: 0xf005, // label 542 0xf2: 0x11504, // base
512 0xf5: 0x601, // i 543 0xf3: 0x6dd06, // option
513 0xf7: 0x9207, // rowspan 544 0xf5: 0x40710, // ondurationchange
514 0xfb: 0x51709, // onplaying 545 0xf7: 0x5508, // noframes
515 0xfd: 0x2a103, // img 546 0xf9: 0x3f908, // dropzone
516 0xfe: 0xf608, // optgroup 547 0xfb: 0x67105, // scope
517 0xff: 0x42307, // content 548 0xfc: 0x9c08, // reversed
518 0x101: 0x53e0c, // onratechange 549 0xfd: 0x3ae0b, // ondragenter
519 0x103: 0x3da0c, // onhashchange 550 0xfe: 0x3ee05, // start
520 0x104: 0x4807, // details 551 0xff: 0xf903, // xmp
521 0x106: 0x40008, // download 552 0x100: 0x5f507, // srclang
522 0x109: 0x14009, // translate 553 0x101: 0x2ef03, // img
523 0x10b: 0x4230f, // contenteditable 554 0x104: 0x101, // b
524 0x10d: 0x36b0b, // ondragleave 555 0x105: 0x23c03, // for
525 0x10e: 0x2106, // accept 556 0x106: 0xc105, // aside
526 0x10f: 0x57a08, // selected 557 0x107: 0x43d07, // oninput
527 0x112: 0x1f20a, // formaction 558 0x108: 0x34a04, // area
528 0x113: 0x5b506, // center 559 0x109: 0x28c0a, // formmethod
529 0x115: 0x45510, // onloadedmetadata 560 0x10a: 0x72004, // wrap
530 0x116: 0x12804, // link 561 0x10c: 0x22402, // rp
531 0x117: 0xdd04, // time 562 0x10d: 0x45f0a, // onkeypress
532 0x118: 0x19f0b, // crossorigin 563 0x10e: 0x5102, // tt
533 0x119: 0x3bd07, // onfocus 564 0x110: 0x33b02, // mi
534 0x11a: 0x58704, // wrap 565 0x111: 0x35b05, // muted
535 0x11b: 0x42204, // icon 566 0x112: 0xb003, // alt
536 0x11d: 0x28105, // video 567 0x113: 0x19004, // code
537 0x11e: 0x4de05, // class 568 0x114: 0x4202, // em
538 0x121: 0x5d40e, // onvolumechange 569 0x115: 0x3b90a, // ondragexit
539 0x122: 0xaa06, // onblur 570 0x117: 0x3d04, // span
540 0x123: 0x2b909, // itemscope 571 0x119: 0x30f08, // manifest
541 0x124: 0x61105, // style 572 0x11a: 0x37b08, // menuitem
542 0x127: 0x41e06, // public 573 0x11b: 0x57f07, // content
543 0x129: 0x2320e, // formnovalidate 574 0x11d: 0x6bd09, // onwaiting
544 0x12a: 0x58206, // onshow 575 0x11f: 0x4ba09, // onloadend
545 0x12c: 0x51706, // onplay 576 0x121: 0x3720d, // oncontextmenu
546 0x12d: 0x3c804, // cite 577 0x123: 0x5c206, // onblur
547 0x12e: 0x2bc02, // ms 578 0x124: 0x3f007, // article
548 0x12f: 0xdb0c, // ontimeupdate 579 0x125: 0xa303, // dir
549 0x130: 0x10904, // kind 580 0x126: 0xe704, // ping
550 0x131: 0x2470a, // formtarget 581 0x127: 0x23408, // required
551 0x135: 0x3af07, // onended 582 0x128: 0x44909, // oninvalid
552 0x136: 0x26506, // hidden 583 0x129: 0x6d405, // align
553 0x137: 0x2c01, // s 584 0x12b: 0x57e04, // icon
554 0x139: 0x2280a, // formmethod 585 0x12c: 0x64902, // h6
555 0x13a: 0x3e805, // input 586 0x12d: 0x1b404, // cols
556 0x13c: 0x50b02, // h6 587 0x12e: 0x2160a, // figcaption
557 0x13d: 0xc902, // ol 588 0x12f: 0x45209, // onkeydown
558 0x13e: 0x3420b, // oncuechange 589 0x130: 0x66708, // onsubmit
559 0x13f: 0x1e50d, // foreignobject 590 0x131: 0x13609, // oncanplay
560 0x143: 0x4e70e, // onbeforeunload 591 0x132: 0x70503, // sup
561 0x144: 0x2bd05, // scope 592 0x133: 0xc01, // p
562 0x145: 0x39609, // onemptied 593 0x135: 0x3fe09, // onemptied
563 0x146: 0x14b05, // defer 594 0x136: 0x38506, // oncopy
564 0x147: 0xc103, // xmp 595 0x137: 0x55804, // cite
565 0x148: 0x39f10, // ondurationchange 596 0x138: 0x39b0a, // ondblclick
566 0x149: 0x1903, // kbd 597 0x13a: 0x4ff0b, // onmousemove
567 0x14c: 0x47609, // onmessage 598 0x13c: 0x66903, // sub
568 0x14d: 0x60006, // option 599 0x13d: 0x47b03, // rel
569 0x14e: 0x2eb09, // minlength 600 0x13e: 0xe008, // optgroup
570 0x14f: 0x32807, // checked 601 0x142: 0x3a07, // rowspan
571 0x150: 0xce08, // autoplay 602 0x143: 0x36c06, // source
572 0x152: 0x202, // br 603 0x144: 0x1fe08, // noscript
573 0x153: 0x2360a, // novalidate 604 0x145: 0x55f04, // open
574 0x156: 0x6307, // noembed 605 0x146: 0x1ec03, // ins
575 0x159: 0x31007, // onclick 606 0x147: 0x23c0d, // foreignObject
576 0x15a: 0x47f0b, // onmousedown 607 0x148: 0x5a10a, // onpopstate
577 0x15b: 0x3a708, // onchange 608 0x14a: 0x27507, // enctype
578 0x15e: 0x3f209, // oninvalid 609 0x14b: 0x25e0e, // onautocomplete
579 0x15f: 0x2bd06, // scoped 610 0x14c: 0x34608, // textarea
580 0x160: 0x18808, // controls 611 0x14e: 0x2600c, // autocomplete
581 0x161: 0x30b05, // muted 612 0x14f: 0x14002, // hr
582 0x162: 0x58d08, // sortable 613 0x150: 0x1ce08, // controls
583 0x163: 0x51106, // usemap 614 0x151: 0xc302, // id
584 0x164: 0x1b80a, // figcaption 615 0x153: 0x21e0c, // onafterprint
585 0x165: 0x35706, // ondrag 616 0x155: 0x2490d, // foreignobject
586 0x166: 0x26b04, // high 617 0x156: 0x31b07, // marquee
587 0x168: 0x3c303, // src 618 0x157: 0x58e07, // onpause
588 0x169: 0x15706, // poster 619 0x158: 0x5e202, // dl
589 0x16b: 0x1670e, // annotation-xml 620 0x159: 0x12c06, // height
590 0x16c: 0x5f704, // step 621 0x15a: 0x33b03, // min
591 0x16d: 0x4, // abbr 622 0x15b: 0xa307, // dirname
592 0x16e: 0x1b06, // dialog 623 0x15c: 0x1a609, // translate
593 0x170: 0x1202, // li 624 0x15d: 0x13004, // html
594 0x172: 0x3ed02, // mo 625 0x15e: 0x33b09, // minlength
595 0x175: 0x1d803, // for 626 0x15f: 0x47a07, // preload
596 0x176: 0x1a803, // ins 627 0x160: 0x70e08, // template
597 0x178: 0x55504, // size 628 0x161: 0x3d30b, // ondragleave
598 0x179: 0x43210, // onlanguagechange 629 0x164: 0x5b403, // src
599 0x17a: 0x8607, // default 630 0x165: 0x31506, // strong
600 0x17b: 0x1a03, // bdi 631 0x167: 0x4c04, // samp
601 0x17c: 0x4d30a, // onpagehide 632 0x168: 0x6ed07, // address
602 0x17d: 0x6907, // dirname 633 0x169: 0x54508, // ononline
603 0x17e: 0x21404, // type 634 0x16b: 0xfb0b, // placeholder
604 0x17f: 0x1f204, // form 635 0x16c: 0x2ac06, // target
605 0x181: 0x28509, // oncanplay 636 0x16d: 0x1ee05, // small
606 0x182: 0x6103, // dfn 637 0x16e: 0x6c607, // onwheel
607 0x183: 0x46308, // tabindex 638 0x16f: 0x1b90a, // annotation
608 0x186: 0x6502, // em 639 0x170: 0x4680a, // spellcheck
609 0x187: 0x27404, // lang 640 0x171: 0x4607, // details
610 0x189: 0x39108, // dropzone 641 0x172: 0xbd06, // canvas
611 0x18a: 0x4080a, // onkeypress 642 0x173: 0xeb09, // autofocus
612 0x18b: 0x23c08, // datetime 643 0x174: 0xc05, // param
613 0x18c: 0x16204, // cols 644 0x176: 0x45708, // download
614 0x18d: 0x1, // a 645 0x177: 0x44603, // del
615 0x18e: 0x4420c, // onloadeddata 646 0x178: 0x36007, // onclose
616 0x190: 0xa605, // audio 647 0x179: 0x16003, // kbd
617 0x192: 0x2e05, // tbody 648 0x17a: 0x30106, // applet
618 0x193: 0x22c06, // method 649 0x17b: 0x2c804, // href
619 0x195: 0xf404, // loop 650 0x17c: 0x5ed08, // onresize
620 0x196: 0x29606, // iframe 651 0x17e: 0x4910c, // onloadeddata
621 0x198: 0x2d504, // head 652 0x180: 0x7402, // tr
622 0x19e: 0x5f108, // manifest 653 0x181: 0x2a80a, // formtarget
623 0x19f: 0xb309, // autofocus 654 0x182: 0xca05, // title
624 0x1a0: 0x14904, // code 655 0x183: 0x6f905, // style
625 0x1a1: 0x55906, // strong 656 0x184: 0x7a06, // strike
626 0x1a2: 0x30308, // multiple 657 0x185: 0x59206, // usemap
627 0x1a3: 0xc05, // param 658 0x186: 0x2e406, // iframe
628 0x1a6: 0x21107, // enctype 659 0x187: 0x1004, // main
629 0x1a7: 0x5b304, // face 660 0x189: 0x9707, // picture
630 0x1a8: 0xfd09, // plaintext 661 0x18c: 0x2fe05, // ismap
631 0x1a9: 0x26e02, // h1 662 0x18e: 0x49904, // data
632 0x1aa: 0x59509, // onstalled 663 0x18f: 0xda05, // label
633 0x1ad: 0x3d406, // script 664 0x191: 0x3c50e, // referrerpolicy
634 0x1ae: 0x2db06, // spacer 665 0x192: 0x13f02, // th
635 0x1af: 0x55108, // onresize 666 0x194: 0x52a06, // prompt
636 0x1b0: 0x4a20b, // onmouseover 667 0x195: 0x5bd07, // section
637 0x1b1: 0x5cc08, // onunload 668 0x197: 0x6cd07, // optimum
638 0x1b2: 0x56708, // onseeked 669 0x198: 0x2c304, // high
639 0x1b4: 0x2140d, // typemustmatch 670 0x199: 0x14502, // h1
640 0x1b5: 0x1cc06, // figure 671 0x19a: 0x65509, // onstalled
641 0x1b6: 0x4950a, // onmouseout 672 0x19b: 0x15603, // var
642 0x1b7: 0x25e03, // pre 673 0x19c: 0x11c04, // time
643 0x1b8: 0x50705, // width 674 0x19e: 0x67002, // ms
644 0x1b9: 0x19906, // sorted 675 0x19f: 0x32506, // header
645 0x1bb: 0x5704, // nobr 676 0x1a0: 0x4ce09, // onmessage
646 0x1be: 0x5302, // tt 677 0x1a1: 0x56205, // nonce
647 0x1bf: 0x1105, // align 678 0x1a2: 0x2560a, // formaction
648 0x1c0: 0x3e607, // oninput 679 0x1a3: 0x20806, // center
649 0x1c3: 0x41807, // onkeyup 680 0x1a4: 0x3704, // nobr
650 0x1c6: 0x1c00c, // onafterprint 681 0x1a5: 0x58905, // table
651 0x1c7: 0x210e, // accept-charset 682 0x1a6: 0x49d07, // listing
652 0x1c8: 0x33c06, // itemid 683 0x1a7: 0x18a06, // legend
653 0x1c9: 0x3e809, // inputmode 684 0x1a9: 0x28309, // challenge
654 0x1cb: 0x53306, // strike 685 0x1aa: 0x23006, // figure
655 0x1cc: 0x5a903, // sub 686 0x1ab: 0x8e05, // media
656 0x1cd: 0x10505, // track 687 0x1ae: 0x8104, // type
657 0x1ce: 0x38605, // start 688 0x1af: 0x11904, // font
658 0x1d0: 0xd608, // basefont 689 0x1b0: 0x4ce0e, // onmessageerror
659 0x1d6: 0x1aa06, // source 690 0x1b1: 0x36508, // seamless
660 0x1d7: 0x18206, // legend 691 0x1b2: 0x5f03, // dfn
661 0x1d8: 0x2d405, // thead 692 0x1b3: 0x19205, // defer
662 0x1da: 0x8c05, // tfoot 693 0x1b4: 0x6b03, // low
663 0x1dd: 0x1ec06, // object 694 0x1b5: 0x62d09, // onseeking
664 0x1de: 0x6e05, // media 695 0x1b6: 0x5170b, // onmouseover
665 0x1df: 0x1670a, // annotation 696 0x1b7: 0x29a0a, // novalidate
666 0x1e0: 0x20d0b, // formenctype 697 0x1b8: 0x7160a, // workertype
667 0x1e2: 0x3d208, // noscript 698 0x1ba: 0x3c107, // itemref
668 0x1e4: 0x55505, // sizes 699 0x1bd: 0x1, // a
669 0x1e5: 0x1fc0c, // autocomplete 700 0x1be: 0x30003, // map
670 0x1e6: 0x9504, // span 701 0x1bf: 0x11a0c, // ontimeupdate
671 0x1e7: 0x9808, // noframes 702 0x1c0: 0x14707, // bgsound
672 0x1e8: 0x24b06, // target 703 0x1c1: 0x3206, // keygen
673 0x1e9: 0x38f06, // ondrop 704 0x1c2: 0x2705, // tbody
674 0x1ea: 0x2b306, // applet 705 0x1c5: 0x64006, // onshow
675 0x1ec: 0x5a08, // reversed 706 0x1c7: 0x2501, // s
676 0x1f0: 0x2a907, // isindex 707 0x1c8: 0x4f07, // pattern
677 0x1f3: 0x27008, // hreflang 708 0x1cc: 0x13610, // oncanplaythrough
678 0x1f5: 0x2f302, // h5 709 0x1ce: 0x2bf02, // dd
679 0x1f6: 0x4f307, // address 710 0x1cf: 0x6f306, // srcset
680 0x1fa: 0x2e103, // max 711 0x1d0: 0x15903, // big
681 0x1fb: 0xc30b, // placeholder 712 0x1d2: 0x64d08, // sortable
682 0x1fc: 0x2f608, // textarea 713 0x1d3: 0x47407, // onkeyup
683 0x1fe: 0x4ad09, // onmouseup 714 0x1d5: 0x59806, // onplay
684 0x1ff: 0x3800b, // ondragstart 715 0x1d7: 0x4ac04, // meta
716 0x1d8: 0x3f706, // ondrop
717 0x1da: 0x5fc08, // onscroll
718 0x1db: 0x1e30b, // crossorigin
719 0x1dc: 0x5670a, // onpageshow
720 0x1dd: 0x4, // abbr
721 0x1de: 0x5e02, // td
722 0x1df: 0x57f0f, // contenteditable
723 0x1e0: 0x25a06, // action
724 0x1e1: 0x10a0b, // playsinline
725 0x1e2: 0x42507, // onfocus
726 0x1e3: 0x2c808, // hreflang
727 0x1e5: 0x50a0a, // onmouseout
728 0x1e6: 0x5e607, // onreset
729 0x1e7: 0x10608, // autoplay
730 0x1ea: 0x67106, // scoped
731 0x1ec: 0x30a, // radiogroup
732 0x1ee: 0x3740b, // contextmenu
733 0x1ef: 0x52209, // onmouseup
734 0x1f1: 0x2b206, // hgroup
735 0x1f2: 0x1f00f, // allowfullscreen
736 0x1f3: 0x4b208, // tabindex
737 0x1f6: 0x2f707, // isindex
738 0x1f7: 0x1a0e, // accept-charset
739 0x1f8: 0x2960e, // formnovalidate
740 0x1fb: 0x1b90e, // annotation-xml
741 0x1fc: 0x4205, // embed
742 0x1fd: 0x20006, // script
743 0x1fe: 0x16206, // dialog
744 0x1ff: 0x1c707, // command
685} 745}
686 746
687const atomText = "abbradiogrouparamalignmarkbdialogaccept-charsetbodyaccesskey" + 747const atomText = "abbradiogrouparamainavalueaccept-charsetbodyaccesskeygenobro" +
688 "genavaluealtdetailsampatternobreversedfnoembedirnamediagroup" + 748 "wspanoembedetailsampatternoframesetdfnomoduleallowpaymentreq" +
689 "ingasyncanvasidefaultfooterowspanoframesetitleaudionblurubya" + 749 "uestrikeytypeallowusermediagroupictureversedirnameterubyaltf" +
690 "utofocusandboxmplaceholderautoplaybasefontimeupdatebdoncance" + 750 "ooterasyncanvasidefaultitleaudioncancelabelooptgroupingautof" +
691 "labelooptgrouplaintextrackindisabledivarbgsoundlowbrbigblink" + 751 "ocusandboxmplaceholderautoplaysinlinebasefontimeupdateviacac" +
692 "blockquotebuttonabortranslatecodefercolgroupostercolorcolspa" + 752 "heightmlbdoncanplaythrough1bgsoundisabledivarbigblinkbdialog" +
693 "nnotation-xmlcommandraggablegendcontrolsmallcoordsortedcross" + 753 "blockquotebuttonabortrackindraggablegendcodefercolgrouplaint" +
694 "originsourcefieldsetfigcaptionafterprintfigurequiredforeignO" + 754 "extranslatecolorcolspannotation-xmlcommandcontrolshapecoords" +
695 "bjectforeignobjectformactionautocompleteerrorformenctypemust" + 755 "lotcrossoriginsmallowfullscreenoscriptfacenterfieldsetfigcap" +
696 "matchallengeformmethodformnovalidatetimeterformtargetheightm" + 756 "tionafterprintegrityfigurequiredforeignObjectforeignobjectfo" +
697 "lhgroupreloadhiddenhigh1hreflanghttp-equivideoncanplaythroug" + 757 "rmactionautocompleteerrorformenctypemustmatchallengeformmeth" +
698 "h2iframeimageimglyph3isindexismappletitemscopeditemtypemarqu" + 758 "odformnovalidatetimeformtargethgrouposterhiddenhigh2hreflang" +
699 "eematheaderspacermaxlength4minlength5mtextareadonlymultiplem" + 759 "http-equivideonclickiframeimageimglyph3isindexismappletitemt" +
700 "utedonclickoncloseamlesspellcheckedoncontextmenuitemidoncuec" + 760 "ypemanifestrongmarqueematheadersortedmaxlength4minlength5mte" +
701 "hangeondblclickondragendondragenterondragleaveondragoverondr" + 761 "xtareadonlymultiplemutedoncloseamlessourceoncontextmenuitemi" +
702 "agstarticleondropzonemptiedondurationchangeonendedonerroronf" + 762 "doncopyoncuechangeoncutondblclickondragendondragenterondrage" +
703 "ocusrcdocitempropenoscriptonhashchangeoninputmodeloninvalido" + 763 "xitemreferrerpolicyondragleaveondragoverondragstarticleondro" +
704 "nkeydownloadonkeypressrclangonkeyupublicontenteditableonlang" + 764 "pzonemptiedondurationchangeonendedonerroronfocuspaceronhashc" +
705 "uagechangeonloadeddatalistingonloadedmetadatabindexonloadsta" + 765 "hangeoninputmodeloninvalidonkeydownloadonkeypresspellchecked" +
706 "rtonmessageonmousedownonmousemoveonmouseoutputonmouseoveronm" + 766 "onkeyupreloadonlanguagechangeonloadeddatalistingonloadedmeta" +
707 "ouseuponmousewheelonofflineononlineonpagehidesclassectionbef" + 767 "databindexonloadendonloadstartonmessageerroronmousedownonmou" +
708 "oreunloaddresshapeonpageshowidth6onpausemaponplayingonpopsta" + 768 "seenteronmouseleaveonmousemoveonmouseoutputonmouseoveronmous" +
709 "teonprogresstrikeytypeonratechangeonresetonresizestrongonscr" + 769 "eupromptonmousewheelonofflineononlineonpagehidescitempropeno" +
710 "ollonseekedonseekingonselectedonshowraponsortableonstalledon" + 770 "nceonpageshowbronpastepublicontenteditableonpausemaponplayin" +
711 "storageonsubmitemrefacenteronsuspendontoggleonunloadonvolume" + 771 "gonpopstateonprogressrcdoclassectionbluronratechangeonreject" +
712 "changeonwaitingoptimumanifestepromptoptionbeforeprintstylesu" + 772 "ionhandledonresetonresizesrclangonscrollonsecuritypolicyviol" +
713 "mmarysupsvgsystemplate" 773 "ationauxclickonseekedonseekingonselectedonshowidth6onsortabl" +
774 "eonstalledonstorageonsubmitemscopedonsuspendontoggleonunhand" +
775 "ledrejectionbeforeprintonunloadonvolumechangeonwaitingonwhee" +
776 "loptimumalignmarkoptionbeforeunloaddressrcsetstylesummarysup" +
777 "svgsystemplateworkertypewrap"
diff --git a/vendor/golang.org/x/net/html/const.go b/vendor/golang.org/x/net/html/const.go
index 52f651f..b37e621 100644
--- a/vendor/golang.org/x/net/html/const.go
+++ b/vendor/golang.org/x/net/html/const.go
@@ -52,10 +52,12 @@ var isSpecialElementMap = map[string]bool{
52 "iframe": true, 52 "iframe": true,
53 "img": true, 53 "img": true,
54 "input": true, 54 "input": true,
55 "isindex": true, 55 "isindex": true, // The 'isindex' element has been removed, but keep it for backwards compatibility.
56 "keygen": true,
56 "li": true, 57 "li": true,
57 "link": true, 58 "link": true,
58 "listing": true, 59 "listing": true,
60 "main": true,
59 "marquee": true, 61 "marquee": true,
60 "menu": true, 62 "menu": true,
61 "meta": true, 63 "meta": true,
diff --git a/vendor/golang.org/x/net/http2/.gitignore b/vendor/golang.org/x/net/http2/.gitignore
new file mode 100644
index 0000000..190f122
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/.gitignore
@@ -0,0 +1,2 @@
1*~
2h2i/h2i
diff --git a/vendor/golang.org/x/net/http2/Dockerfile b/vendor/golang.org/x/net/http2/Dockerfile
new file mode 100644
index 0000000..53fc525
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/Dockerfile
@@ -0,0 +1,51 @@
1#
2# This Dockerfile builds a recent curl with HTTP/2 client support, using
3# a recent nghttp2 build.
4#
5# See the Makefile for how to tag it. If Docker and that image is found, the
6# Go tests use this curl binary for integration tests.
7#
8
9FROM ubuntu:trusty
10
11RUN apt-get update && \
12 apt-get upgrade -y && \
13 apt-get install -y git-core build-essential wget
14
15RUN apt-get install -y --no-install-recommends \
16 autotools-dev libtool pkg-config zlib1g-dev \
17 libcunit1-dev libssl-dev libxml2-dev libevent-dev \
18 automake autoconf
19
20# The list of packages nghttp2 recommends for h2load:
21RUN apt-get install -y --no-install-recommends make binutils \
22 autoconf automake autotools-dev \
23 libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev \
24 libev-dev libevent-dev libjansson-dev libjemalloc-dev \
25 cython python3.4-dev python-setuptools
26
27# Note: setting NGHTTP2_VER before the git clone, so an old git clone isn't cached:
28ENV NGHTTP2_VER 895da9a
29RUN cd /root && git clone https://github.com/tatsuhiro-t/nghttp2.git
30
31WORKDIR /root/nghttp2
32RUN git reset --hard $NGHTTP2_VER
33RUN autoreconf -i
34RUN automake
35RUN autoconf
36RUN ./configure
37RUN make
38RUN make install
39
40WORKDIR /root
41RUN wget http://curl.haxx.se/download/curl-7.45.0.tar.gz
42RUN tar -zxvf curl-7.45.0.tar.gz
43WORKDIR /root/curl-7.45.0
44RUN ./configure --with-ssl --with-nghttp2=/usr/local
45RUN make
46RUN make install
47RUN ldconfig
48
49CMD ["-h"]
50ENTRYPOINT ["/usr/local/bin/curl"]
51
diff --git a/vendor/golang.org/x/net/http2/Makefile b/vendor/golang.org/x/net/http2/Makefile
new file mode 100644
index 0000000..55fd826
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/Makefile
@@ -0,0 +1,3 @@
1curlimage:
2 docker build -t gohttp2/curl .
3
diff --git a/vendor/golang.org/x/net/http2/README b/vendor/golang.org/x/net/http2/README
new file mode 100644
index 0000000..360d5aa
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/README
@@ -0,0 +1,20 @@
1This is a work-in-progress HTTP/2 implementation for Go.
2
3It will eventually live in the Go standard library and won't require
4any changes to your code to use. It will just be automatic.
5
6Status:
7
8* The server support is pretty good. A few things are missing
9 but are being worked on.
10* The client work has just started but shares a lot of code
11 is coming along much quicker.
12
13Docs are at https://godoc.org/golang.org/x/net/http2
14
15Demo test server at https://http2.golang.org/
16
17Help & bug reports welcome!
18
19Contributing: https://golang.org/doc/contribute.html
20Bugs: https://golang.org/issue/new?title=x/net/http2:+
diff --git a/vendor/golang.org/x/net/http2/ciphers.go b/vendor/golang.org/x/net/http2/ciphers.go
new file mode 100644
index 0000000..698860b
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/ciphers.go
@@ -0,0 +1,641 @@
1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7// A list of the possible cipher suite ids. Taken from
8// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt
9
10const (
11 cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000
12 cipher_TLS_RSA_WITH_NULL_MD5 uint16 = 0x0001
13 cipher_TLS_RSA_WITH_NULL_SHA uint16 = 0x0002
14 cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0003
15 cipher_TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
16 cipher_TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
17 cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x0006
18 cipher_TLS_RSA_WITH_IDEA_CBC_SHA uint16 = 0x0007
19 cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0008
20 cipher_TLS_RSA_WITH_DES_CBC_SHA uint16 = 0x0009
21 cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000A
22 cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000B
23 cipher_TLS_DH_DSS_WITH_DES_CBC_SHA uint16 = 0x000C
24 cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x000D
25 cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000E
26 cipher_TLS_DH_RSA_WITH_DES_CBC_SHA uint16 = 0x000F
27 cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0010
28 cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011
29 cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA uint16 = 0x0012
30 cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x0013
31 cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014
32 cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA uint16 = 0x0015
33 cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016
34 cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0017
35 cipher_TLS_DH_anon_WITH_RC4_128_MD5 uint16 = 0x0018
36 cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019
37 cipher_TLS_DH_anon_WITH_DES_CBC_SHA uint16 = 0x001A
38 cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0x001B
39 // Reserved uint16 = 0x001C-1D
40 cipher_TLS_KRB5_WITH_DES_CBC_SHA uint16 = 0x001E
41 cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA uint16 = 0x001F
42 cipher_TLS_KRB5_WITH_RC4_128_SHA uint16 = 0x0020
43 cipher_TLS_KRB5_WITH_IDEA_CBC_SHA uint16 = 0x0021
44 cipher_TLS_KRB5_WITH_DES_CBC_MD5 uint16 = 0x0022
45 cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5 uint16 = 0x0023
46 cipher_TLS_KRB5_WITH_RC4_128_MD5 uint16 = 0x0024
47 cipher_TLS_KRB5_WITH_IDEA_CBC_MD5 uint16 = 0x0025
48 cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA uint16 = 0x0026
49 cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA uint16 = 0x0027
50 cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA uint16 = 0x0028
51 cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 uint16 = 0x0029
52 cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x002A
53 cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5 uint16 = 0x002B
54 cipher_TLS_PSK_WITH_NULL_SHA uint16 = 0x002C
55 cipher_TLS_DHE_PSK_WITH_NULL_SHA uint16 = 0x002D
56 cipher_TLS_RSA_PSK_WITH_NULL_SHA uint16 = 0x002E
57 cipher_TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002F
58 cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0030
59 cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0031
60 cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0032
61 cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033
62 cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA uint16 = 0x0034
63 cipher_TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
64 cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0036
65 cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0037
66 cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0038
67 cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039
68 cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA uint16 = 0x003A
69 cipher_TLS_RSA_WITH_NULL_SHA256 uint16 = 0x003B
70 cipher_TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003C
71 cipher_TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003D
72 cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x003E
73 cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003F
74 cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x0040
75 cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0041
76 cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0042
77 cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0043
78 cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044
79 cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045
80 cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046
81 // Reserved uint16 = 0x0047-4F
82 // Reserved uint16 = 0x0050-58
83 // Reserved uint16 = 0x0059-5C
84 // Unassigned uint16 = 0x005D-5F
85 // Reserved uint16 = 0x0060-66
86 cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067
87 cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x0068
88 cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x0069
89 cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A
90 cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B
91 cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C
92 cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D
93 // Unassigned uint16 = 0x006E-83
94 cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0084
95 cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0085
96 cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0086
97 cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0087
98 cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0088
99 cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0089
100 cipher_TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008A
101 cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008B
102 cipher_TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008C
103 cipher_TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008D
104 cipher_TLS_DHE_PSK_WITH_RC4_128_SHA uint16 = 0x008E
105 cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008F
106 cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0090
107 cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0091
108 cipher_TLS_RSA_PSK_WITH_RC4_128_SHA uint16 = 0x0092
109 cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x0093
110 cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0094
111 cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0095
112 cipher_TLS_RSA_WITH_SEED_CBC_SHA uint16 = 0x0096
113 cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA uint16 = 0x0097
114 cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA uint16 = 0x0098
115 cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA uint16 = 0x0099
116 cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA uint16 = 0x009A
117 cipher_TLS_DH_anon_WITH_SEED_CBC_SHA uint16 = 0x009B
118 cipher_TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009C
119 cipher_TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009D
120 cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009E
121 cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009F
122 cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x00A0
123 cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x00A1
124 cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A2
125 cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A3
126 cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A4
127 cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A5
128 cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256 uint16 = 0x00A6
129 cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384 uint16 = 0x00A7
130 cipher_TLS_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00A8
131 cipher_TLS_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00A9
132 cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AA
133 cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AB
134 cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AC
135 cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AD
136 cipher_TLS_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00AE
137 cipher_TLS_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00AF
138 cipher_TLS_PSK_WITH_NULL_SHA256 uint16 = 0x00B0
139 cipher_TLS_PSK_WITH_NULL_SHA384 uint16 = 0x00B1
140 cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B2
141 cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B3
142 cipher_TLS_DHE_PSK_WITH_NULL_SHA256 uint16 = 0x00B4
143 cipher_TLS_DHE_PSK_WITH_NULL_SHA384 uint16 = 0x00B5
144 cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B6
145 cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B7
146 cipher_TLS_RSA_PSK_WITH_NULL_SHA256 uint16 = 0x00B8
147 cipher_TLS_RSA_PSK_WITH_NULL_SHA384 uint16 = 0x00B9
148 cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BA
149 cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BB
150 cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BC
151 cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD
152 cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE
153 cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF
154 cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C0
155 cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C1
156 cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C2
157 cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3
158 cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4
159 cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5
160 // Unassigned uint16 = 0x00C6-FE
161 cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF
162 // Unassigned uint16 = 0x01-55,*
163 cipher_TLS_FALLBACK_SCSV uint16 = 0x5600
164 // Unassigned uint16 = 0x5601 - 0xC000
165 cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA uint16 = 0xC001
166 cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA uint16 = 0xC002
167 cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC003
168 cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC004
169 cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC005
170 cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA uint16 = 0xC006
171 cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xC007
172 cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC008
173 cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC009
174 cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC00A
175 cipher_TLS_ECDH_RSA_WITH_NULL_SHA uint16 = 0xC00B
176 cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA uint16 = 0xC00C
177 cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC00D
178 cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC00E
179 cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC00F
180 cipher_TLS_ECDHE_RSA_WITH_NULL_SHA uint16 = 0xC010
181 cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xC011
182 cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC012
183 cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC013
184 cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC014
185 cipher_TLS_ECDH_anon_WITH_NULL_SHA uint16 = 0xC015
186 cipher_TLS_ECDH_anon_WITH_RC4_128_SHA uint16 = 0xC016
187 cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0xC017
188 cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA uint16 = 0xC018
189 cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA uint16 = 0xC019
190 cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01A
191 cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01B
192 cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01C
193 cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA uint16 = 0xC01D
194 cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC01E
195 cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA uint16 = 0xC01F
196 cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA uint16 = 0xC020
197 cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC021
198 cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA uint16 = 0xC022
199 cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC023
200 cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC024
201 cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC025
202 cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC026
203 cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC027
204 cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC028
205 cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC029
206 cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC02A
207 cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02B
208 cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02C
209 cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02D
210 cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02E
211 cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02F
212 cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC030
213 cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC031
214 cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC032
215 cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA uint16 = 0xC033
216 cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0xC034
217 cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xC035
218 cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xC036
219 cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0xC037
220 cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0xC038
221 cipher_TLS_ECDHE_PSK_WITH_NULL_SHA uint16 = 0xC039
222 cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256 uint16 = 0xC03A
223 cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384 uint16 = 0xC03B
224 cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03C
225 cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03D
226 cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03E
227 cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03F
228 cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC040
229 cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC041
230 cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC042
231 cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC043
232 cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC044
233 cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC045
234 cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC046
235 cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC047
236 cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC048
237 cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC049
238 cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04A
239 cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04B
240 cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04C
241 cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04D
242 cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04E
243 cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04F
244 cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC050
245 cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC051
246 cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC052
247 cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC053
248 cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC054
249 cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC055
250 cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC056
251 cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC057
252 cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC058
253 cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC059
254 cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05A
255 cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05B
256 cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05C
257 cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05D
258 cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05E
259 cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05F
260 cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC060
261 cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC061
262 cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC062
263 cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC063
264 cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC064
265 cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC065
266 cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC066
267 cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC067
268 cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC068
269 cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC069
270 cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06A
271 cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06B
272 cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06C
273 cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06D
274 cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06E
275 cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06F
276 cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC070
277 cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC071
278 cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072
279 cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073
280 cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC074
281 cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC075
282 cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC076
283 cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC077
284 cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC078
285 cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC079
286 cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07A
287 cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07B
288 cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07C
289 cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07D
290 cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07E
291 cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07F
292 cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC080
293 cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC081
294 cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC082
295 cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC083
296 cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC084
297 cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC085
298 cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086
299 cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087
300 cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC088
301 cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC089
302 cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08A
303 cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08B
304 cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08C
305 cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08D
306 cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08E
307 cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08F
308 cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC090
309 cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC091
310 cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC092
311 cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC093
312 cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC094
313 cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC095
314 cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC096
315 cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC097
316 cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC098
317 cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC099
318 cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC09A
319 cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC09B
320 cipher_TLS_RSA_WITH_AES_128_CCM uint16 = 0xC09C
321 cipher_TLS_RSA_WITH_AES_256_CCM uint16 = 0xC09D
322 cipher_TLS_DHE_RSA_WITH_AES_128_CCM uint16 = 0xC09E
323 cipher_TLS_DHE_RSA_WITH_AES_256_CCM uint16 = 0xC09F
324 cipher_TLS_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A0
325 cipher_TLS_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A1
326 cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A2
327 cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A3
328 cipher_TLS_PSK_WITH_AES_128_CCM uint16 = 0xC0A4
329 cipher_TLS_PSK_WITH_AES_256_CCM uint16 = 0xC0A5
330 cipher_TLS_DHE_PSK_WITH_AES_128_CCM uint16 = 0xC0A6
331 cipher_TLS_DHE_PSK_WITH_AES_256_CCM uint16 = 0xC0A7
332 cipher_TLS_PSK_WITH_AES_128_CCM_8 uint16 = 0xC0A8
333 cipher_TLS_PSK_WITH_AES_256_CCM_8 uint16 = 0xC0A9
334 cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8 uint16 = 0xC0AA
335 cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8 uint16 = 0xC0AB
336 cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM uint16 = 0xC0AC
337 cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM uint16 = 0xC0AD
338 cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 uint16 = 0xC0AE
339 cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 uint16 = 0xC0AF
340 // Unassigned uint16 = 0xC0B0-FF
341 // Unassigned uint16 = 0xC1-CB,*
342 // Unassigned uint16 = 0xCC00-A7
343 cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA8
344 cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9
345 cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAA
346 cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAB
347 cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAC
348 cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAD
349 cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAE
350)
351
352// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
353// References:
354// https://tools.ietf.org/html/rfc7540#appendix-A
355// Reject cipher suites from Appendix A.
356// "This list includes those cipher suites that do not
357// offer an ephemeral key exchange and those that are
358// based on the TLS null, stream or block cipher type"
359func isBadCipher(cipher uint16) bool {
360 switch cipher {
361 case cipher_TLS_NULL_WITH_NULL_NULL,
362 cipher_TLS_RSA_WITH_NULL_MD5,
363 cipher_TLS_RSA_WITH_NULL_SHA,
364 cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5,
365 cipher_TLS_RSA_WITH_RC4_128_MD5,
366 cipher_TLS_RSA_WITH_RC4_128_SHA,
367 cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
368 cipher_TLS_RSA_WITH_IDEA_CBC_SHA,
369 cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
370 cipher_TLS_RSA_WITH_DES_CBC_SHA,
371 cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
372 cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
373 cipher_TLS_DH_DSS_WITH_DES_CBC_SHA,
374 cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
375 cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
376 cipher_TLS_DH_RSA_WITH_DES_CBC_SHA,
377 cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
378 cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
379 cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA,
380 cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
381 cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
382 cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA,
383 cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
384 cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,
385 cipher_TLS_DH_anon_WITH_RC4_128_MD5,
386 cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
387 cipher_TLS_DH_anon_WITH_DES_CBC_SHA,
388 cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
389 cipher_TLS_KRB5_WITH_DES_CBC_SHA,
390 cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA,
391 cipher_TLS_KRB5_WITH_RC4_128_SHA,
392 cipher_TLS_KRB5_WITH_IDEA_CBC_SHA,
393 cipher_TLS_KRB5_WITH_DES_CBC_MD5,
394 cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5,
395 cipher_TLS_KRB5_WITH_RC4_128_MD5,
396 cipher_TLS_KRB5_WITH_IDEA_CBC_MD5,
397 cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,
398 cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA,
399 cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA,
400 cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5,
401 cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5,
402 cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5,
403 cipher_TLS_PSK_WITH_NULL_SHA,
404 cipher_TLS_DHE_PSK_WITH_NULL_SHA,
405 cipher_TLS_RSA_PSK_WITH_NULL_SHA,
406 cipher_TLS_RSA_WITH_AES_128_CBC_SHA,
407 cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA,
408 cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA,
409 cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
410 cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
411 cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA,
412 cipher_TLS_RSA_WITH_AES_256_CBC_SHA,
413 cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA,
414 cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA,
415 cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
416 cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
417 cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA,
418 cipher_TLS_RSA_WITH_NULL_SHA256,
419 cipher_TLS_RSA_WITH_AES_128_CBC_SHA256,
420 cipher_TLS_RSA_WITH_AES_256_CBC_SHA256,
421 cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
422 cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
423 cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
424 cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
425 cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
426 cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
427 cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
428 cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
429 cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
430 cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
431 cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
432 cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
433 cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
434 cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
435 cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256,
436 cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256,
437 cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
438 cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
439 cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
440 cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
441 cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
442 cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA,
443 cipher_TLS_PSK_WITH_RC4_128_SHA,
444 cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
445 cipher_TLS_PSK_WITH_AES_128_CBC_SHA,
446 cipher_TLS_PSK_WITH_AES_256_CBC_SHA,
447 cipher_TLS_DHE_PSK_WITH_RC4_128_SHA,
448 cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
449 cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
450 cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
451 cipher_TLS_RSA_PSK_WITH_RC4_128_SHA,
452 cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
453 cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
454 cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
455 cipher_TLS_RSA_WITH_SEED_CBC_SHA,
456 cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA,
457 cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA,
458 cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA,
459 cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA,
460 cipher_TLS_DH_anon_WITH_SEED_CBC_SHA,
461 cipher_TLS_RSA_WITH_AES_128_GCM_SHA256,
462 cipher_TLS_RSA_WITH_AES_256_GCM_SHA384,
463 cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
464 cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
465 cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256,
466 cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
467 cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256,
468 cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384,
469 cipher_TLS_PSK_WITH_AES_128_GCM_SHA256,
470 cipher_TLS_PSK_WITH_AES_256_GCM_SHA384,
471 cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
472 cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
473 cipher_TLS_PSK_WITH_AES_128_CBC_SHA256,
474 cipher_TLS_PSK_WITH_AES_256_CBC_SHA384,
475 cipher_TLS_PSK_WITH_NULL_SHA256,
476 cipher_TLS_PSK_WITH_NULL_SHA384,
477 cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
478 cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
479 cipher_TLS_DHE_PSK_WITH_NULL_SHA256,
480 cipher_TLS_DHE_PSK_WITH_NULL_SHA384,
481 cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
482 cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
483 cipher_TLS_RSA_PSK_WITH_NULL_SHA256,
484 cipher_TLS_RSA_PSK_WITH_NULL_SHA384,
485 cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
486 cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256,
487 cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
488 cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
489 cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
490 cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256,
491 cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
492 cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256,
493 cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256,
494 cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
495 cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
496 cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
497 cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
498 cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA,
499 cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
500 cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
501 cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
502 cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
503 cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
504 cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
505 cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
506 cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
507 cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
508 cipher_TLS_ECDH_RSA_WITH_NULL_SHA,
509 cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA,
510 cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
511 cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
512 cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
513 cipher_TLS_ECDHE_RSA_WITH_NULL_SHA,
514 cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
515 cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
516 cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
517 cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
518 cipher_TLS_ECDH_anon_WITH_NULL_SHA,
519 cipher_TLS_ECDH_anon_WITH_RC4_128_SHA,
520 cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
521 cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
522 cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
523 cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
524 cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
525 cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
526 cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
527 cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
528 cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
529 cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
530 cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
531 cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
532 cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
533 cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
534 cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
535 cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
536 cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
537 cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
538 cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
539 cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
540 cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
541 cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
542 cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
543 cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
544 cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
545 cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
546 cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
547 cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
548 cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
549 cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
550 cipher_TLS_ECDHE_PSK_WITH_NULL_SHA,
551 cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256,
552 cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384,
553 cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
554 cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
555 cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256,
556 cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384,
557 cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256,
558 cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384,
559 cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256,
560 cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384,
561 cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
562 cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
563 cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256,
564 cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384,
565 cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
566 cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
567 cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
568 cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
569 cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
570 cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
571 cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
572 cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
573 cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
574 cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
575 cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256,
576 cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384,
577 cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256,
578 cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384,
579 cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256,
580 cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384,
581 cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
582 cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
583 cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
584 cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
585 cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
586 cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
587 cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
588 cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
589 cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
590 cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
591 cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
592 cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
593 cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
594 cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
595 cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
596 cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
597 cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
598 cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
599 cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
600 cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
601 cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
602 cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
603 cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
604 cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
605 cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
606 cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
607 cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
608 cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
609 cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256,
610 cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384,
611 cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256,
612 cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384,
613 cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
614 cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
615 cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
616 cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
617 cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
618 cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
619 cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
620 cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
621 cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
622 cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
623 cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
624 cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
625 cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
626 cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
627 cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
628 cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
629 cipher_TLS_RSA_WITH_AES_128_CCM,
630 cipher_TLS_RSA_WITH_AES_256_CCM,
631 cipher_TLS_RSA_WITH_AES_128_CCM_8,
632 cipher_TLS_RSA_WITH_AES_256_CCM_8,
633 cipher_TLS_PSK_WITH_AES_128_CCM,
634 cipher_TLS_PSK_WITH_AES_256_CCM,
635 cipher_TLS_PSK_WITH_AES_128_CCM_8,
636 cipher_TLS_PSK_WITH_AES_256_CCM_8:
637 return true
638 default:
639 return false
640 }
641}
diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go
new file mode 100644
index 0000000..bdf5652
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/client_conn_pool.go
@@ -0,0 +1,256 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Transport code's client connection pooling.
6
7package http2
8
9import (
10 "crypto/tls"
11 "net/http"
12 "sync"
13)
14
15// ClientConnPool manages a pool of HTTP/2 client connections.
16type ClientConnPool interface {
17 GetClientConn(req *http.Request, addr string) (*ClientConn, error)
18 MarkDead(*ClientConn)
19}
20
21// clientConnPoolIdleCloser is the interface implemented by ClientConnPool
22// implementations which can close their idle connections.
23type clientConnPoolIdleCloser interface {
24 ClientConnPool
25 closeIdleConnections()
26}
27
28var (
29 _ clientConnPoolIdleCloser = (*clientConnPool)(nil)
30 _ clientConnPoolIdleCloser = noDialClientConnPool{}
31)
32
33// TODO: use singleflight for dialing and addConnCalls?
34type clientConnPool struct {
35 t *Transport
36
37 mu sync.Mutex // TODO: maybe switch to RWMutex
38 // TODO: add support for sharing conns based on cert names
39 // (e.g. share conn for googleapis.com and appspot.com)
40 conns map[string][]*ClientConn // key is host:port
41 dialing map[string]*dialCall // currently in-flight dials
42 keys map[*ClientConn][]string
43 addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls
44}
45
46func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
47 return p.getClientConn(req, addr, dialOnMiss)
48}
49
50const (
51 dialOnMiss = true
52 noDialOnMiss = false
53)
54
55func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
56 if isConnectionCloseRequest(req) && dialOnMiss {
57 // It gets its own connection.
58 const singleUse = true
59 cc, err := p.t.dialClientConn(addr, singleUse)
60 if err != nil {
61 return nil, err
62 }
63 return cc, nil
64 }
65 p.mu.Lock()
66 for _, cc := range p.conns[addr] {
67 if cc.CanTakeNewRequest() {
68 p.mu.Unlock()
69 return cc, nil
70 }
71 }
72 if !dialOnMiss {
73 p.mu.Unlock()
74 return nil, ErrNoCachedConn
75 }
76 call := p.getStartDialLocked(addr)
77 p.mu.Unlock()
78 <-call.done
79 return call.res, call.err
80}
81
82// dialCall is an in-flight Transport dial call to a host.
83type dialCall struct {
84 p *clientConnPool
85 done chan struct{} // closed when done
86 res *ClientConn // valid after done is closed
87 err error // valid after done is closed
88}
89
90// requires p.mu is held.
91func (p *clientConnPool) getStartDialLocked(addr string) *dialCall {
92 if call, ok := p.dialing[addr]; ok {
93 // A dial is already in-flight. Don't start another.
94 return call
95 }
96 call := &dialCall{p: p, done: make(chan struct{})}
97 if p.dialing == nil {
98 p.dialing = make(map[string]*dialCall)
99 }
100 p.dialing[addr] = call
101 go call.dial(addr)
102 return call
103}
104
105// run in its own goroutine.
106func (c *dialCall) dial(addr string) {
107 const singleUse = false // shared conn
108 c.res, c.err = c.p.t.dialClientConn(addr, singleUse)
109 close(c.done)
110
111 c.p.mu.Lock()
112 delete(c.p.dialing, addr)
113 if c.err == nil {
114 c.p.addConnLocked(addr, c.res)
115 }
116 c.p.mu.Unlock()
117}
118
119// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
120// already exist. It coalesces concurrent calls with the same key.
121// This is used by the http1 Transport code when it creates a new connection. Because
122// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know
123// the protocol), it can get into a situation where it has multiple TLS connections.
124// This code decides which ones live or die.
125// The return value used is whether c was used.
126// c is never closed.
127func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c *tls.Conn) (used bool, err error) {
128 p.mu.Lock()
129 for _, cc := range p.conns[key] {
130 if cc.CanTakeNewRequest() {
131 p.mu.Unlock()
132 return false, nil
133 }
134 }
135 call, dup := p.addConnCalls[key]
136 if !dup {
137 if p.addConnCalls == nil {
138 p.addConnCalls = make(map[string]*addConnCall)
139 }
140 call = &addConnCall{
141 p: p,
142 done: make(chan struct{}),
143 }
144 p.addConnCalls[key] = call
145 go call.run(t, key, c)
146 }
147 p.mu.Unlock()
148
149 <-call.done
150 if call.err != nil {
151 return false, call.err
152 }
153 return !dup, nil
154}
155
156type addConnCall struct {
157 p *clientConnPool
158 done chan struct{} // closed when done
159 err error
160}
161
162func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
163 cc, err := t.NewClientConn(tc)
164
165 p := c.p
166 p.mu.Lock()
167 if err != nil {
168 c.err = err
169 } else {
170 p.addConnLocked(key, cc)
171 }
172 delete(p.addConnCalls, key)
173 p.mu.Unlock()
174 close(c.done)
175}
176
177func (p *clientConnPool) addConn(key string, cc *ClientConn) {
178 p.mu.Lock()
179 p.addConnLocked(key, cc)
180 p.mu.Unlock()
181}
182
183// p.mu must be held
184func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {
185 for _, v := range p.conns[key] {
186 if v == cc {
187 return
188 }
189 }
190 if p.conns == nil {
191 p.conns = make(map[string][]*ClientConn)
192 }
193 if p.keys == nil {
194 p.keys = make(map[*ClientConn][]string)
195 }
196 p.conns[key] = append(p.conns[key], cc)
197 p.keys[cc] = append(p.keys[cc], key)
198}
199
200func (p *clientConnPool) MarkDead(cc *ClientConn) {
201 p.mu.Lock()
202 defer p.mu.Unlock()
203 for _, key := range p.keys[cc] {
204 vv, ok := p.conns[key]
205 if !ok {
206 continue
207 }
208 newList := filterOutClientConn(vv, cc)
209 if len(newList) > 0 {
210 p.conns[key] = newList
211 } else {
212 delete(p.conns, key)
213 }
214 }
215 delete(p.keys, cc)
216}
217
218func (p *clientConnPool) closeIdleConnections() {
219 p.mu.Lock()
220 defer p.mu.Unlock()
221 // TODO: don't close a cc if it was just added to the pool
222 // milliseconds ago and has never been used. There's currently
223 // a small race window with the HTTP/1 Transport's integration
224 // where it can add an idle conn just before using it, and
225 // somebody else can concurrently call CloseIdleConns and
226 // break some caller's RoundTrip.
227 for _, vv := range p.conns {
228 for _, cc := range vv {
229 cc.closeIfIdle()
230 }
231 }
232}
233
234func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn {
235 out := in[:0]
236 for _, v := range in {
237 if v != exclude {
238 out = append(out, v)
239 }
240 }
241 // If we filtered it out, zero out the last item to prevent
242 // the GC from seeing it.
243 if len(in) != len(out) {
244 in[len(in)-1] = nil
245 }
246 return out
247}
248
249// noDialClientConnPool is an implementation of http2.ClientConnPool
250// which never dials. We let the HTTP/1.1 client dial and use its TLS
251// connection instead.
252type noDialClientConnPool struct{ *clientConnPool }
253
254func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
255 return p.getClientConn(req, addr, noDialOnMiss)
256}
diff --git a/vendor/golang.org/x/net/http2/configure_transport.go b/vendor/golang.org/x/net/http2/configure_transport.go
new file mode 100644
index 0000000..b65fc6d
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/configure_transport.go
@@ -0,0 +1,80 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.6
6
7package http2
8
9import (
10 "crypto/tls"
11 "fmt"
12 "net/http"
13)
14
15func configureTransport(t1 *http.Transport) (*Transport, error) {
16 connPool := new(clientConnPool)
17 t2 := &Transport{
18 ConnPool: noDialClientConnPool{connPool},
19 t1: t1,
20 }
21 connPool.t = t2
22 if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
23 return nil, err
24 }
25 if t1.TLSClientConfig == nil {
26 t1.TLSClientConfig = new(tls.Config)
27 }
28 if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
29 t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
30 }
31 if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
32 t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
33 }
34 upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper {
35 addr := authorityAddr("https", authority)
36 if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
37 go c.Close()
38 return erringRoundTripper{err}
39 } else if !used {
40 // Turns out we don't need this c.
41 // For example, two goroutines made requests to the same host
42 // at the same time, both kicking off TCP dials. (since protocol
43 // was unknown)
44 go c.Close()
45 }
46 return t2
47 }
48 if m := t1.TLSNextProto; len(m) == 0 {
49 t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{
50 "h2": upgradeFn,
51 }
52 } else {
53 m["h2"] = upgradeFn
54 }
55 return t2, nil
56}
57
58// registerHTTPSProtocol calls Transport.RegisterProtocol but
59// converting panics into errors.
60func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
61 defer func() {
62 if e := recover(); e != nil {
63 err = fmt.Errorf("%v", e)
64 }
65 }()
66 t.RegisterProtocol("https", rt)
67 return nil
68}
69
70// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
71// if there's already has a cached connection to the host.
72type noDialH2RoundTripper struct{ t *Transport }
73
74func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
75 res, err := rt.t.RoundTrip(req)
76 if err == ErrNoCachedConn {
77 return nil, http.ErrSkipAltProtocol
78 }
79 return res, err
80}
diff --git a/vendor/golang.org/x/net/http2/databuffer.go b/vendor/golang.org/x/net/http2/databuffer.go
new file mode 100644
index 0000000..a3067f8
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/databuffer.go
@@ -0,0 +1,146 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import (
8 "errors"
9 "fmt"
10 "sync"
11)
12
13// Buffer chunks are allocated from a pool to reduce pressure on GC.
14// The maximum wasted space per dataBuffer is 2x the largest size class,
15// which happens when the dataBuffer has multiple chunks and there is
16// one unread byte in both the first and last chunks. We use a few size
17// classes to minimize overheads for servers that typically receive very
18// small request bodies.
19//
20// TODO: Benchmark to determine if the pools are necessary. The GC may have
21// improved enough that we can instead allocate chunks like this:
22// make([]byte, max(16<<10, expectedBytesRemaining))
23var (
24 dataChunkSizeClasses = []int{
25 1 << 10,
26 2 << 10,
27 4 << 10,
28 8 << 10,
29 16 << 10,
30 }
31 dataChunkPools = [...]sync.Pool{
32 {New: func() interface{} { return make([]byte, 1<<10) }},
33 {New: func() interface{} { return make([]byte, 2<<10) }},
34 {New: func() interface{} { return make([]byte, 4<<10) }},
35 {New: func() interface{} { return make([]byte, 8<<10) }},
36 {New: func() interface{} { return make([]byte, 16<<10) }},
37 }
38)
39
40func getDataBufferChunk(size int64) []byte {
41 i := 0
42 for ; i < len(dataChunkSizeClasses)-1; i++ {
43 if size <= int64(dataChunkSizeClasses[i]) {
44 break
45 }
46 }
47 return dataChunkPools[i].Get().([]byte)
48}
49
50func putDataBufferChunk(p []byte) {
51 for i, n := range dataChunkSizeClasses {
52 if len(p) == n {
53 dataChunkPools[i].Put(p)
54 return
55 }
56 }
57 panic(fmt.Sprintf("unexpected buffer len=%v", len(p)))
58}
59
60// dataBuffer is an io.ReadWriter backed by a list of data chunks.
61// Each dataBuffer is used to read DATA frames on a single stream.
62// The buffer is divided into chunks so the server can limit the
63// total memory used by a single connection without limiting the
64// request body size on any single stream.
65type dataBuffer struct {
66 chunks [][]byte
67 r int // next byte to read is chunks[0][r]
68 w int // next byte to write is chunks[len(chunks)-1][w]
69 size int // total buffered bytes
70 expected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0)
71}
72
73var errReadEmpty = errors.New("read from empty dataBuffer")
74
75// Read copies bytes from the buffer into p.
76// It is an error to read when no data is available.
77func (b *dataBuffer) Read(p []byte) (int, error) {
78 if b.size == 0 {
79 return 0, errReadEmpty
80 }
81 var ntotal int
82 for len(p) > 0 && b.size > 0 {
83 readFrom := b.bytesFromFirstChunk()
84 n := copy(p, readFrom)
85 p = p[n:]
86 ntotal += n
87 b.r += n
88 b.size -= n
89 // If the first chunk has been consumed, advance to the next chunk.
90 if b.r == len(b.chunks[0]) {
91 putDataBufferChunk(b.chunks[0])
92 end := len(b.chunks) - 1
93 copy(b.chunks[:end], b.chunks[1:])
94 b.chunks[end] = nil
95 b.chunks = b.chunks[:end]
96 b.r = 0
97 }
98 }
99 return ntotal, nil
100}
101
102func (b *dataBuffer) bytesFromFirstChunk() []byte {
103 if len(b.chunks) == 1 {
104 return b.chunks[0][b.r:b.w]
105 }
106 return b.chunks[0][b.r:]
107}
108
109// Len returns the number of bytes of the unread portion of the buffer.
110func (b *dataBuffer) Len() int {
111 return b.size
112}
113
114// Write appends p to the buffer.
115func (b *dataBuffer) Write(p []byte) (int, error) {
116 ntotal := len(p)
117 for len(p) > 0 {
118 // If the last chunk is empty, allocate a new chunk. Try to allocate
119 // enough to fully copy p plus any additional bytes we expect to
120 // receive. However, this may allocate less than len(p).
121 want := int64(len(p))
122 if b.expected > want {
123 want = b.expected
124 }
125 chunk := b.lastChunkOrAlloc(want)
126 n := copy(chunk[b.w:], p)
127 p = p[n:]
128 b.w += n
129 b.size += n
130 b.expected -= int64(n)
131 }
132 return ntotal, nil
133}
134
135func (b *dataBuffer) lastChunkOrAlloc(want int64) []byte {
136 if len(b.chunks) != 0 {
137 last := b.chunks[len(b.chunks)-1]
138 if b.w < len(last) {
139 return last
140 }
141 }
142 chunk := getDataBufferChunk(want)
143 b.chunks = append(b.chunks, chunk)
144 b.w = 0
145 return chunk
146}
diff --git a/vendor/golang.org/x/net/http2/errors.go b/vendor/golang.org/x/net/http2/errors.go
new file mode 100644
index 0000000..71f2c46
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/errors.go
@@ -0,0 +1,133 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import (
8 "errors"
9 "fmt"
10)
11
12// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
13type ErrCode uint32
14
15const (
16 ErrCodeNo ErrCode = 0x0
17 ErrCodeProtocol ErrCode = 0x1
18 ErrCodeInternal ErrCode = 0x2
19 ErrCodeFlowControl ErrCode = 0x3
20 ErrCodeSettingsTimeout ErrCode = 0x4
21 ErrCodeStreamClosed ErrCode = 0x5
22 ErrCodeFrameSize ErrCode = 0x6
23 ErrCodeRefusedStream ErrCode = 0x7
24 ErrCodeCancel ErrCode = 0x8
25 ErrCodeCompression ErrCode = 0x9
26 ErrCodeConnect ErrCode = 0xa
27 ErrCodeEnhanceYourCalm ErrCode = 0xb
28 ErrCodeInadequateSecurity ErrCode = 0xc
29 ErrCodeHTTP11Required ErrCode = 0xd
30)
31
32var errCodeName = map[ErrCode]string{
33 ErrCodeNo: "NO_ERROR",
34 ErrCodeProtocol: "PROTOCOL_ERROR",
35 ErrCodeInternal: "INTERNAL_ERROR",
36 ErrCodeFlowControl: "FLOW_CONTROL_ERROR",
37 ErrCodeSettingsTimeout: "SETTINGS_TIMEOUT",
38 ErrCodeStreamClosed: "STREAM_CLOSED",
39 ErrCodeFrameSize: "FRAME_SIZE_ERROR",
40 ErrCodeRefusedStream: "REFUSED_STREAM",
41 ErrCodeCancel: "CANCEL",
42 ErrCodeCompression: "COMPRESSION_ERROR",
43 ErrCodeConnect: "CONNECT_ERROR",
44 ErrCodeEnhanceYourCalm: "ENHANCE_YOUR_CALM",
45 ErrCodeInadequateSecurity: "INADEQUATE_SECURITY",
46 ErrCodeHTTP11Required: "HTTP_1_1_REQUIRED",
47}
48
49func (e ErrCode) String() string {
50 if s, ok := errCodeName[e]; ok {
51 return s
52 }
53 return fmt.Sprintf("unknown error code 0x%x", uint32(e))
54}
55
56// ConnectionError is an error that results in the termination of the
57// entire connection.
58type ConnectionError ErrCode
59
60func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: %s", ErrCode(e)) }
61
62// StreamError is an error that only affects one stream within an
63// HTTP/2 connection.
64type StreamError struct {
65 StreamID uint32
66 Code ErrCode
67 Cause error // optional additional detail
68}
69
70func streamError(id uint32, code ErrCode) StreamError {
71 return StreamError{StreamID: id, Code: code}
72}
73
74func (e StreamError) Error() string {
75 if e.Cause != nil {
76 return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause)
77 }
78 return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
79}
80
81// 6.9.1 The Flow Control Window
82// "If a sender receives a WINDOW_UPDATE that causes a flow control
83// window to exceed this maximum it MUST terminate either the stream
84// or the connection, as appropriate. For streams, [...]; for the
85// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code."
86type goAwayFlowError struct{}
87
88func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
89
90// connError represents an HTTP/2 ConnectionError error code, along
91// with a string (for debugging) explaining why.
92//
93// Errors of this type are only returned by the frame parser functions
94// and converted into ConnectionError(Code), after stashing away
95// the Reason into the Framer's errDetail field, accessible via
96// the (*Framer).ErrorDetail method.
97type connError struct {
98 Code ErrCode // the ConnectionError error code
99 Reason string // additional reason
100}
101
102func (e connError) Error() string {
103 return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
104}
105
106type pseudoHeaderError string
107
108func (e pseudoHeaderError) Error() string {
109 return fmt.Sprintf("invalid pseudo-header %q", string(e))
110}
111
112type duplicatePseudoHeaderError string
113
114func (e duplicatePseudoHeaderError) Error() string {
115 return fmt.Sprintf("duplicate pseudo-header %q", string(e))
116}
117
118type headerFieldNameError string
119
120func (e headerFieldNameError) Error() string {
121 return fmt.Sprintf("invalid header field name %q", string(e))
122}
123
124type headerFieldValueError string
125
126func (e headerFieldValueError) Error() string {
127 return fmt.Sprintf("invalid header field value %q", string(e))
128}
129
130var (
131 errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
132 errPseudoAfterRegular = errors.New("pseudo header field after regular")
133)
diff --git a/vendor/golang.org/x/net/http2/flow.go b/vendor/golang.org/x/net/http2/flow.go
new file mode 100644
index 0000000..957de25
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/flow.go
@@ -0,0 +1,50 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Flow control
6
7package http2
8
9// flow is the flow control window's size.
10type flow struct {
11 // n is the number of DATA bytes we're allowed to send.
12 // A flow is kept both on a conn and a per-stream.
13 n int32
14
15 // conn points to the shared connection-level flow that is
16 // shared by all streams on that conn. It is nil for the flow
17 // that's on the conn directly.
18 conn *flow
19}
20
21func (f *flow) setConnFlow(cf *flow) { f.conn = cf }
22
23func (f *flow) available() int32 {
24 n := f.n
25 if f.conn != nil && f.conn.n < n {
26 n = f.conn.n
27 }
28 return n
29}
30
31func (f *flow) take(n int32) {
32 if n > f.available() {
33 panic("internal error: took too much")
34 }
35 f.n -= n
36 if f.conn != nil {
37 f.conn.n -= n
38 }
39}
40
41// add adds n bytes (positive or negative) to the flow control window.
42// It returns false if the sum would exceed 2^31-1.
43func (f *flow) add(n int32) bool {
44 remain := (1<<31 - 1) - f.n
45 if n > remain {
46 return false
47 }
48 f.n += n
49 return true
50}
diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go
new file mode 100644
index 0000000..3b14890
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/frame.go
@@ -0,0 +1,1579 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import (
8 "bytes"
9 "encoding/binary"
10 "errors"
11 "fmt"
12 "io"
13 "log"
14 "strings"
15 "sync"
16
17 "golang.org/x/net/http2/hpack"
18 "golang.org/x/net/lex/httplex"
19)
20
21const frameHeaderLen = 9
22
23var padZeros = make([]byte, 255) // zeros for padding
24
25// A FrameType is a registered frame type as defined in
26// http://http2.github.io/http2-spec/#rfc.section.11.2
27type FrameType uint8
28
29const (
30 FrameData FrameType = 0x0
31 FrameHeaders FrameType = 0x1
32 FramePriority FrameType = 0x2
33 FrameRSTStream FrameType = 0x3
34 FrameSettings FrameType = 0x4
35 FramePushPromise FrameType = 0x5
36 FramePing FrameType = 0x6
37 FrameGoAway FrameType = 0x7
38 FrameWindowUpdate FrameType = 0x8
39 FrameContinuation FrameType = 0x9
40)
41
42var frameName = map[FrameType]string{
43 FrameData: "DATA",
44 FrameHeaders: "HEADERS",
45 FramePriority: "PRIORITY",
46 FrameRSTStream: "RST_STREAM",
47 FrameSettings: "SETTINGS",
48 FramePushPromise: "PUSH_PROMISE",
49 FramePing: "PING",
50 FrameGoAway: "GOAWAY",
51 FrameWindowUpdate: "WINDOW_UPDATE",
52 FrameContinuation: "CONTINUATION",
53}
54
55func (t FrameType) String() string {
56 if s, ok := frameName[t]; ok {
57 return s
58 }
59 return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
60}
61
62// Flags is a bitmask of HTTP/2 flags.
63// The meaning of flags varies depending on the frame type.
64type Flags uint8
65
66// Has reports whether f contains all (0 or more) flags in v.
67func (f Flags) Has(v Flags) bool {
68 return (f & v) == v
69}
70
71// Frame-specific FrameHeader flag bits.
72const (
73 // Data Frame
74 FlagDataEndStream Flags = 0x1
75 FlagDataPadded Flags = 0x8
76
77 // Headers Frame
78 FlagHeadersEndStream Flags = 0x1
79 FlagHeadersEndHeaders Flags = 0x4
80 FlagHeadersPadded Flags = 0x8
81 FlagHeadersPriority Flags = 0x20
82
83 // Settings Frame
84 FlagSettingsAck Flags = 0x1
85
86 // Ping Frame
87 FlagPingAck Flags = 0x1
88
89 // Continuation Frame
90 FlagContinuationEndHeaders Flags = 0x4
91
92 FlagPushPromiseEndHeaders Flags = 0x4
93 FlagPushPromisePadded Flags = 0x8
94)
95
96var flagName = map[FrameType]map[Flags]string{
97 FrameData: {
98 FlagDataEndStream: "END_STREAM",
99 FlagDataPadded: "PADDED",
100 },
101 FrameHeaders: {
102 FlagHeadersEndStream: "END_STREAM",
103 FlagHeadersEndHeaders: "END_HEADERS",
104 FlagHeadersPadded: "PADDED",
105 FlagHeadersPriority: "PRIORITY",
106 },
107 FrameSettings: {
108 FlagSettingsAck: "ACK",
109 },
110 FramePing: {
111 FlagPingAck: "ACK",
112 },
113 FrameContinuation: {
114 FlagContinuationEndHeaders: "END_HEADERS",
115 },
116 FramePushPromise: {
117 FlagPushPromiseEndHeaders: "END_HEADERS",
118 FlagPushPromisePadded: "PADDED",
119 },
120}
121
122// a frameParser parses a frame given its FrameHeader and payload
123// bytes. The length of payload will always equal fh.Length (which
124// might be 0).
125type frameParser func(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error)
126
127var frameParsers = map[FrameType]frameParser{
128 FrameData: parseDataFrame,
129 FrameHeaders: parseHeadersFrame,
130 FramePriority: parsePriorityFrame,
131 FrameRSTStream: parseRSTStreamFrame,
132 FrameSettings: parseSettingsFrame,
133 FramePushPromise: parsePushPromise,
134 FramePing: parsePingFrame,
135 FrameGoAway: parseGoAwayFrame,
136 FrameWindowUpdate: parseWindowUpdateFrame,
137 FrameContinuation: parseContinuationFrame,
138}
139
140func typeFrameParser(t FrameType) frameParser {
141 if f := frameParsers[t]; f != nil {
142 return f
143 }
144 return parseUnknownFrame
145}
146
147// A FrameHeader is the 9 byte header of all HTTP/2 frames.
148//
149// See http://http2.github.io/http2-spec/#FrameHeader
150type FrameHeader struct {
151 valid bool // caller can access []byte fields in the Frame
152
153 // Type is the 1 byte frame type. There are ten standard frame
154 // types, but extension frame types may be written by WriteRawFrame
155 // and will be returned by ReadFrame (as UnknownFrame).
156 Type FrameType
157
158 // Flags are the 1 byte of 8 potential bit flags per frame.
159 // They are specific to the frame type.
160 Flags Flags
161
162 // Length is the length of the frame, not including the 9 byte header.
163 // The maximum size is one byte less than 16MB (uint24), but only
164 // frames up to 16KB are allowed without peer agreement.
165 Length uint32
166
167 // StreamID is which stream this frame is for. Certain frames
168 // are not stream-specific, in which case this field is 0.
169 StreamID uint32
170}
171
172// Header returns h. It exists so FrameHeaders can be embedded in other
173// specific frame types and implement the Frame interface.
174func (h FrameHeader) Header() FrameHeader { return h }
175
176func (h FrameHeader) String() string {
177 var buf bytes.Buffer
178 buf.WriteString("[FrameHeader ")
179 h.writeDebug(&buf)
180 buf.WriteByte(']')
181 return buf.String()
182}
183
184func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
185 buf.WriteString(h.Type.String())
186 if h.Flags != 0 {
187 buf.WriteString(" flags=")
188 set := 0
189 for i := uint8(0); i < 8; i++ {
190 if h.Flags&(1<<i) == 0 {
191 continue
192 }
193 set++
194 if set > 1 {
195 buf.WriteByte('|')
196 }
197 name := flagName[h.Type][Flags(1<<i)]
198 if name != "" {
199 buf.WriteString(name)
200 } else {
201 fmt.Fprintf(buf, "0x%x", 1<<i)
202 }
203 }
204 }
205 if h.StreamID != 0 {
206 fmt.Fprintf(buf, " stream=%d", h.StreamID)
207 }
208 fmt.Fprintf(buf, " len=%d", h.Length)
209}
210
211func (h *FrameHeader) checkValid() {
212 if !h.valid {
213 panic("Frame accessor called on non-owned Frame")
214 }
215}
216
217func (h *FrameHeader) invalidate() { h.valid = false }
218
219// frame header bytes.
220// Used only by ReadFrameHeader.
221var fhBytes = sync.Pool{
222 New: func() interface{} {
223 buf := make([]byte, frameHeaderLen)
224 return &buf
225 },
226}
227
228// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
229// Most users should use Framer.ReadFrame instead.
230func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
231 bufp := fhBytes.Get().(*[]byte)
232 defer fhBytes.Put(bufp)
233 return readFrameHeader(*bufp, r)
234}
235
236func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {
237 _, err := io.ReadFull(r, buf[:frameHeaderLen])
238 if err != nil {
239 return FrameHeader{}, err
240 }
241 return FrameHeader{
242 Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
243 Type: FrameType(buf[3]),
244 Flags: Flags(buf[4]),
245 StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
246 valid: true,
247 }, nil
248}
249
250// A Frame is the base interface implemented by all frame types.
251// Callers will generally type-assert the specific frame type:
252// *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
253//
254// Frames are only valid until the next call to Framer.ReadFrame.
255type Frame interface {
256 Header() FrameHeader
257
258 // invalidate is called by Framer.ReadFrame to make this
259 // frame's buffers as being invalid, since the subsequent
260 // frame will reuse them.
261 invalidate()
262}
263
264// A Framer reads and writes Frames.
265type Framer struct {
266 r io.Reader
267 lastFrame Frame
268 errDetail error
269
270 // lastHeaderStream is non-zero if the last frame was an
271 // unfinished HEADERS/CONTINUATION.
272 lastHeaderStream uint32
273
274 maxReadSize uint32
275 headerBuf [frameHeaderLen]byte
276
277 // TODO: let getReadBuf be configurable, and use a less memory-pinning
278 // allocator in server.go to minimize memory pinned for many idle conns.
279 // Will probably also need to make frame invalidation have a hook too.
280 getReadBuf func(size uint32) []byte
281 readBuf []byte // cache for default getReadBuf
282
283 maxWriteSize uint32 // zero means unlimited; TODO: implement
284
285 w io.Writer
286 wbuf []byte
287
288 // AllowIllegalWrites permits the Framer's Write methods to
289 // write frames that do not conform to the HTTP/2 spec. This
290 // permits using the Framer to test other HTTP/2
291 // implementations' conformance to the spec.
292 // If false, the Write methods will prefer to return an error
293 // rather than comply.
294 AllowIllegalWrites bool
295
296 // AllowIllegalReads permits the Framer's ReadFrame method
297 // to return non-compliant frames or frame orders.
298 // This is for testing and permits using the Framer to test
299 // other HTTP/2 implementations' conformance to the spec.
300 // It is not compatible with ReadMetaHeaders.
301 AllowIllegalReads bool
302
303 // ReadMetaHeaders if non-nil causes ReadFrame to merge
304 // HEADERS and CONTINUATION frames together and return
305 // MetaHeadersFrame instead.
306 ReadMetaHeaders *hpack.Decoder
307
308 // MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
309 // It's used only if ReadMetaHeaders is set; 0 means a sane default
310 // (currently 16MB)
311 // If the limit is hit, MetaHeadersFrame.Truncated is set true.
312 MaxHeaderListSize uint32
313
314 // TODO: track which type of frame & with which flags was sent
315 // last. Then return an error (unless AllowIllegalWrites) if
316 // we're in the middle of a header block and a
317 // non-Continuation or Continuation on a different stream is
318 // attempted to be written.
319
320 logReads, logWrites bool
321
322 debugFramer *Framer // only use for logging written writes
323 debugFramerBuf *bytes.Buffer
324 debugReadLoggerf func(string, ...interface{})
325 debugWriteLoggerf func(string, ...interface{})
326
327 frameCache *frameCache // nil if frames aren't reused (default)
328}
329
330func (fr *Framer) maxHeaderListSize() uint32 {
331 if fr.MaxHeaderListSize == 0 {
332 return 16 << 20 // sane default, per docs
333 }
334 return fr.MaxHeaderListSize
335}
336
337func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
338 // Write the FrameHeader.
339 f.wbuf = append(f.wbuf[:0],
340 0, // 3 bytes of length, filled in in endWrite
341 0,
342 0,
343 byte(ftype),
344 byte(flags),
345 byte(streamID>>24),
346 byte(streamID>>16),
347 byte(streamID>>8),
348 byte(streamID))
349}
350
351func (f *Framer) endWrite() error {
352 // Now that we know the final size, fill in the FrameHeader in
353 // the space previously reserved for it. Abuse append.
354 length := len(f.wbuf) - frameHeaderLen
355 if length >= (1 << 24) {
356 return ErrFrameTooLarge
357 }
358 _ = append(f.wbuf[:0],
359 byte(length>>16),
360 byte(length>>8),
361 byte(length))
362 if f.logWrites {
363 f.logWrite()
364 }
365
366 n, err := f.w.Write(f.wbuf)
367 if err == nil && n != len(f.wbuf) {
368 err = io.ErrShortWrite
369 }
370 return err
371}
372
373func (f *Framer) logWrite() {
374 if f.debugFramer == nil {
375 f.debugFramerBuf = new(bytes.Buffer)
376 f.debugFramer = NewFramer(nil, f.debugFramerBuf)
377 f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
378 // Let us read anything, even if we accidentally wrote it
379 // in the wrong order:
380 f.debugFramer.AllowIllegalReads = true
381 }
382 f.debugFramerBuf.Write(f.wbuf)
383 fr, err := f.debugFramer.ReadFrame()
384 if err != nil {
385 f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f)
386 return
387 }
388 f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
389}
390
391func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) }
392func (f *Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) }
393func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
394func (f *Framer) writeUint32(v uint32) {
395 f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
396}
397
398const (
399 minMaxFrameSize = 1 << 14
400 maxFrameSize = 1<<24 - 1
401)
402
403// SetReuseFrames allows the Framer to reuse Frames.
404// If called on a Framer, Frames returned by calls to ReadFrame are only
405// valid until the next call to ReadFrame.
406func (fr *Framer) SetReuseFrames() {
407 if fr.frameCache != nil {
408 return
409 }
410 fr.frameCache = &frameCache{}
411}
412
413type frameCache struct {
414 dataFrame DataFrame
415}
416
417func (fc *frameCache) getDataFrame() *DataFrame {
418 if fc == nil {
419 return &DataFrame{}
420 }
421 return &fc.dataFrame
422}
423
424// NewFramer returns a Framer that writes frames to w and reads them from r.
425func NewFramer(w io.Writer, r io.Reader) *Framer {
426 fr := &Framer{
427 w: w,
428 r: r,
429 logReads: logFrameReads,
430 logWrites: logFrameWrites,
431 debugReadLoggerf: log.Printf,
432 debugWriteLoggerf: log.Printf,
433 }
434 fr.getReadBuf = func(size uint32) []byte {
435 if cap(fr.readBuf) >= int(size) {
436 return fr.readBuf[:size]
437 }
438 fr.readBuf = make([]byte, size)
439 return fr.readBuf
440 }
441 fr.SetMaxReadFrameSize(maxFrameSize)
442 return fr
443}
444
445// SetMaxReadFrameSize sets the maximum size of a frame
446// that will be read by a subsequent call to ReadFrame.
447// It is the caller's responsibility to advertise this
448// limit with a SETTINGS frame.
449func (fr *Framer) SetMaxReadFrameSize(v uint32) {
450 if v > maxFrameSize {
451 v = maxFrameSize
452 }
453 fr.maxReadSize = v
454}
455
456// ErrorDetail returns a more detailed error of the last error
457// returned by Framer.ReadFrame. For instance, if ReadFrame
458// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
459// will say exactly what was invalid. ErrorDetail is not guaranteed
460// to return a non-nil value and like the rest of the http2 package,
461// its return value is not protected by an API compatibility promise.
462// ErrorDetail is reset after the next call to ReadFrame.
463func (fr *Framer) ErrorDetail() error {
464 return fr.errDetail
465}
466
467// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
468// sends a frame that is larger than declared with SetMaxReadFrameSize.
469var ErrFrameTooLarge = errors.New("http2: frame too large")
470
471// terminalReadFrameError reports whether err is an unrecoverable
472// error from ReadFrame and no other frames should be read.
473func terminalReadFrameError(err error) bool {
474 if _, ok := err.(StreamError); ok {
475 return false
476 }
477 return err != nil
478}
479
480// ReadFrame reads a single frame. The returned Frame is only valid
481// until the next call to ReadFrame.
482//
483// If the frame is larger than previously set with SetMaxReadFrameSize, the
484// returned error is ErrFrameTooLarge. Other errors may be of type
485// ConnectionError, StreamError, or anything else from the underlying
486// reader.
487func (fr *Framer) ReadFrame() (Frame, error) {
488 fr.errDetail = nil
489 if fr.lastFrame != nil {
490 fr.lastFrame.invalidate()
491 }
492 fh, err := readFrameHeader(fr.headerBuf[:], fr.r)
493 if err != nil {
494 return nil, err
495 }
496 if fh.Length > fr.maxReadSize {
497 return nil, ErrFrameTooLarge
498 }
499 payload := fr.getReadBuf(fh.Length)
500 if _, err := io.ReadFull(fr.r, payload); err != nil {
501 return nil, err
502 }
503 f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, payload)
504 if err != nil {
505 if ce, ok := err.(connError); ok {
506 return nil, fr.connError(ce.Code, ce.Reason)
507 }
508 return nil, err
509 }
510 if err := fr.checkFrameOrder(f); err != nil {
511 return nil, err
512 }
513 if fr.logReads {
514 fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f))
515 }
516 if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {
517 return fr.readMetaFrame(f.(*HeadersFrame))
518 }
519 return f, nil
520}
521
522// connError returns ConnectionError(code) but first
523// stashes away a public reason to the caller can optionally relay it
524// to the peer before hanging up on them. This might help others debug
525// their implementations.
526func (fr *Framer) connError(code ErrCode, reason string) error {
527 fr.errDetail = errors.New(reason)
528 return ConnectionError(code)
529}
530
531// checkFrameOrder reports an error if f is an invalid frame to return
532// next from ReadFrame. Mostly it checks whether HEADERS and
533// CONTINUATION frames are contiguous.
534func (fr *Framer) checkFrameOrder(f Frame) error {
535 last := fr.lastFrame
536 fr.lastFrame = f
537 if fr.AllowIllegalReads {
538 return nil
539 }
540
541 fh := f.Header()
542 if fr.lastHeaderStream != 0 {
543 if fh.Type != FrameContinuation {
544 return fr.connError(ErrCodeProtocol,
545 fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
546 fh.Type, fh.StreamID,
547 last.Header().Type, fr.lastHeaderStream))
548 }
549 if fh.StreamID != fr.lastHeaderStream {
550 return fr.connError(ErrCodeProtocol,
551 fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
552 fh.StreamID, fr.lastHeaderStream))
553 }
554 } else if fh.Type == FrameContinuation {
555 return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
556 }
557
558 switch fh.Type {
559 case FrameHeaders, FrameContinuation:
560 if fh.Flags.Has(FlagHeadersEndHeaders) {
561 fr.lastHeaderStream = 0
562 } else {
563 fr.lastHeaderStream = fh.StreamID
564 }
565 }
566
567 return nil
568}
569
570// A DataFrame conveys arbitrary, variable-length sequences of octets
571// associated with a stream.
572// See http://http2.github.io/http2-spec/#rfc.section.6.1
573type DataFrame struct {
574 FrameHeader
575 data []byte
576}
577
578func (f *DataFrame) StreamEnded() bool {
579 return f.FrameHeader.Flags.Has(FlagDataEndStream)
580}
581
582// Data returns the frame's data octets, not including any padding
583// size byte or padding suffix bytes.
584// The caller must not retain the returned memory past the next
585// call to ReadFrame.
586func (f *DataFrame) Data() []byte {
587 f.checkValid()
588 return f.data
589}
590
591func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
592 if fh.StreamID == 0 {
593 // DATA frames MUST be associated with a stream. If a
594 // DATA frame is received whose stream identifier
595 // field is 0x0, the recipient MUST respond with a
596 // connection error (Section 5.4.1) of type
597 // PROTOCOL_ERROR.
598 return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
599 }
600 f := fc.getDataFrame()
601 f.FrameHeader = fh
602
603 var padSize byte
604 if fh.Flags.Has(FlagDataPadded) {
605 var err error
606 payload, padSize, err = readByte(payload)
607 if err != nil {
608 return nil, err
609 }
610 }
611 if int(padSize) > len(payload) {
612 // If the length of the padding is greater than the
613 // length of the frame payload, the recipient MUST
614 // treat this as a connection error.
615 // Filed: https://github.com/http2/http2-spec/issues/610
616 return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
617 }
618 f.data = payload[:len(payload)-int(padSize)]
619 return f, nil
620}
621
622var (
623 errStreamID = errors.New("invalid stream ID")
624 errDepStreamID = errors.New("invalid dependent stream ID")
625 errPadLength = errors.New("pad length too large")
626 errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled")
627)
628
629func validStreamIDOrZero(streamID uint32) bool {
630 return streamID&(1<<31) == 0
631}
632
633func validStreamID(streamID uint32) bool {
634 return streamID != 0 && streamID&(1<<31) == 0
635}
636
637// WriteData writes a DATA frame.
638//
639// It will perform exactly one Write to the underlying Writer.
640// It is the caller's responsibility not to violate the maximum frame size
641// and to not call other Write methods concurrently.
642func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
643 return f.WriteDataPadded(streamID, endStream, data, nil)
644}
645
646// WriteData writes a DATA frame with optional padding.
647//
648// If pad is nil, the padding bit is not sent.
649// The length of pad must not exceed 255 bytes.
650// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.
651//
652// It will perform exactly one Write to the underlying Writer.
653// It is the caller's responsibility not to violate the maximum frame size
654// and to not call other Write methods concurrently.
655func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
656 if !validStreamID(streamID) && !f.AllowIllegalWrites {
657 return errStreamID
658 }
659 if len(pad) > 0 {
660 if len(pad) > 255 {
661 return errPadLength
662 }
663 if !f.AllowIllegalWrites {
664 for _, b := range pad {
665 if b != 0 {
666 // "Padding octets MUST be set to zero when sending."
667 return errPadBytes
668 }
669 }
670 }
671 }
672 var flags Flags
673 if endStream {
674 flags |= FlagDataEndStream
675 }
676 if pad != nil {
677 flags |= FlagDataPadded
678 }
679 f.startWrite(FrameData, flags, streamID)
680 if pad != nil {
681 f.wbuf = append(f.wbuf, byte(len(pad)))
682 }
683 f.wbuf = append(f.wbuf, data...)
684 f.wbuf = append(f.wbuf, pad...)
685 return f.endWrite()
686}
687
688// A SettingsFrame conveys configuration parameters that affect how
689// endpoints communicate, such as preferences and constraints on peer
690// behavior.
691//
692// See http://http2.github.io/http2-spec/#SETTINGS
693type SettingsFrame struct {
694 FrameHeader
695 p []byte
696}
697
698func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
699 if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
700 // When this (ACK 0x1) bit is set, the payload of the
701 // SETTINGS frame MUST be empty. Receipt of a
702 // SETTINGS frame with the ACK flag set and a length
703 // field value other than 0 MUST be treated as a
704 // connection error (Section 5.4.1) of type
705 // FRAME_SIZE_ERROR.
706 return nil, ConnectionError(ErrCodeFrameSize)
707 }
708 if fh.StreamID != 0 {
709 // SETTINGS frames always apply to a connection,
710 // never a single stream. The stream identifier for a
711 // SETTINGS frame MUST be zero (0x0). If an endpoint
712 // receives a SETTINGS frame whose stream identifier
713 // field is anything other than 0x0, the endpoint MUST
714 // respond with a connection error (Section 5.4.1) of
715 // type PROTOCOL_ERROR.
716 return nil, ConnectionError(ErrCodeProtocol)
717 }
718 if len(p)%6 != 0 {
719 // Expecting even number of 6 byte settings.
720 return nil, ConnectionError(ErrCodeFrameSize)
721 }
722 f := &SettingsFrame{FrameHeader: fh, p: p}
723 if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
724 // Values above the maximum flow control window size of 2^31 - 1 MUST
725 // be treated as a connection error (Section 5.4.1) of type
726 // FLOW_CONTROL_ERROR.
727 return nil, ConnectionError(ErrCodeFlowControl)
728 }
729 return f, nil
730}
731
732func (f *SettingsFrame) IsAck() bool {
733 return f.FrameHeader.Flags.Has(FlagSettingsAck)
734}
735
736func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) {
737 f.checkValid()
738 buf := f.p
739 for len(buf) > 0 {
740 settingID := SettingID(binary.BigEndian.Uint16(buf[:2]))
741 if settingID == s {
742 return binary.BigEndian.Uint32(buf[2:6]), true
743 }
744 buf = buf[6:]
745 }
746 return 0, false
747}
748
749// ForeachSetting runs fn for each setting.
750// It stops and returns the first error.
751func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
752 f.checkValid()
753 buf := f.p
754 for len(buf) > 0 {
755 if err := fn(Setting{
756 SettingID(binary.BigEndian.Uint16(buf[:2])),
757 binary.BigEndian.Uint32(buf[2:6]),
758 }); err != nil {
759 return err
760 }
761 buf = buf[6:]
762 }
763 return nil
764}
765
766// WriteSettings writes a SETTINGS frame with zero or more settings
767// specified and the ACK bit not set.
768//
769// It will perform exactly one Write to the underlying Writer.
770// It is the caller's responsibility to not call other Write methods concurrently.
771func (f *Framer) WriteSettings(settings ...Setting) error {
772 f.startWrite(FrameSettings, 0, 0)
773 for _, s := range settings {
774 f.writeUint16(uint16(s.ID))
775 f.writeUint32(s.Val)
776 }
777 return f.endWrite()
778}
779
780// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.
781//
782// It will perform exactly one Write to the underlying Writer.
783// It is the caller's responsibility to not call other Write methods concurrently.
784func (f *Framer) WriteSettingsAck() error {
785 f.startWrite(FrameSettings, FlagSettingsAck, 0)
786 return f.endWrite()
787}
788
789// A PingFrame is a mechanism for measuring a minimal round trip time
790// from the sender, as well as determining whether an idle connection
791// is still functional.
792// See http://http2.github.io/http2-spec/#rfc.section.6.7
793type PingFrame struct {
794 FrameHeader
795 Data [8]byte
796}
797
798func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
799
800func parsePingFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
801 if len(payload) != 8 {
802 return nil, ConnectionError(ErrCodeFrameSize)
803 }
804 if fh.StreamID != 0 {
805 return nil, ConnectionError(ErrCodeProtocol)
806 }
807 f := &PingFrame{FrameHeader: fh}
808 copy(f.Data[:], payload)
809 return f, nil
810}
811
812func (f *Framer) WritePing(ack bool, data [8]byte) error {
813 var flags Flags
814 if ack {
815 flags = FlagPingAck
816 }
817 f.startWrite(FramePing, flags, 0)
818 f.writeBytes(data[:])
819 return f.endWrite()
820}
821
822// A GoAwayFrame informs the remote peer to stop creating streams on this connection.
823// See http://http2.github.io/http2-spec/#rfc.section.6.8
824type GoAwayFrame struct {
825 FrameHeader
826 LastStreamID uint32
827 ErrCode ErrCode
828 debugData []byte
829}
830
831// DebugData returns any debug data in the GOAWAY frame. Its contents
832// are not defined.
833// The caller must not retain the returned memory past the next
834// call to ReadFrame.
835func (f *GoAwayFrame) DebugData() []byte {
836 f.checkValid()
837 return f.debugData
838}
839
840func parseGoAwayFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
841 if fh.StreamID != 0 {
842 return nil, ConnectionError(ErrCodeProtocol)
843 }
844 if len(p) < 8 {
845 return nil, ConnectionError(ErrCodeFrameSize)
846 }
847 return &GoAwayFrame{
848 FrameHeader: fh,
849 LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
850 ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])),
851 debugData: p[8:],
852 }, nil
853}
854
855func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {
856 f.startWrite(FrameGoAway, 0, 0)
857 f.writeUint32(maxStreamID & (1<<31 - 1))
858 f.writeUint32(uint32(code))
859 f.writeBytes(debugData)
860 return f.endWrite()
861}
862
863// An UnknownFrame is the frame type returned when the frame type is unknown
864// or no specific frame type parser exists.
865type UnknownFrame struct {
866 FrameHeader
867 p []byte
868}
869
870// Payload returns the frame's payload (after the header). It is not
871// valid to call this method after a subsequent call to
872// Framer.ReadFrame, nor is it valid to retain the returned slice.
873// The memory is owned by the Framer and is invalidated when the next
874// frame is read.
875func (f *UnknownFrame) Payload() []byte {
876 f.checkValid()
877 return f.p
878}
879
880func parseUnknownFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
881 return &UnknownFrame{fh, p}, nil
882}
883
884// A WindowUpdateFrame is used to implement flow control.
885// See http://http2.github.io/http2-spec/#rfc.section.6.9
886type WindowUpdateFrame struct {
887 FrameHeader
888 Increment uint32 // never read with high bit set
889}
890
891func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
892 if len(p) != 4 {
893 return nil, ConnectionError(ErrCodeFrameSize)
894 }
895 inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
896 if inc == 0 {
897 // A receiver MUST treat the receipt of a
898 // WINDOW_UPDATE frame with an flow control window
899 // increment of 0 as a stream error (Section 5.4.2) of
900 // type PROTOCOL_ERROR; errors on the connection flow
901 // control window MUST be treated as a connection
902 // error (Section 5.4.1).
903 if fh.StreamID == 0 {
904 return nil, ConnectionError(ErrCodeProtocol)
905 }
906 return nil, streamError(fh.StreamID, ErrCodeProtocol)
907 }
908 return &WindowUpdateFrame{
909 FrameHeader: fh,
910 Increment: inc,
911 }, nil
912}
913
914// WriteWindowUpdate writes a WINDOW_UPDATE frame.
915// The increment value must be between 1 and 2,147,483,647, inclusive.
916// If the Stream ID is zero, the window update applies to the
917// connection as a whole.
918func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {
919 // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
920 if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
921 return errors.New("illegal window increment value")
922 }
923 f.startWrite(FrameWindowUpdate, 0, streamID)
924 f.writeUint32(incr)
925 return f.endWrite()
926}
927
928// A HeadersFrame is used to open a stream and additionally carries a
929// header block fragment.
930type HeadersFrame struct {
931 FrameHeader
932
933 // Priority is set if FlagHeadersPriority is set in the FrameHeader.
934 Priority PriorityParam
935
936 headerFragBuf []byte // not owned
937}
938
939func (f *HeadersFrame) HeaderBlockFragment() []byte {
940 f.checkValid()
941 return f.headerFragBuf
942}
943
944func (f *HeadersFrame) HeadersEnded() bool {
945 return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)
946}
947
948func (f *HeadersFrame) StreamEnded() bool {
949 return f.FrameHeader.Flags.Has(FlagHeadersEndStream)
950}
951
952func (f *HeadersFrame) HasPriority() bool {
953 return f.FrameHeader.Flags.Has(FlagHeadersPriority)
954}
955
956func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) {
957 hf := &HeadersFrame{
958 FrameHeader: fh,
959 }
960 if fh.StreamID == 0 {
961 // HEADERS frames MUST be associated with a stream. If a HEADERS frame
962 // is received whose stream identifier field is 0x0, the recipient MUST
963 // respond with a connection error (Section 5.4.1) of type
964 // PROTOCOL_ERROR.
965 return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
966 }
967 var padLength uint8
968 if fh.Flags.Has(FlagHeadersPadded) {
969 if p, padLength, err = readByte(p); err != nil {
970 return
971 }
972 }
973 if fh.Flags.Has(FlagHeadersPriority) {
974 var v uint32
975 p, v, err = readUint32(p)
976 if err != nil {
977 return nil, err
978 }
979 hf.Priority.StreamDep = v & 0x7fffffff
980 hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
981 p, hf.Priority.Weight, err = readByte(p)
982 if err != nil {
983 return nil, err
984 }
985 }
986 if len(p)-int(padLength) <= 0 {
987 return nil, streamError(fh.StreamID, ErrCodeProtocol)
988 }
989 hf.headerFragBuf = p[:len(p)-int(padLength)]
990 return hf, nil
991}
992
993// HeadersFrameParam are the parameters for writing a HEADERS frame.
994type HeadersFrameParam struct {
995 // StreamID is the required Stream ID to initiate.
996 StreamID uint32
997 // BlockFragment is part (or all) of a Header Block.
998 BlockFragment []byte
999
1000 // EndStream indicates that the header block is the last that
1001 // the endpoint will send for the identified stream. Setting
1002 // this flag causes the stream to enter one of "half closed"
1003 // states.
1004 EndStream bool
1005
1006 // EndHeaders indicates that this frame contains an entire
1007 // header block and is not followed by any
1008 // CONTINUATION frames.
1009 EndHeaders bool
1010
1011 // PadLength is the optional number of bytes of zeros to add
1012 // to this frame.
1013 PadLength uint8
1014
1015 // Priority, if non-zero, includes stream priority information
1016 // in the HEADER frame.
1017 Priority PriorityParam
1018}
1019
1020// WriteHeaders writes a single HEADERS frame.
1021//
1022// This is a low-level header writing method. Encoding headers and
1023// splitting them into any necessary CONTINUATION frames is handled
1024// elsewhere.
1025//
1026// It will perform exactly one Write to the underlying Writer.
1027// It is the caller's responsibility to not call other Write methods concurrently.
1028func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
1029 if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
1030 return errStreamID
1031 }
1032 var flags Flags
1033 if p.PadLength != 0 {
1034 flags |= FlagHeadersPadded
1035 }
1036 if p.EndStream {
1037 flags |= FlagHeadersEndStream
1038 }
1039 if p.EndHeaders {
1040 flags |= FlagHeadersEndHeaders
1041 }
1042 if !p.Priority.IsZero() {
1043 flags |= FlagHeadersPriority
1044 }
1045 f.startWrite(FrameHeaders, flags, p.StreamID)
1046 if p.PadLength != 0 {
1047 f.writeByte(p.PadLength)
1048 }
1049 if !p.Priority.IsZero() {
1050 v := p.Priority.StreamDep
1051 if !validStreamIDOrZero(v) && !f.AllowIllegalWrites {
1052 return errDepStreamID
1053 }
1054 if p.Priority.Exclusive {
1055 v |= 1 << 31
1056 }
1057 f.writeUint32(v)
1058 f.writeByte(p.Priority.Weight)
1059 }
1060 f.wbuf = append(f.wbuf, p.BlockFragment...)
1061 f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
1062 return f.endWrite()
1063}
1064
1065// A PriorityFrame specifies the sender-advised priority of a stream.
1066// See http://http2.github.io/http2-spec/#rfc.section.6.3
1067type PriorityFrame struct {
1068 FrameHeader
1069 PriorityParam
1070}
1071
1072// PriorityParam are the stream prioritzation parameters.
1073type PriorityParam struct {
1074 // StreamDep is a 31-bit stream identifier for the
1075 // stream that this stream depends on. Zero means no
1076 // dependency.
1077 StreamDep uint32
1078
1079 // Exclusive is whether the dependency is exclusive.
1080 Exclusive bool
1081
1082 // Weight is the stream's zero-indexed weight. It should be
1083 // set together with StreamDep, or neither should be set. Per
1084 // the spec, "Add one to the value to obtain a weight between
1085 // 1 and 256."
1086 Weight uint8
1087}
1088
1089func (p PriorityParam) IsZero() bool {
1090 return p == PriorityParam{}
1091}
1092
1093func parsePriorityFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
1094 if fh.StreamID == 0 {
1095 return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
1096 }
1097 if len(payload) != 5 {
1098 return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
1099 }
1100 v := binary.BigEndian.Uint32(payload[:4])
1101 streamID := v & 0x7fffffff // mask off high bit
1102 return &PriorityFrame{
1103 FrameHeader: fh,
1104 PriorityParam: PriorityParam{
1105 Weight: payload[4],
1106 StreamDep: streamID,
1107 Exclusive: streamID != v, // was high bit set?
1108 },
1109 }, nil
1110}
1111
1112// WritePriority writes a PRIORITY frame.
1113//
1114// It will perform exactly one Write to the underlying Writer.
1115// It is the caller's responsibility to not call other Write methods concurrently.
1116func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
1117 if !validStreamID(streamID) && !f.AllowIllegalWrites {
1118 return errStreamID
1119 }
1120 if !validStreamIDOrZero(p.StreamDep) {
1121 return errDepStreamID
1122 }
1123 f.startWrite(FramePriority, 0, streamID)
1124 v := p.StreamDep
1125 if p.Exclusive {
1126 v |= 1 << 31
1127 }
1128 f.writeUint32(v)
1129 f.writeByte(p.Weight)
1130 return f.endWrite()
1131}
1132
1133// A RSTStreamFrame allows for abnormal termination of a stream.
1134// See http://http2.github.io/http2-spec/#rfc.section.6.4
1135type RSTStreamFrame struct {
1136 FrameHeader
1137 ErrCode ErrCode
1138}
1139
1140func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
1141 if len(p) != 4 {
1142 return nil, ConnectionError(ErrCodeFrameSize)
1143 }
1144 if fh.StreamID == 0 {
1145 return nil, ConnectionError(ErrCodeProtocol)
1146 }
1147 return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
1148}
1149
1150// WriteRSTStream writes a RST_STREAM frame.
1151//
1152// It will perform exactly one Write to the underlying Writer.
1153// It is the caller's responsibility to not call other Write methods concurrently.
1154func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
1155 if !validStreamID(streamID) && !f.AllowIllegalWrites {
1156 return errStreamID
1157 }
1158 f.startWrite(FrameRSTStream, 0, streamID)
1159 f.writeUint32(uint32(code))
1160 return f.endWrite()
1161}
1162
1163// A ContinuationFrame is used to continue a sequence of header block fragments.
1164// See http://http2.github.io/http2-spec/#rfc.section.6.10
1165type ContinuationFrame struct {
1166 FrameHeader
1167 headerFragBuf []byte
1168}
1169
1170func parseContinuationFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
1171 if fh.StreamID == 0 {
1172 return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
1173 }
1174 return &ContinuationFrame{fh, p}, nil
1175}
1176
1177func (f *ContinuationFrame) HeaderBlockFragment() []byte {
1178 f.checkValid()
1179 return f.headerFragBuf
1180}
1181
1182func (f *ContinuationFrame) HeadersEnded() bool {
1183 return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)
1184}
1185
1186// WriteContinuation writes a CONTINUATION frame.
1187//
1188// It will perform exactly one Write to the underlying Writer.
1189// It is the caller's responsibility to not call other Write methods concurrently.
1190func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
1191 if !validStreamID(streamID) && !f.AllowIllegalWrites {
1192 return errStreamID
1193 }
1194 var flags Flags
1195 if endHeaders {
1196 flags |= FlagContinuationEndHeaders
1197 }
1198 f.startWrite(FrameContinuation, flags, streamID)
1199 f.wbuf = append(f.wbuf, headerBlockFragment...)
1200 return f.endWrite()
1201}
1202
1203// A PushPromiseFrame is used to initiate a server stream.
1204// See http://http2.github.io/http2-spec/#rfc.section.6.6
1205type PushPromiseFrame struct {
1206 FrameHeader
1207 PromiseID uint32
1208 headerFragBuf []byte // not owned
1209}
1210
1211func (f *PushPromiseFrame) HeaderBlockFragment() []byte {
1212 f.checkValid()
1213 return f.headerFragBuf
1214}
1215
1216func (f *PushPromiseFrame) HeadersEnded() bool {
1217 return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
1218}
1219
1220func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) {
1221 pp := &PushPromiseFrame{
1222 FrameHeader: fh,
1223 }
1224 if pp.StreamID == 0 {
1225 // PUSH_PROMISE frames MUST be associated with an existing,
1226 // peer-initiated stream. The stream identifier of a
1227 // PUSH_PROMISE frame indicates the stream it is associated
1228 // with. If the stream identifier field specifies the value
1229 // 0x0, a recipient MUST respond with a connection error
1230 // (Section 5.4.1) of type PROTOCOL_ERROR.
1231 return nil, ConnectionError(ErrCodeProtocol)
1232 }
1233 // The PUSH_PROMISE frame includes optional padding.
1234 // Padding fields and flags are identical to those defined for DATA frames
1235 var padLength uint8
1236 if fh.Flags.Has(FlagPushPromisePadded) {
1237 if p, padLength, err = readByte(p); err != nil {
1238 return
1239 }
1240 }
1241
1242 p, pp.PromiseID, err = readUint32(p)
1243 if err != nil {
1244 return
1245 }
1246 pp.PromiseID = pp.PromiseID & (1<<31 - 1)
1247
1248 if int(padLength) > len(p) {
1249 // like the DATA frame, error out if padding is longer than the body.
1250 return nil, ConnectionError(ErrCodeProtocol)
1251 }
1252 pp.headerFragBuf = p[:len(p)-int(padLength)]
1253 return pp, nil
1254}
1255
1256// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
1257type PushPromiseParam struct {
1258 // StreamID is the required Stream ID to initiate.
1259 StreamID uint32
1260
1261 // PromiseID is the required Stream ID which this
1262 // Push Promises
1263 PromiseID uint32
1264
1265 // BlockFragment is part (or all) of a Header Block.
1266 BlockFragment []byte
1267
1268 // EndHeaders indicates that this frame contains an entire
1269 // header block and is not followed by any
1270 // CONTINUATION frames.
1271 EndHeaders bool
1272
1273 // PadLength is the optional number of bytes of zeros to add
1274 // to this frame.
1275 PadLength uint8
1276}
1277
1278// WritePushPromise writes a single PushPromise Frame.
1279//
1280// As with Header Frames, This is the low level call for writing
1281// individual frames. Continuation frames are handled elsewhere.
1282//
1283// It will perform exactly one Write to the underlying Writer.
1284// It is the caller's responsibility to not call other Write methods concurrently.
1285func (f *Framer) WritePushPromise(p PushPromiseParam) error {
1286 if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
1287 return errStreamID
1288 }
1289 var flags Flags
1290 if p.PadLength != 0 {
1291 flags |= FlagPushPromisePadded
1292 }
1293 if p.EndHeaders {
1294 flags |= FlagPushPromiseEndHeaders
1295 }
1296 f.startWrite(FramePushPromise, flags, p.StreamID)
1297 if p.PadLength != 0 {
1298 f.writeByte(p.PadLength)
1299 }
1300 if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
1301 return errStreamID
1302 }
1303 f.writeUint32(p.PromiseID)
1304 f.wbuf = append(f.wbuf, p.BlockFragment...)
1305 f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
1306 return f.endWrite()
1307}
1308
1309// WriteRawFrame writes a raw frame. This can be used to write
1310// extension frames unknown to this package.
1311func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {
1312 f.startWrite(t, flags, streamID)
1313 f.writeBytes(payload)
1314 return f.endWrite()
1315}
1316
1317func readByte(p []byte) (remain []byte, b byte, err error) {
1318 if len(p) == 0 {
1319 return nil, 0, io.ErrUnexpectedEOF
1320 }
1321 return p[1:], p[0], nil
1322}
1323
1324func readUint32(p []byte) (remain []byte, v uint32, err error) {
1325 if len(p) < 4 {
1326 return nil, 0, io.ErrUnexpectedEOF
1327 }
1328 return p[4:], binary.BigEndian.Uint32(p[:4]), nil
1329}
1330
1331type streamEnder interface {
1332 StreamEnded() bool
1333}
1334
1335type headersEnder interface {
1336 HeadersEnded() bool
1337}
1338
1339type headersOrContinuation interface {
1340 headersEnder
1341 HeaderBlockFragment() []byte
1342}
1343
1344// A MetaHeadersFrame is the representation of one HEADERS frame and
1345// zero or more contiguous CONTINUATION frames and the decoding of
1346// their HPACK-encoded contents.
1347//
1348// This type of frame does not appear on the wire and is only returned
1349// by the Framer when Framer.ReadMetaHeaders is set.
1350type MetaHeadersFrame struct {
1351 *HeadersFrame
1352
1353 // Fields are the fields contained in the HEADERS and
1354 // CONTINUATION frames. The underlying slice is owned by the
1355 // Framer and must not be retained after the next call to
1356 // ReadFrame.
1357 //
1358 // Fields are guaranteed to be in the correct http2 order and
1359 // not have unknown pseudo header fields or invalid header
1360 // field names or values. Required pseudo header fields may be
1361 // missing, however. Use the MetaHeadersFrame.Pseudo accessor
1362 // method access pseudo headers.
1363 Fields []hpack.HeaderField
1364
1365 // Truncated is whether the max header list size limit was hit
1366 // and Fields is incomplete. The hpack decoder state is still
1367 // valid, however.
1368 Truncated bool
1369}
1370
1371// PseudoValue returns the given pseudo header field's value.
1372// The provided pseudo field should not contain the leading colon.
1373func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string {
1374 for _, hf := range mh.Fields {
1375 if !hf.IsPseudo() {
1376 return ""
1377 }
1378 if hf.Name[1:] == pseudo {
1379 return hf.Value
1380 }
1381 }
1382 return ""
1383}
1384
1385// RegularFields returns the regular (non-pseudo) header fields of mh.
1386// The caller does not own the returned slice.
1387func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField {
1388 for i, hf := range mh.Fields {
1389 if !hf.IsPseudo() {
1390 return mh.Fields[i:]
1391 }
1392 }
1393 return nil
1394}
1395
1396// PseudoFields returns the pseudo header fields of mh.
1397// The caller does not own the returned slice.
1398func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
1399 for i, hf := range mh.Fields {
1400 if !hf.IsPseudo() {
1401 return mh.Fields[:i]
1402 }
1403 }
1404 return mh.Fields
1405}
1406
1407func (mh *MetaHeadersFrame) checkPseudos() error {
1408 var isRequest, isResponse bool
1409 pf := mh.PseudoFields()
1410 for i, hf := range pf {
1411 switch hf.Name {
1412 case ":method", ":path", ":scheme", ":authority":
1413 isRequest = true
1414 case ":status":
1415 isResponse = true
1416 default:
1417 return pseudoHeaderError(hf.Name)
1418 }
1419 // Check for duplicates.
1420 // This would be a bad algorithm, but N is 4.
1421 // And this doesn't allocate.
1422 for _, hf2 := range pf[:i] {
1423 if hf.Name == hf2.Name {
1424 return duplicatePseudoHeaderError(hf.Name)
1425 }
1426 }
1427 }
1428 if isRequest && isResponse {
1429 return errMixPseudoHeaderTypes
1430 }
1431 return nil
1432}
1433
1434func (fr *Framer) maxHeaderStringLen() int {
1435 v := fr.maxHeaderListSize()
1436 if uint32(int(v)) == v {
1437 return int(v)
1438 }
1439 // They had a crazy big number for MaxHeaderBytes anyway,
1440 // so give them unlimited header lengths:
1441 return 0
1442}
1443
1444// readMetaFrame returns 0 or more CONTINUATION frames from fr and
1445// merge them into into the provided hf and returns a MetaHeadersFrame
1446// with the decoded hpack values.
1447func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
1448 if fr.AllowIllegalReads {
1449 return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
1450 }
1451 mh := &MetaHeadersFrame{
1452 HeadersFrame: hf,
1453 }
1454 var remainSize = fr.maxHeaderListSize()
1455 var sawRegular bool
1456
1457 var invalid error // pseudo header field errors
1458 hdec := fr.ReadMetaHeaders
1459 hdec.SetEmitEnabled(true)
1460 hdec.SetMaxStringLength(fr.maxHeaderStringLen())
1461 hdec.SetEmitFunc(func(hf hpack.HeaderField) {
1462 if VerboseLogs && fr.logReads {
1463 fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
1464 }
1465 if !httplex.ValidHeaderFieldValue(hf.Value) {
1466 invalid = headerFieldValueError(hf.Value)
1467 }
1468 isPseudo := strings.HasPrefix(hf.Name, ":")
1469 if isPseudo {
1470 if sawRegular {
1471 invalid = errPseudoAfterRegular
1472 }
1473 } else {
1474 sawRegular = true
1475 if !validWireHeaderFieldName(hf.Name) {
1476 invalid = headerFieldNameError(hf.Name)
1477 }
1478 }
1479
1480 if invalid != nil {
1481 hdec.SetEmitEnabled(false)
1482 return
1483 }
1484
1485 size := hf.Size()
1486 if size > remainSize {
1487 hdec.SetEmitEnabled(false)
1488 mh.Truncated = true
1489 return
1490 }
1491 remainSize -= size
1492
1493 mh.Fields = append(mh.Fields, hf)
1494 })
1495 // Lose reference to MetaHeadersFrame:
1496 defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})
1497
1498 var hc headersOrContinuation = hf
1499 for {
1500 frag := hc.HeaderBlockFragment()
1501 if _, err := hdec.Write(frag); err != nil {
1502 return nil, ConnectionError(ErrCodeCompression)
1503 }
1504
1505 if hc.HeadersEnded() {
1506 break
1507 }
1508 if f, err := fr.ReadFrame(); err != nil {
1509 return nil, err
1510 } else {
1511 hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder
1512 }
1513 }
1514
1515 mh.HeadersFrame.headerFragBuf = nil
1516 mh.HeadersFrame.invalidate()
1517
1518 if err := hdec.Close(); err != nil {
1519 return nil, ConnectionError(ErrCodeCompression)
1520 }
1521 if invalid != nil {
1522 fr.errDetail = invalid
1523 if VerboseLogs {
1524 log.Printf("http2: invalid header: %v", invalid)
1525 }
1526 return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid}
1527 }
1528 if err := mh.checkPseudos(); err != nil {
1529 fr.errDetail = err
1530 if VerboseLogs {
1531 log.Printf("http2: invalid pseudo headers: %v", err)
1532 }
1533 return nil, StreamError{mh.StreamID, ErrCodeProtocol, err}
1534 }
1535 return mh, nil
1536}
1537
1538func summarizeFrame(f Frame) string {
1539 var buf bytes.Buffer
1540 f.Header().writeDebug(&buf)
1541 switch f := f.(type) {
1542 case *SettingsFrame:
1543 n := 0
1544 f.ForeachSetting(func(s Setting) error {
1545 n++
1546 if n == 1 {
1547 buf.WriteString(", settings:")
1548 }
1549 fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
1550 return nil
1551 })
1552 if n > 0 {
1553 buf.Truncate(buf.Len() - 1) // remove trailing comma
1554 }
1555 case *DataFrame:
1556 data := f.Data()
1557 const max = 256
1558 if len(data) > max {
1559 data = data[:max]
1560 }
1561 fmt.Fprintf(&buf, " data=%q", data)
1562 if len(f.Data()) > max {
1563 fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
1564 }
1565 case *WindowUpdateFrame:
1566 if f.StreamID == 0 {
1567 buf.WriteString(" (conn)")
1568 }
1569 fmt.Fprintf(&buf, " incr=%v", f.Increment)
1570 case *PingFrame:
1571 fmt.Fprintf(&buf, " ping=%q", f.Data[:])
1572 case *GoAwayFrame:
1573 fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
1574 f.LastStreamID, f.ErrCode, f.debugData)
1575 case *RSTStreamFrame:
1576 fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
1577 }
1578 return buf.String()
1579}
diff --git a/vendor/golang.org/x/net/http2/go16.go b/vendor/golang.org/x/net/http2/go16.go
new file mode 100644
index 0000000..00b2e9e
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/go16.go
@@ -0,0 +1,16 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.6
6
7package http2
8
9import (
10 "net/http"
11 "time"
12)
13
14func transportExpectContinueTimeout(t1 *http.Transport) time.Duration {
15 return t1.ExpectContinueTimeout
16}
diff --git a/vendor/golang.org/x/net/http2/go17.go b/vendor/golang.org/x/net/http2/go17.go
new file mode 100644
index 0000000..47b7fae
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/go17.go
@@ -0,0 +1,106 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.7
6
7package http2
8
9import (
10 "context"
11 "net"
12 "net/http"
13 "net/http/httptrace"
14 "time"
15)
16
17type contextContext interface {
18 context.Context
19}
20
21func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) {
22 ctx, cancel = context.WithCancel(context.Background())
23 ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
24 if hs := opts.baseConfig(); hs != nil {
25 ctx = context.WithValue(ctx, http.ServerContextKey, hs)
26 }
27 return
28}
29
30func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) {
31 return context.WithCancel(ctx)
32}
33
34func requestWithContext(req *http.Request, ctx contextContext) *http.Request {
35 return req.WithContext(ctx)
36}
37
38type clientTrace httptrace.ClientTrace
39
40func reqContext(r *http.Request) context.Context { return r.Context() }
41
42func (t *Transport) idleConnTimeout() time.Duration {
43 if t.t1 != nil {
44 return t.t1.IdleConnTimeout
45 }
46 return 0
47}
48
49func setResponseUncompressed(res *http.Response) { res.Uncompressed = true }
50
51func traceGotConn(req *http.Request, cc *ClientConn) {
52 trace := httptrace.ContextClientTrace(req.Context())
53 if trace == nil || trace.GotConn == nil {
54 return
55 }
56 ci := httptrace.GotConnInfo{Conn: cc.tconn}
57 cc.mu.Lock()
58 ci.Reused = cc.nextStreamID > 1
59 ci.WasIdle = len(cc.streams) == 0 && ci.Reused
60 if ci.WasIdle && !cc.lastActive.IsZero() {
61 ci.IdleTime = time.Now().Sub(cc.lastActive)
62 }
63 cc.mu.Unlock()
64
65 trace.GotConn(ci)
66}
67
68func traceWroteHeaders(trace *clientTrace) {
69 if trace != nil && trace.WroteHeaders != nil {
70 trace.WroteHeaders()
71 }
72}
73
74func traceGot100Continue(trace *clientTrace) {
75 if trace != nil && trace.Got100Continue != nil {
76 trace.Got100Continue()
77 }
78}
79
80func traceWait100Continue(trace *clientTrace) {
81 if trace != nil && trace.Wait100Continue != nil {
82 trace.Wait100Continue()
83 }
84}
85
86func traceWroteRequest(trace *clientTrace, err error) {
87 if trace != nil && trace.WroteRequest != nil {
88 trace.WroteRequest(httptrace.WroteRequestInfo{Err: err})
89 }
90}
91
92func traceFirstResponseByte(trace *clientTrace) {
93 if trace != nil && trace.GotFirstResponseByte != nil {
94 trace.GotFirstResponseByte()
95 }
96}
97
98func requestTrace(req *http.Request) *clientTrace {
99 trace := httptrace.ContextClientTrace(req.Context())
100 return (*clientTrace)(trace)
101}
102
103// Ping sends a PING frame to the server and waits for the ack.
104func (cc *ClientConn) Ping(ctx context.Context) error {
105 return cc.ping(ctx)
106}
diff --git a/vendor/golang.org/x/net/http2/go17_not18.go b/vendor/golang.org/x/net/http2/go17_not18.go
new file mode 100644
index 0000000..b4c52ec
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/go17_not18.go
@@ -0,0 +1,36 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.7,!go1.8
6
7package http2
8
9import "crypto/tls"
10
11// temporary copy of Go 1.7's private tls.Config.clone:
12func cloneTLSConfig(c *tls.Config) *tls.Config {
13 return &tls.Config{
14 Rand: c.Rand,
15 Time: c.Time,
16 Certificates: c.Certificates,
17 NameToCertificate: c.NameToCertificate,
18 GetCertificate: c.GetCertificate,
19 RootCAs: c.RootCAs,
20 NextProtos: c.NextProtos,
21 ServerName: c.ServerName,
22 ClientAuth: c.ClientAuth,
23 ClientCAs: c.ClientCAs,
24 InsecureSkipVerify: c.InsecureSkipVerify,
25 CipherSuites: c.CipherSuites,
26 PreferServerCipherSuites: c.PreferServerCipherSuites,
27 SessionTicketsDisabled: c.SessionTicketsDisabled,
28 SessionTicketKey: c.SessionTicketKey,
29 ClientSessionCache: c.ClientSessionCache,
30 MinVersion: c.MinVersion,
31 MaxVersion: c.MaxVersion,
32 CurvePreferences: c.CurvePreferences,
33 DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
34 Renegotiation: c.Renegotiation,
35 }
36}
diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go
new file mode 100644
index 0000000..4f30d22
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/go18.go
@@ -0,0 +1,56 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.8
6
7package http2
8
9import (
10 "crypto/tls"
11 "io"
12 "net/http"
13)
14
15func cloneTLSConfig(c *tls.Config) *tls.Config {
16 c2 := c.Clone()
17 c2.GetClientCertificate = c.GetClientCertificate // golang.org/issue/19264
18 return c2
19}
20
21var _ http.Pusher = (*responseWriter)(nil)
22
23// Push implements http.Pusher.
24func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
25 internalOpts := pushOptions{}
26 if opts != nil {
27 internalOpts.Method = opts.Method
28 internalOpts.Header = opts.Header
29 }
30 return w.push(target, internalOpts)
31}
32
33func configureServer18(h1 *http.Server, h2 *Server) error {
34 if h2.IdleTimeout == 0 {
35 if h1.IdleTimeout != 0 {
36 h2.IdleTimeout = h1.IdleTimeout
37 } else {
38 h2.IdleTimeout = h1.ReadTimeout
39 }
40 }
41 return nil
42}
43
44func shouldLogPanic(panicValue interface{}) bool {
45 return panicValue != nil && panicValue != http.ErrAbortHandler
46}
47
48func reqGetBody(req *http.Request) func() (io.ReadCloser, error) {
49 return req.GetBody
50}
51
52func reqBodyIsNoBody(body io.ReadCloser) bool {
53 return body == http.NoBody
54}
55
56func 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
new file mode 100644
index 0000000..38124ba
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/go19.go
@@ -0,0 +1,16 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.9
6
7package http2
8
9import (
10 "net/http"
11)
12
13func configureServer19(s *http.Server, conf *Server) error {
14 s.RegisterOnShutdown(conf.state.startGracefulShutdown)
15 return nil
16}
diff --git a/vendor/golang.org/x/net/http2/gotrack.go b/vendor/golang.org/x/net/http2/gotrack.go
new file mode 100644
index 0000000..9933c9f
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/gotrack.go
@@ -0,0 +1,170 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Defensive debug-only utility to track that functions run on the
6// goroutine that they're supposed to.
7
8package http2
9
10import (
11 "bytes"
12 "errors"
13 "fmt"
14 "os"
15 "runtime"
16 "strconv"
17 "sync"
18)
19
20var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
21
22type goroutineLock uint64
23
24func newGoroutineLock() goroutineLock {
25 if !DebugGoroutines {
26 return 0
27 }
28 return goroutineLock(curGoroutineID())
29}
30
31func (g goroutineLock) check() {
32 if !DebugGoroutines {
33 return
34 }
35 if curGoroutineID() != uint64(g) {
36 panic("running on the wrong goroutine")
37 }
38}
39
40func (g goroutineLock) checkNotOn() {
41 if !DebugGoroutines {
42 return
43 }
44 if curGoroutineID() == uint64(g) {
45 panic("running on the wrong goroutine")
46 }
47}
48
49var goroutineSpace = []byte("goroutine ")
50
51func curGoroutineID() uint64 {
52 bp := littleBuf.Get().(*[]byte)
53 defer littleBuf.Put(bp)
54 b := *bp
55 b = b[:runtime.Stack(b, false)]
56 // Parse the 4707 out of "goroutine 4707 ["
57 b = bytes.TrimPrefix(b, goroutineSpace)
58 i := bytes.IndexByte(b, ' ')
59 if i < 0 {
60 panic(fmt.Sprintf("No space found in %q", b))
61 }
62 b = b[:i]
63 n, err := parseUintBytes(b, 10, 64)
64 if err != nil {
65 panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err))
66 }
67 return n
68}
69
70var littleBuf = sync.Pool{
71 New: func() interface{} {
72 buf := make([]byte, 64)
73 return &buf
74 },
75}
76
77// parseUintBytes is like strconv.ParseUint, but using a []byte.
78func parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {
79 var cutoff, maxVal uint64
80
81 if bitSize == 0 {
82 bitSize = int(strconv.IntSize)
83 }
84
85 s0 := s
86 switch {
87 case len(s) < 1:
88 err = strconv.ErrSyntax
89 goto Error
90
91 case 2 <= base && base <= 36:
92 // valid base; nothing to do
93
94 case base == 0:
95 // Look for octal, hex prefix.
96 switch {
97 case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
98 base = 16
99 s = s[2:]
100 if len(s) < 1 {
101 err = strconv.ErrSyntax
102 goto Error
103 }
104 case s[0] == '0':
105 base = 8
106 default:
107 base = 10
108 }
109
110 default:
111 err = errors.New("invalid base " + strconv.Itoa(base))
112 goto Error
113 }
114
115 n = 0
116 cutoff = cutoff64(base)
117 maxVal = 1<<uint(bitSize) - 1
118
119 for i := 0; i < len(s); i++ {
120 var v byte
121 d := s[i]
122 switch {
123 case '0' <= d && d <= '9':
124 v = d - '0'
125 case 'a' <= d && d <= 'z':
126 v = d - 'a' + 10
127 case 'A' <= d && d <= 'Z':
128 v = d - 'A' + 10
129 default:
130 n = 0
131 err = strconv.ErrSyntax
132 goto Error
133 }
134 if int(v) >= base {
135 n = 0
136 err = strconv.ErrSyntax
137 goto Error
138 }
139
140 if n >= cutoff {
141 // n*base overflows
142 n = 1<<64 - 1
143 err = strconv.ErrRange
144 goto Error
145 }
146 n *= uint64(base)
147
148 n1 := n + uint64(v)
149 if n1 < n || n1 > maxVal {
150 // n+v overflows
151 n = 1<<64 - 1
152 err = strconv.ErrRange
153 goto Error
154 }
155 n = n1
156 }
157
158 return n, nil
159
160Error:
161 return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
162}
163
164// Return the first number n such that n*base >= 1<<64.
165func cutoff64(base int) uint64 {
166 if base < 2 {
167 return 0
168 }
169 return (1<<64-1)/uint64(base) + 1
170}
diff --git a/vendor/golang.org/x/net/http2/headermap.go b/vendor/golang.org/x/net/http2/headermap.go
new file mode 100644
index 0000000..c2805f6
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/headermap.go
@@ -0,0 +1,78 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import (
8 "net/http"
9 "strings"
10)
11
12var (
13 commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case
14 commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case
15)
16
17func init() {
18 for _, v := range []string{
19 "accept",
20 "accept-charset",
21 "accept-encoding",
22 "accept-language",
23 "accept-ranges",
24 "age",
25 "access-control-allow-origin",
26 "allow",
27 "authorization",
28 "cache-control",
29 "content-disposition",
30 "content-encoding",
31 "content-language",
32 "content-length",
33 "content-location",
34 "content-range",
35 "content-type",
36 "cookie",
37 "date",
38 "etag",
39 "expect",
40 "expires",
41 "from",
42 "host",
43 "if-match",
44 "if-modified-since",
45 "if-none-match",
46 "if-unmodified-since",
47 "last-modified",
48 "link",
49 "location",
50 "max-forwards",
51 "proxy-authenticate",
52 "proxy-authorization",
53 "range",
54 "referer",
55 "refresh",
56 "retry-after",
57 "server",
58 "set-cookie",
59 "strict-transport-security",
60 "trailer",
61 "transfer-encoding",
62 "user-agent",
63 "vary",
64 "via",
65 "www-authenticate",
66 } {
67 chk := http.CanonicalHeaderKey(v)
68 commonLowerHeader[chk] = v
69 commonCanonHeader[v] = chk
70 }
71}
72
73func lowerHeader(v string) string {
74 if s, ok := commonLowerHeader[v]; ok {
75 return s
76 }
77 return strings.ToLower(v)
78}
diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go
new file mode 100644
index 0000000..54726c2
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/hpack/encode.go
@@ -0,0 +1,240 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package hpack
6
7import (
8 "io"
9)
10
11const (
12 uint32Max = ^uint32(0)
13 initialHeaderTableSize = 4096
14)
15
16type Encoder struct {
17 dynTab dynamicTable
18 // minSize is the minimum table size set by
19 // SetMaxDynamicTableSize after the previous Header Table Size
20 // Update.
21 minSize uint32
22 // maxSizeLimit is the maximum table size this encoder
23 // supports. This will protect the encoder from too large
24 // size.
25 maxSizeLimit uint32
26 // tableSizeUpdate indicates whether "Header Table Size
27 // Update" is required.
28 tableSizeUpdate bool
29 w io.Writer
30 buf []byte
31}
32
33// NewEncoder returns a new Encoder which performs HPACK encoding. An
34// encoded data is written to w.
35func NewEncoder(w io.Writer) *Encoder {
36 e := &Encoder{
37 minSize: uint32Max,
38 maxSizeLimit: initialHeaderTableSize,
39 tableSizeUpdate: false,
40 w: w,
41 }
42 e.dynTab.table.init()
43 e.dynTab.setMaxSize(initialHeaderTableSize)
44 return e
45}
46
47// WriteField encodes f into a single Write to e's underlying Writer.
48// This function may also produce bytes for "Header Table Size Update"
49// if necessary. If produced, it is done before encoding f.
50func (e *Encoder) WriteField(f HeaderField) error {
51 e.buf = e.buf[:0]
52
53 if e.tableSizeUpdate {
54 e.tableSizeUpdate = false
55 if e.minSize < e.dynTab.maxSize {
56 e.buf = appendTableSize(e.buf, e.minSize)
57 }
58 e.minSize = uint32Max
59 e.buf = appendTableSize(e.buf, e.dynTab.maxSize)
60 }
61
62 idx, nameValueMatch := e.searchTable(f)
63 if nameValueMatch {
64 e.buf = appendIndexed(e.buf, idx)
65 } else {
66 indexing := e.shouldIndex(f)
67 if indexing {
68 e.dynTab.add(f)
69 }
70
71 if idx == 0 {
72 e.buf = appendNewName(e.buf, f, indexing)
73 } else {
74 e.buf = appendIndexedName(e.buf, f, idx, indexing)
75 }
76 }
77 n, err := e.w.Write(e.buf)
78 if err == nil && n != len(e.buf) {
79 err = io.ErrShortWrite
80 }
81 return err
82}
83
84// searchTable searches f in both stable and dynamic header tables.
85// The static header table is searched first. Only when there is no
86// exact match for both name and value, the dynamic header table is
87// then searched. If there is no match, i is 0. If both name and value
88// match, i is the matched index and nameValueMatch becomes true. If
89// only name matches, i points to that index and nameValueMatch
90// becomes false.
91func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) {
92 i, nameValueMatch = staticTable.search(f)
93 if nameValueMatch {
94 return i, true
95 }
96
97 j, nameValueMatch := e.dynTab.table.search(f)
98 if nameValueMatch || (i == 0 && j != 0) {
99 return j + uint64(staticTable.len()), nameValueMatch
100 }
101
102 return i, false
103}
104
105// SetMaxDynamicTableSize changes the dynamic header table size to v.
106// The actual size is bounded by the value passed to
107// SetMaxDynamicTableSizeLimit.
108func (e *Encoder) SetMaxDynamicTableSize(v uint32) {
109 if v > e.maxSizeLimit {
110 v = e.maxSizeLimit
111 }
112 if v < e.minSize {
113 e.minSize = v
114 }
115 e.tableSizeUpdate = true
116 e.dynTab.setMaxSize(v)
117}
118
119// SetMaxDynamicTableSizeLimit changes the maximum value that can be
120// specified in SetMaxDynamicTableSize to v. By default, it is set to
121// 4096, which is the same size of the default dynamic header table
122// size described in HPACK specification. If the current maximum
123// dynamic header table size is strictly greater than v, "Header Table
124// Size Update" will be done in the next WriteField call and the
125// maximum dynamic header table size is truncated to v.
126func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {
127 e.maxSizeLimit = v
128 if e.dynTab.maxSize > v {
129 e.tableSizeUpdate = true
130 e.dynTab.setMaxSize(v)
131 }
132}
133
134// shouldIndex reports whether f should be indexed.
135func (e *Encoder) shouldIndex(f HeaderField) bool {
136 return !f.Sensitive && f.Size() <= e.dynTab.maxSize
137}
138
139// appendIndexed appends index i, as encoded in "Indexed Header Field"
140// representation, to dst and returns the extended buffer.
141func appendIndexed(dst []byte, i uint64) []byte {
142 first := len(dst)
143 dst = appendVarInt(dst, 7, i)
144 dst[first] |= 0x80
145 return dst
146}
147
148// appendNewName appends f, as encoded in one of "Literal Header field
149// - New Name" representation variants, to dst and returns the
150// extended buffer.
151//
152// If f.Sensitive is true, "Never Indexed" representation is used. If
153// f.Sensitive is false and indexing is true, "Inremental Indexing"
154// representation is used.
155func appendNewName(dst []byte, f HeaderField, indexing bool) []byte {
156 dst = append(dst, encodeTypeByte(indexing, f.Sensitive))
157 dst = appendHpackString(dst, f.Name)
158 return appendHpackString(dst, f.Value)
159}
160
161// appendIndexedName appends f and index i referring indexed name
162// entry, as encoded in one of "Literal Header field - Indexed Name"
163// representation variants, to dst and returns the extended buffer.
164//
165// If f.Sensitive is true, "Never Indexed" representation is used. If
166// f.Sensitive is false and indexing is true, "Incremental Indexing"
167// representation is used.
168func appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte {
169 first := len(dst)
170 var n byte
171 if indexing {
172 n = 6
173 } else {
174 n = 4
175 }
176 dst = appendVarInt(dst, n, i)
177 dst[first] |= encodeTypeByte(indexing, f.Sensitive)
178 return appendHpackString(dst, f.Value)
179}
180
181// appendTableSize appends v, as encoded in "Header Table Size Update"
182// representation, to dst and returns the extended buffer.
183func appendTableSize(dst []byte, v uint32) []byte {
184 first := len(dst)
185 dst = appendVarInt(dst, 5, uint64(v))
186 dst[first] |= 0x20
187 return dst
188}
189
190// appendVarInt appends i, as encoded in variable integer form using n
191// bit prefix, to dst and returns the extended buffer.
192//
193// See
194// http://http2.github.io/http2-spec/compression.html#integer.representation
195func appendVarInt(dst []byte, n byte, i uint64) []byte {
196 k := uint64((1 << n) - 1)
197 if i < k {
198 return append(dst, byte(i))
199 }
200 dst = append(dst, byte(k))
201 i -= k
202 for ; i >= 128; i >>= 7 {
203 dst = append(dst, byte(0x80|(i&0x7f)))
204 }
205 return append(dst, byte(i))
206}
207
208// appendHpackString appends s, as encoded in "String Literal"
209// representation, to dst and returns the the extended buffer.
210//
211// s will be encoded in Huffman codes only when it produces strictly
212// shorter byte string.
213func appendHpackString(dst []byte, s string) []byte {
214 huffmanLength := HuffmanEncodeLength(s)
215 if huffmanLength < uint64(len(s)) {
216 first := len(dst)
217 dst = appendVarInt(dst, 7, huffmanLength)
218 dst = AppendHuffmanString(dst, s)
219 dst[first] |= 0x80
220 } else {
221 dst = appendVarInt(dst, 7, uint64(len(s)))
222 dst = append(dst, s...)
223 }
224 return dst
225}
226
227// encodeTypeByte returns type byte. If sensitive is true, type byte
228// for "Never Indexed" representation is returned. If sensitive is
229// false and indexing is true, type byte for "Incremental Indexing"
230// representation is returned. Otherwise, type byte for "Without
231// Indexing" is returned.
232func encodeTypeByte(indexing, sensitive bool) byte {
233 if sensitive {
234 return 0x10
235 }
236 if indexing {
237 return 0x40
238 }
239 return 0
240}
diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go
new file mode 100644
index 0000000..176644a
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/hpack/hpack.go
@@ -0,0 +1,490 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package hpack implements HPACK, a compression format for
6// efficiently representing HTTP header fields in the context of HTTP/2.
7//
8// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
9package hpack
10
11import (
12 "bytes"
13 "errors"
14 "fmt"
15)
16
17// A DecodingError is something the spec defines as a decoding error.
18type DecodingError struct {
19 Err error
20}
21
22func (de DecodingError) Error() string {
23 return fmt.Sprintf("decoding error: %v", de.Err)
24}
25
26// An InvalidIndexError is returned when an encoder references a table
27// entry before the static table or after the end of the dynamic table.
28type InvalidIndexError int
29
30func (e InvalidIndexError) Error() string {
31 return fmt.Sprintf("invalid indexed representation index %d", int(e))
32}
33
34// A HeaderField is a name-value pair. Both the name and value are
35// treated as opaque sequences of octets.
36type HeaderField struct {
37 Name, Value string
38
39 // Sensitive means that this header field should never be
40 // indexed.
41 Sensitive bool
42}
43
44// IsPseudo reports whether the header field is an http2 pseudo header.
45// That is, it reports whether it starts with a colon.
46// It is not otherwise guaranteed to be a valid pseudo header field,
47// though.
48func (hf HeaderField) IsPseudo() bool {
49 return len(hf.Name) != 0 && hf.Name[0] == ':'
50}
51
52func (hf HeaderField) String() string {
53 var suffix string
54 if hf.Sensitive {
55 suffix = " (sensitive)"
56 }
57 return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
58}
59
60// Size returns the size of an entry per RFC 7541 section 4.1.
61func (hf HeaderField) Size() uint32 {
62 // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
63 // "The size of the dynamic table is the sum of the size of
64 // its entries. The size of an entry is the sum of its name's
65 // length in octets (as defined in Section 5.2), its value's
66 // length in octets (see Section 5.2), plus 32. The size of
67 // an entry is calculated using the length of the name and
68 // value without any Huffman encoding applied."
69
70 // This can overflow if somebody makes a large HeaderField
71 // Name and/or Value by hand, but we don't care, because that
72 // won't happen on the wire because the encoding doesn't allow
73 // it.
74 return uint32(len(hf.Name) + len(hf.Value) + 32)
75}
76
77// A Decoder is the decoding context for incremental processing of
78// header blocks.
79type Decoder struct {
80 dynTab dynamicTable
81 emit func(f HeaderField)
82
83 emitEnabled bool // whether calls to emit are enabled
84 maxStrLen int // 0 means unlimited
85
86 // buf is the unparsed buffer. It's only written to
87 // saveBuf if it was truncated in the middle of a header
88 // block. Because it's usually not owned, we can only
89 // process it under Write.
90 buf []byte // not owned; only valid during Write
91
92 // saveBuf is previous data passed to Write which we weren't able
93 // to fully parse before. Unlike buf, we own this data.
94 saveBuf bytes.Buffer
95}
96
97// NewDecoder returns a new decoder with the provided maximum dynamic
98// table size. The emitFunc will be called for each valid field
99// parsed, in the same goroutine as calls to Write, before Write returns.
100func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
101 d := &Decoder{
102 emit: emitFunc,
103 emitEnabled: true,
104 }
105 d.dynTab.table.init()
106 d.dynTab.allowedMaxSize = maxDynamicTableSize
107 d.dynTab.setMaxSize(maxDynamicTableSize)
108 return d
109}
110
111// ErrStringLength is returned by Decoder.Write when the max string length
112// (as configured by Decoder.SetMaxStringLength) would be violated.
113var ErrStringLength = errors.New("hpack: string too long")
114
115// SetMaxStringLength sets the maximum size of a HeaderField name or
116// value string. If a string exceeds this length (even after any
117// decompression), Write will return ErrStringLength.
118// A value of 0 means unlimited and is the default from NewDecoder.
119func (d *Decoder) SetMaxStringLength(n int) {
120 d.maxStrLen = n
121}
122
123// SetEmitFunc changes the callback used when new header fields
124// are decoded.
125// It must be non-nil. It does not affect EmitEnabled.
126func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
127 d.emit = emitFunc
128}
129
130// SetEmitEnabled controls whether the emitFunc provided to NewDecoder
131// should be called. The default is true.
132//
133// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
134// while still decoding and keeping in-sync with decoder state, but
135// without doing unnecessary decompression or generating unnecessary
136// garbage for header fields past the limit.
137func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
138
139// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
140// are currently enabled. The default is true.
141func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
142
143// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
144// underlying buffers for garbage reasons.
145
146func (d *Decoder) SetMaxDynamicTableSize(v uint32) {
147 d.dynTab.setMaxSize(v)
148}
149
150// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded
151// stream (via dynamic table size updates) may set the maximum size
152// to.
153func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
154 d.dynTab.allowedMaxSize = v
155}
156
157type dynamicTable struct {
158 // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2
159 table headerFieldTable
160 size uint32 // in bytes
161 maxSize uint32 // current maxSize
162 allowedMaxSize uint32 // maxSize may go up to this, inclusive
163}
164
165func (dt *dynamicTable) setMaxSize(v uint32) {
166 dt.maxSize = v
167 dt.evict()
168}
169
170func (dt *dynamicTable) add(f HeaderField) {
171 dt.table.addEntry(f)
172 dt.size += f.Size()
173 dt.evict()
174}
175
176// If we're too big, evict old stuff.
177func (dt *dynamicTable) evict() {
178 var n int
179 for dt.size > dt.maxSize && n < dt.table.len() {
180 dt.size -= dt.table.ents[n].Size()
181 n++
182 }
183 dt.table.evictOldest(n)
184}
185
186func (d *Decoder) maxTableIndex() int {
187 // This should never overflow. RFC 7540 Section 6.5.2 limits the size of
188 // the dynamic table to 2^32 bytes, where each entry will occupy more than
189 // one byte. Further, the staticTable has a fixed, small length.
190 return d.dynTab.table.len() + staticTable.len()
191}
192
193func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {
194 // See Section 2.3.3.
195 if i == 0 {
196 return
197 }
198 if i <= uint64(staticTable.len()) {
199 return staticTable.ents[i-1], true
200 }
201 if i > uint64(d.maxTableIndex()) {
202 return
203 }
204 // In the dynamic table, newer entries have lower indices.
205 // However, dt.ents[0] is the oldest entry. Hence, dt.ents is
206 // the reversed dynamic table.
207 dt := d.dynTab.table
208 return dt.ents[dt.len()-(int(i)-staticTable.len())], true
209}
210
211// Decode decodes an entire block.
212//
213// TODO: remove this method and make it incremental later? This is
214// easier for debugging now.
215func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
216 var hf []HeaderField
217 saveFunc := d.emit
218 defer func() { d.emit = saveFunc }()
219 d.emit = func(f HeaderField) { hf = append(hf, f) }
220 if _, err := d.Write(p); err != nil {
221 return nil, err
222 }
223 if err := d.Close(); err != nil {
224 return nil, err
225 }
226 return hf, nil
227}
228
229func (d *Decoder) Close() error {
230 if d.saveBuf.Len() > 0 {
231 d.saveBuf.Reset()
232 return DecodingError{errors.New("truncated headers")}
233 }
234 return nil
235}
236
237func (d *Decoder) Write(p []byte) (n int, err error) {
238 if len(p) == 0 {
239 // Prevent state machine CPU attacks (making us redo
240 // work up to the point of finding out we don't have
241 // enough data)
242 return
243 }
244 // Only copy the data if we have to. Optimistically assume
245 // that p will contain a complete header block.
246 if d.saveBuf.Len() == 0 {
247 d.buf = p
248 } else {
249 d.saveBuf.Write(p)
250 d.buf = d.saveBuf.Bytes()
251 d.saveBuf.Reset()
252 }
253
254 for len(d.buf) > 0 {
255 err = d.parseHeaderFieldRepr()
256 if err == errNeedMore {
257 // Extra paranoia, making sure saveBuf won't
258 // get too large. All the varint and string
259 // reading code earlier should already catch
260 // overlong things and return ErrStringLength,
261 // but keep this as a last resort.
262 const varIntOverhead = 8 // conservative
263 if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
264 return 0, ErrStringLength
265 }
266 d.saveBuf.Write(d.buf)
267 return len(p), nil
268 }
269 if err != nil {
270 break
271 }
272 }
273 return len(p), err
274}
275
276// errNeedMore is an internal sentinel error value that means the
277// buffer is truncated and we need to read more data before we can
278// continue parsing.
279var errNeedMore = errors.New("need more data")
280
281type indexType int
282
283const (
284 indexedTrue indexType = iota
285 indexedFalse
286 indexedNever
287)
288
289func (v indexType) indexed() bool { return v == indexedTrue }
290func (v indexType) sensitive() bool { return v == indexedNever }
291
292// returns errNeedMore if there isn't enough data available.
293// any other error is fatal.
294// consumes d.buf iff it returns nil.
295// precondition: must be called with len(d.buf) > 0
296func (d *Decoder) parseHeaderFieldRepr() error {
297 b := d.buf[0]
298 switch {
299 case b&128 != 0:
300 // Indexed representation.
301 // High bit set?
302 // http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
303 return d.parseFieldIndexed()
304 case b&192 == 64:
305 // 6.2.1 Literal Header Field with Incremental Indexing
306 // 0b10xxxxxx: top two bits are 10
307 // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1
308 return d.parseFieldLiteral(6, indexedTrue)
309 case b&240 == 0:
310 // 6.2.2 Literal Header Field without Indexing
311 // 0b0000xxxx: top four bits are 0000
312 // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2
313 return d.parseFieldLiteral(4, indexedFalse)
314 case b&240 == 16:
315 // 6.2.3 Literal Header Field never Indexed
316 // 0b0001xxxx: top four bits are 0001
317 // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3
318 return d.parseFieldLiteral(4, indexedNever)
319 case b&224 == 32:
320 // 6.3 Dynamic Table Size Update
321 // Top three bits are '001'.
322 // http://http2.github.io/http2-spec/compression.html#rfc.section.6.3
323 return d.parseDynamicTableSizeUpdate()
324 }
325
326 return DecodingError{errors.New("invalid encoding")}
327}
328
329// (same invariants and behavior as parseHeaderFieldRepr)
330func (d *Decoder) parseFieldIndexed() error {
331 buf := d.buf
332 idx, buf, err := readVarInt(7, buf)
333 if err != nil {
334 return err
335 }
336 hf, ok := d.at(idx)
337 if !ok {
338 return DecodingError{InvalidIndexError(idx)}
339 }
340 d.buf = buf
341 return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
342}
343
344// (same invariants and behavior as parseHeaderFieldRepr)
345func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
346 buf := d.buf
347 nameIdx, buf, err := readVarInt(n, buf)
348 if err != nil {
349 return err
350 }
351
352 var hf HeaderField
353 wantStr := d.emitEnabled || it.indexed()
354 if nameIdx > 0 {
355 ihf, ok := d.at(nameIdx)
356 if !ok {
357 return DecodingError{InvalidIndexError(nameIdx)}
358 }
359 hf.Name = ihf.Name
360 } else {
361 hf.Name, buf, err = d.readString(buf, wantStr)
362 if err != nil {
363 return err
364 }
365 }
366 hf.Value, buf, err = d.readString(buf, wantStr)
367 if err != nil {
368 return err
369 }
370 d.buf = buf
371 if it.indexed() {
372 d.dynTab.add(hf)
373 }
374 hf.Sensitive = it.sensitive()
375 return d.callEmit(hf)
376}
377
378func (d *Decoder) callEmit(hf HeaderField) error {
379 if d.maxStrLen != 0 {
380 if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
381 return ErrStringLength
382 }
383 }
384 if d.emitEnabled {
385 d.emit(hf)
386 }
387 return nil
388}
389
390// (same invariants and behavior as parseHeaderFieldRepr)
391func (d *Decoder) parseDynamicTableSizeUpdate() error {
392 buf := d.buf
393 size, buf, err := readVarInt(5, buf)
394 if err != nil {
395 return err
396 }
397 if size > uint64(d.dynTab.allowedMaxSize) {
398 return DecodingError{errors.New("dynamic table size update too large")}
399 }
400 d.dynTab.setMaxSize(uint32(size))
401 d.buf = buf
402 return nil
403}
404
405var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
406
407// readVarInt reads an unsigned variable length integer off the
408// beginning of p. n is the parameter as described in
409// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1.
410//
411// n must always be between 1 and 8.
412//
413// The returned remain buffer is either a smaller suffix of p, or err != nil.
414// The error is errNeedMore if p doesn't contain a complete integer.
415func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
416 if n < 1 || n > 8 {
417 panic("bad n")
418 }
419 if len(p) == 0 {
420 return 0, p, errNeedMore
421 }
422 i = uint64(p[0])
423 if n < 8 {
424 i &= (1 << uint64(n)) - 1
425 }
426 if i < (1<<uint64(n))-1 {
427 return i, p[1:], nil
428 }
429
430 origP := p
431 p = p[1:]
432 var m uint64
433 for len(p) > 0 {
434 b := p[0]
435 p = p[1:]
436 i += uint64(b&127) << m
437 if b&128 == 0 {
438 return i, p, nil
439 }
440 m += 7
441 if m >= 63 { // TODO: proper overflow check. making this up.
442 return 0, origP, errVarintOverflow
443 }
444 }
445 return 0, origP, errNeedMore
446}
447
448// readString decodes an hpack string from p.
449//
450// wantStr is whether s will be used. If false, decompression and
451// []byte->string garbage are skipped if s will be ignored
452// anyway. This does mean that huffman decoding errors for non-indexed
453// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
454// is returning an error anyway, and because they're not indexed, the error
455// won't affect the decoding state.
456func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) {
457 if len(p) == 0 {
458 return "", p, errNeedMore
459 }
460 isHuff := p[0]&128 != 0
461 strLen, p, err := readVarInt(7, p)
462 if err != nil {
463 return "", p, err
464 }
465 if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
466 return "", nil, ErrStringLength
467 }
468 if uint64(len(p)) < strLen {
469 return "", p, errNeedMore
470 }
471 if !isHuff {
472 if wantStr {
473 s = string(p[:strLen])
474 }
475 return s, p[strLen:], nil
476 }
477
478 if wantStr {
479 buf := bufPool.Get().(*bytes.Buffer)
480 buf.Reset() // don't trust others
481 defer bufPool.Put(buf)
482 if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil {
483 buf.Reset()
484 return "", nil, err
485 }
486 s = buf.String()
487 buf.Reset() // be nice to GC
488 }
489 return s, p[strLen:], nil
490}
diff --git a/vendor/golang.org/x/net/http2/hpack/huffman.go b/vendor/golang.org/x/net/http2/hpack/huffman.go
new file mode 100644
index 0000000..8850e39
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/hpack/huffman.go
@@ -0,0 +1,212 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package hpack
6
7import (
8 "bytes"
9 "errors"
10 "io"
11 "sync"
12)
13
14var bufPool = sync.Pool{
15 New: func() interface{} { return new(bytes.Buffer) },
16}
17
18// HuffmanDecode decodes the string in v and writes the expanded
19// result to w, returning the number of bytes written to w and the
20// Write call's return value. At most one Write call is made.
21func HuffmanDecode(w io.Writer, v []byte) (int, error) {
22 buf := bufPool.Get().(*bytes.Buffer)
23 buf.Reset()
24 defer bufPool.Put(buf)
25 if err := huffmanDecode(buf, 0, v); err != nil {
26 return 0, err
27 }
28 return w.Write(buf.Bytes())
29}
30
31// HuffmanDecodeToString decodes the string in v.
32func HuffmanDecodeToString(v []byte) (string, error) {
33 buf := bufPool.Get().(*bytes.Buffer)
34 buf.Reset()
35 defer bufPool.Put(buf)
36 if err := huffmanDecode(buf, 0, v); err != nil {
37 return "", err
38 }
39 return buf.String(), nil
40}
41
42// ErrInvalidHuffman is returned for errors found decoding
43// Huffman-encoded strings.
44var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
45
46// huffmanDecode decodes v to buf.
47// If maxLen is greater than 0, attempts to write more to buf than
48// maxLen bytes will return ErrStringLength.
49func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
50 n := rootHuffmanNode
51 // cur is the bit buffer that has not been fed into n.
52 // cbits is the number of low order bits in cur that are valid.
53 // sbits is the number of bits of the symbol prefix being decoded.
54 cur, cbits, sbits := uint(0), uint8(0), uint8(0)
55 for _, b := range v {
56 cur = cur<<8 | uint(b)
57 cbits += 8
58 sbits += 8
59 for cbits >= 8 {
60 idx := byte(cur >> (cbits - 8))
61 n = n.children[idx]
62 if n == nil {
63 return ErrInvalidHuffman
64 }
65 if n.children == nil {
66 if maxLen != 0 && buf.Len() == maxLen {
67 return ErrStringLength
68 }
69 buf.WriteByte(n.sym)
70 cbits -= n.codeLen
71 n = rootHuffmanNode
72 sbits = cbits
73 } else {
74 cbits -= 8
75 }
76 }
77 }
78 for cbits > 0 {
79 n = n.children[byte(cur<<(8-cbits))]
80 if n == nil {
81 return ErrInvalidHuffman
82 }
83 if n.children != nil || n.codeLen > cbits {
84 break
85 }
86 if maxLen != 0 && buf.Len() == maxLen {
87 return ErrStringLength
88 }
89 buf.WriteByte(n.sym)
90 cbits -= n.codeLen
91 n = rootHuffmanNode
92 sbits = cbits
93 }
94 if sbits > 7 {
95 // Either there was an incomplete symbol, or overlong padding.
96 // Both are decoding errors per RFC 7541 section 5.2.
97 return ErrInvalidHuffman
98 }
99 if mask := uint(1<<cbits - 1); cur&mask != mask {
100 // Trailing bits must be a prefix of EOS per RFC 7541 section 5.2.
101 return ErrInvalidHuffman
102 }
103
104 return nil
105}
106
107type node struct {
108 // children is non-nil for internal nodes
109 children []*node
110
111 // The following are only valid if children is nil:
112 codeLen uint8 // number of bits that led to the output of sym
113 sym byte // output symbol
114}
115
116func newInternalNode() *node {
117 return &node{children: make([]*node, 256)}
118}
119
120var rootHuffmanNode = newInternalNode()
121
122func init() {
123 if len(huffmanCodes) != 256 {
124 panic("unexpected size")
125 }
126 for i, code := range huffmanCodes {
127 addDecoderNode(byte(i), code, huffmanCodeLen[i])
128 }
129}
130
131func addDecoderNode(sym byte, code uint32, codeLen uint8) {
132 cur := rootHuffmanNode
133 for codeLen > 8 {
134 codeLen -= 8
135 i := uint8(code >> codeLen)
136 if cur.children[i] == nil {
137 cur.children[i] = newInternalNode()
138 }
139 cur = cur.children[i]
140 }
141 shift := 8 - codeLen
142 start, end := int(uint8(code<<shift)), int(1<<shift)
143 for i := start; i < start+end; i++ {
144 cur.children[i] = &node{sym: sym, codeLen: codeLen}
145 }
146}
147
148// AppendHuffmanString appends s, as encoded in Huffman codes, to dst
149// and returns the extended buffer.
150func AppendHuffmanString(dst []byte, s string) []byte {
151 rembits := uint8(8)
152
153 for i := 0; i < len(s); i++ {
154 if rembits == 8 {
155 dst = append(dst, 0)
156 }
157 dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i])
158 }
159
160 if rembits < 8 {
161 // special EOS symbol
162 code := uint32(0x3fffffff)
163 nbits := uint8(30)
164
165 t := uint8(code >> (nbits - rembits))
166 dst[len(dst)-1] |= t
167 }
168
169 return dst
170}
171
172// HuffmanEncodeLength returns the number of bytes required to encode
173// s in Huffman codes. The result is round up to byte boundary.
174func HuffmanEncodeLength(s string) uint64 {
175 n := uint64(0)
176 for i := 0; i < len(s); i++ {
177 n += uint64(huffmanCodeLen[s[i]])
178 }
179 return (n + 7) / 8
180}
181
182// appendByteToHuffmanCode appends Huffman code for c to dst and
183// returns the extended buffer and the remaining bits in the last
184// element. The appending is not byte aligned and the remaining bits
185// in the last element of dst is given in rembits.
186func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) {
187 code := huffmanCodes[c]
188 nbits := huffmanCodeLen[c]
189
190 for {
191 if rembits > nbits {
192 t := uint8(code << (rembits - nbits))
193 dst[len(dst)-1] |= t
194 rembits -= nbits
195 break
196 }
197
198 t := uint8(code >> (nbits - rembits))
199 dst[len(dst)-1] |= t
200
201 nbits -= rembits
202 rembits = 8
203
204 if nbits == 0 {
205 break
206 }
207
208 dst = append(dst, 0)
209 }
210
211 return dst, rembits
212}
diff --git a/vendor/golang.org/x/net/http2/hpack/tables.go b/vendor/golang.org/x/net/http2/hpack/tables.go
new file mode 100644
index 0000000..a66cfbe
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/hpack/tables.go
@@ -0,0 +1,479 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package hpack
6
7import (
8 "fmt"
9)
10
11// headerFieldTable implements a list of HeaderFields.
12// This is used to implement the static and dynamic tables.
13type headerFieldTable struct {
14 // For static tables, entries are never evicted.
15 //
16 // For dynamic tables, entries are evicted from ents[0] and added to the end.
17 // Each entry has a unique id that starts at one and increments for each
18 // entry that is added. This unique id is stable across evictions, meaning
19 // it can be used as a pointer to a specific entry. As in hpack, unique ids
20 // are 1-based. The unique id for ents[k] is k + evictCount + 1.
21 //
22 // Zero is not a valid unique id.
23 //
24 // evictCount should not overflow in any remotely practical situation. In
25 // practice, we will have one dynamic table per HTTP/2 connection. If we
26 // assume a very powerful server that handles 1M QPS per connection and each
27 // request adds (then evicts) 100 entries from the table, it would still take
28 // 2M years for evictCount to overflow.
29 ents []HeaderField
30 evictCount uint64
31
32 // byName maps a HeaderField name to the unique id of the newest entry with
33 // the same name. See above for a definition of "unique id".
34 byName map[string]uint64
35
36 // byNameValue maps a HeaderField name/value pair to the unique id of the newest
37 // entry with the same name and value. See above for a definition of "unique id".
38 byNameValue map[pairNameValue]uint64
39}
40
41type pairNameValue struct {
42 name, value string
43}
44
45func (t *headerFieldTable) init() {
46 t.byName = make(map[string]uint64)
47 t.byNameValue = make(map[pairNameValue]uint64)
48}
49
50// len reports the number of entries in the table.
51func (t *headerFieldTable) len() int {
52 return len(t.ents)
53}
54
55// addEntry adds a new entry.
56func (t *headerFieldTable) addEntry(f HeaderField) {
57 id := uint64(t.len()) + t.evictCount + 1
58 t.byName[f.Name] = id
59 t.byNameValue[pairNameValue{f.Name, f.Value}] = id
60 t.ents = append(t.ents, f)
61}
62
63// evictOldest evicts the n oldest entries in the table.
64func (t *headerFieldTable) evictOldest(n int) {
65 if n > t.len() {
66 panic(fmt.Sprintf("evictOldest(%v) on table with %v entries", n, t.len()))
67 }
68 for k := 0; k < n; k++ {
69 f := t.ents[k]
70 id := t.evictCount + uint64(k) + 1
71 if t.byName[f.Name] == id {
72 delete(t.byName, f.Name)
73 }
74 if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id {
75 delete(t.byNameValue, p)
76 }
77 }
78 copy(t.ents, t.ents[n:])
79 for k := t.len() - n; k < t.len(); k++ {
80 t.ents[k] = HeaderField{} // so strings can be garbage collected
81 }
82 t.ents = t.ents[:t.len()-n]
83 if t.evictCount+uint64(n) < t.evictCount {
84 panic("evictCount overflow")
85 }
86 t.evictCount += uint64(n)
87}
88
89// search finds f in the table. If there is no match, i is 0.
90// If both name and value match, i is the matched index and nameValueMatch
91// becomes true. If only name matches, i points to that index and
92// nameValueMatch becomes false.
93//
94// The returned index is a 1-based HPACK index. For dynamic tables, HPACK says
95// that index 1 should be the newest entry, but t.ents[0] is the oldest entry,
96// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic
97// table, the return value i actually refers to the entry t.ents[t.len()-i].
98//
99// All tables are assumed to be a dynamic tables except for the global
100// staticTable pointer.
101//
102// See Section 2.3.3.
103func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
104 if !f.Sensitive {
105 if id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 {
106 return t.idToIndex(id), true
107 }
108 }
109 if id := t.byName[f.Name]; id != 0 {
110 return t.idToIndex(id), false
111 }
112 return 0, false
113}
114
115// idToIndex converts a unique id to an HPACK index.
116// See Section 2.3.3.
117func (t *headerFieldTable) idToIndex(id uint64) uint64 {
118 if id <= t.evictCount {
119 panic(fmt.Sprintf("id (%v) <= evictCount (%v)", id, t.evictCount))
120 }
121 k := id - t.evictCount - 1 // convert id to an index t.ents[k]
122 if t != staticTable {
123 return uint64(t.len()) - k // dynamic table
124 }
125 return k + 1
126}
127
128// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
129var staticTable = newStaticTable()
130var staticTableEntries = [...]HeaderField{
131 {Name: ":authority"},
132 {Name: ":method", Value: "GET"},
133 {Name: ":method", Value: "POST"},
134 {Name: ":path", Value: "/"},
135 {Name: ":path", Value: "/index.html"},
136 {Name: ":scheme", Value: "http"},
137 {Name: ":scheme", Value: "https"},
138 {Name: ":status", Value: "200"},
139 {Name: ":status", Value: "204"},
140 {Name: ":status", Value: "206"},
141 {Name: ":status", Value: "304"},
142 {Name: ":status", Value: "400"},
143 {Name: ":status", Value: "404"},
144 {Name: ":status", Value: "500"},
145 {Name: "accept-charset"},
146 {Name: "accept-encoding", Value: "gzip, deflate"},
147 {Name: "accept-language"},
148 {Name: "accept-ranges"},
149 {Name: "accept"},
150 {Name: "access-control-allow-origin"},
151 {Name: "age"},
152 {Name: "allow"},
153 {Name: "authorization"},
154 {Name: "cache-control"},
155 {Name: "content-disposition"},
156 {Name: "content-encoding"},
157 {Name: "content-language"},
158 {Name: "content-length"},
159 {Name: "content-location"},
160 {Name: "content-range"},
161 {Name: "content-type"},
162 {Name: "cookie"},
163 {Name: "date"},
164 {Name: "etag"},
165 {Name: "expect"},
166 {Name: "expires"},
167 {Name: "from"},
168 {Name: "host"},
169 {Name: "if-match"},
170 {Name: "if-modified-since"},
171 {Name: "if-none-match"},
172 {Name: "if-range"},
173 {Name: "if-unmodified-since"},
174 {Name: "last-modified"},
175 {Name: "link"},
176 {Name: "location"},
177 {Name: "max-forwards"},
178 {Name: "proxy-authenticate"},
179 {Name: "proxy-authorization"},
180 {Name: "range"},
181 {Name: "referer"},
182 {Name: "refresh"},
183 {Name: "retry-after"},
184 {Name: "server"},
185 {Name: "set-cookie"},
186 {Name: "strict-transport-security"},
187 {Name: "transfer-encoding"},
188 {Name: "user-agent"},
189 {Name: "vary"},
190 {Name: "via"},
191 {Name: "www-authenticate"},
192}
193
194func newStaticTable() *headerFieldTable {
195 t := &headerFieldTable{}
196 t.init()
197 for _, e := range staticTableEntries[:] {
198 t.addEntry(e)
199 }
200 return t
201}
202
203var huffmanCodes = [256]uint32{
204 0x1ff8,
205 0x7fffd8,
206 0xfffffe2,
207 0xfffffe3,
208 0xfffffe4,
209 0xfffffe5,
210 0xfffffe6,
211 0xfffffe7,
212 0xfffffe8,
213 0xffffea,
214 0x3ffffffc,
215 0xfffffe9,
216 0xfffffea,
217 0x3ffffffd,
218 0xfffffeb,
219 0xfffffec,
220 0xfffffed,
221 0xfffffee,
222 0xfffffef,
223 0xffffff0,
224 0xffffff1,
225 0xffffff2,
226 0x3ffffffe,
227 0xffffff3,
228 0xffffff4,
229 0xffffff5,
230 0xffffff6,
231 0xffffff7,
232 0xffffff8,
233 0xffffff9,
234 0xffffffa,
235 0xffffffb,
236 0x14,
237 0x3f8,
238 0x3f9,
239 0xffa,
240 0x1ff9,
241 0x15,
242 0xf8,
243 0x7fa,
244 0x3fa,
245 0x3fb,
246 0xf9,
247 0x7fb,
248 0xfa,
249 0x16,
250 0x17,
251 0x18,
252 0x0,
253 0x1,
254 0x2,
255 0x19,
256 0x1a,
257 0x1b,
258 0x1c,
259 0x1d,
260 0x1e,
261 0x1f,
262 0x5c,
263 0xfb,
264 0x7ffc,
265 0x20,
266 0xffb,
267 0x3fc,
268 0x1ffa,
269 0x21,
270 0x5d,
271 0x5e,
272 0x5f,
273 0x60,
274 0x61,
275 0x62,
276 0x63,
277 0x64,
278 0x65,
279 0x66,
280 0x67,
281 0x68,
282 0x69,
283 0x6a,
284 0x6b,
285 0x6c,
286 0x6d,
287 0x6e,
288 0x6f,
289 0x70,
290 0x71,
291 0x72,
292 0xfc,
293 0x73,
294 0xfd,
295 0x1ffb,
296 0x7fff0,
297 0x1ffc,
298 0x3ffc,
299 0x22,
300 0x7ffd,
301 0x3,
302 0x23,
303 0x4,
304 0x24,
305 0x5,
306 0x25,
307 0x26,
308 0x27,
309 0x6,
310 0x74,
311 0x75,
312 0x28,
313 0x29,
314 0x2a,
315 0x7,
316 0x2b,
317 0x76,
318 0x2c,
319 0x8,
320 0x9,
321 0x2d,
322 0x77,
323 0x78,
324 0x79,
325 0x7a,
326 0x7b,
327 0x7ffe,
328 0x7fc,
329 0x3ffd,
330 0x1ffd,
331 0xffffffc,
332 0xfffe6,
333 0x3fffd2,
334 0xfffe7,
335 0xfffe8,
336 0x3fffd3,
337 0x3fffd4,
338 0x3fffd5,
339 0x7fffd9,
340 0x3fffd6,
341 0x7fffda,
342 0x7fffdb,
343 0x7fffdc,
344 0x7fffdd,
345 0x7fffde,
346 0xffffeb,
347 0x7fffdf,
348 0xffffec,
349 0xffffed,
350 0x3fffd7,
351 0x7fffe0,
352 0xffffee,
353 0x7fffe1,
354 0x7fffe2,
355 0x7fffe3,
356 0x7fffe4,
357 0x1fffdc,
358 0x3fffd8,
359 0x7fffe5,
360 0x3fffd9,
361 0x7fffe6,
362 0x7fffe7,
363 0xffffef,
364 0x3fffda,
365 0x1fffdd,
366 0xfffe9,
367 0x3fffdb,
368 0x3fffdc,
369 0x7fffe8,
370 0x7fffe9,
371 0x1fffde,
372 0x7fffea,
373 0x3fffdd,
374 0x3fffde,
375 0xfffff0,
376 0x1fffdf,
377 0x3fffdf,
378 0x7fffeb,
379 0x7fffec,
380 0x1fffe0,
381 0x1fffe1,
382 0x3fffe0,
383 0x1fffe2,
384 0x7fffed,
385 0x3fffe1,
386 0x7fffee,
387 0x7fffef,
388 0xfffea,
389 0x3fffe2,
390 0x3fffe3,
391 0x3fffe4,
392 0x7ffff0,
393 0x3fffe5,
394 0x3fffe6,
395 0x7ffff1,
396 0x3ffffe0,
397 0x3ffffe1,
398 0xfffeb,
399 0x7fff1,
400 0x3fffe7,
401 0x7ffff2,
402 0x3fffe8,
403 0x1ffffec,
404 0x3ffffe2,
405 0x3ffffe3,
406 0x3ffffe4,
407 0x7ffffde,
408 0x7ffffdf,
409 0x3ffffe5,
410 0xfffff1,
411 0x1ffffed,
412 0x7fff2,
413 0x1fffe3,
414 0x3ffffe6,
415 0x7ffffe0,
416 0x7ffffe1,
417 0x3ffffe7,
418 0x7ffffe2,
419 0xfffff2,
420 0x1fffe4,
421 0x1fffe5,
422 0x3ffffe8,
423 0x3ffffe9,
424 0xffffffd,
425 0x7ffffe3,
426 0x7ffffe4,
427 0x7ffffe5,
428 0xfffec,
429 0xfffff3,
430 0xfffed,
431 0x1fffe6,
432 0x3fffe9,
433 0x1fffe7,
434 0x1fffe8,
435 0x7ffff3,
436 0x3fffea,
437 0x3fffeb,
438 0x1ffffee,
439 0x1ffffef,
440 0xfffff4,
441 0xfffff5,
442 0x3ffffea,
443 0x7ffff4,
444 0x3ffffeb,
445 0x7ffffe6,
446 0x3ffffec,
447 0x3ffffed,
448 0x7ffffe7,
449 0x7ffffe8,
450 0x7ffffe9,
451 0x7ffffea,
452 0x7ffffeb,
453 0xffffffe,
454 0x7ffffec,
455 0x7ffffed,
456 0x7ffffee,
457 0x7ffffef,
458 0x7fffff0,
459 0x3ffffee,
460}
461
462var huffmanCodeLen = [256]uint8{
463 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
464 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
465 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
466 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,
467 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
468 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,
469 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,
470 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,
471 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,
472 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,
473 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,
474 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,
475 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,
476 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,
477 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,
478 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
479}
diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go
new file mode 100644
index 0000000..d565f40
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/http2.go
@@ -0,0 +1,391 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package http2 implements the HTTP/2 protocol.
6//
7// This package is low-level and intended to be used directly by very
8// few people. Most users will use it indirectly through the automatic
9// use by the net/http package (from Go 1.6 and later).
10// For use in earlier Go versions see ConfigureServer. (Transport support
11// requires Go 1.6 or later)
12//
13// See https://http2.github.io/ for more information on HTTP/2.
14//
15// See https://http2.golang.org/ for a test server running this code.
16//
17package http2 // import "golang.org/x/net/http2"
18
19import (
20 "bufio"
21 "crypto/tls"
22 "errors"
23 "fmt"
24 "io"
25 "net/http"
26 "os"
27 "sort"
28 "strconv"
29 "strings"
30 "sync"
31
32 "golang.org/x/net/lex/httplex"
33)
34
35var (
36 VerboseLogs bool
37 logFrameWrites bool
38 logFrameReads bool
39 inTests bool
40)
41
42func init() {
43 e := os.Getenv("GODEBUG")
44 if strings.Contains(e, "http2debug=1") {
45 VerboseLogs = true
46 }
47 if strings.Contains(e, "http2debug=2") {
48 VerboseLogs = true
49 logFrameWrites = true
50 logFrameReads = true
51 }
52}
53
54const (
55 // ClientPreface is the string that must be sent by new
56 // connections from clients.
57 ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
58
59 // SETTINGS_MAX_FRAME_SIZE default
60 // http://http2.github.io/http2-spec/#rfc.section.6.5.2
61 initialMaxFrameSize = 16384
62
63 // NextProtoTLS is the NPN/ALPN protocol negotiated during
64 // HTTP/2's TLS setup.
65 NextProtoTLS = "h2"
66
67 // http://http2.github.io/http2-spec/#SettingValues
68 initialHeaderTableSize = 4096
69
70 initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
71
72 defaultMaxReadFrameSize = 1 << 20
73)
74
75var (
76 clientPreface = []byte(ClientPreface)
77)
78
79type streamState int
80
81// HTTP/2 stream states.
82//
83// See http://tools.ietf.org/html/rfc7540#section-5.1.
84//
85// For simplicity, the server code merges "reserved (local)" into
86// "half-closed (remote)". This is one less state transition to track.
87// The only downside is that we send PUSH_PROMISEs slightly less
88// liberally than allowable. More discussion here:
89// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html
90//
91// "reserved (remote)" is omitted since the client code does not
92// support server push.
93const (
94 stateIdle streamState = iota
95 stateOpen
96 stateHalfClosedLocal
97 stateHalfClosedRemote
98 stateClosed
99)
100
101var stateName = [...]string{
102 stateIdle: "Idle",
103 stateOpen: "Open",
104 stateHalfClosedLocal: "HalfClosedLocal",
105 stateHalfClosedRemote: "HalfClosedRemote",
106 stateClosed: "Closed",
107}
108
109func (st streamState) String() string {
110 return stateName[st]
111}
112
113// Setting is a setting parameter: which setting it is, and its value.
114type Setting struct {
115 // ID is which setting is being set.
116 // See http://http2.github.io/http2-spec/#SettingValues
117 ID SettingID
118
119 // Val is the value.
120 Val uint32
121}
122
123func (s Setting) String() string {
124 return fmt.Sprintf("[%v = %d]", s.ID, s.Val)
125}
126
127// Valid reports whether the setting is valid.
128func (s Setting) Valid() error {
129 // Limits and error codes from 6.5.2 Defined SETTINGS Parameters
130 switch s.ID {
131 case SettingEnablePush:
132 if s.Val != 1 && s.Val != 0 {
133 return ConnectionError(ErrCodeProtocol)
134 }
135 case SettingInitialWindowSize:
136 if s.Val > 1<<31-1 {
137 return ConnectionError(ErrCodeFlowControl)
138 }
139 case SettingMaxFrameSize:
140 if s.Val < 16384 || s.Val > 1<<24-1 {
141 return ConnectionError(ErrCodeProtocol)
142 }
143 }
144 return nil
145}
146
147// A SettingID is an HTTP/2 setting as defined in
148// http://http2.github.io/http2-spec/#iana-settings
149type SettingID uint16
150
151const (
152 SettingHeaderTableSize SettingID = 0x1
153 SettingEnablePush SettingID = 0x2
154 SettingMaxConcurrentStreams SettingID = 0x3
155 SettingInitialWindowSize SettingID = 0x4
156 SettingMaxFrameSize SettingID = 0x5
157 SettingMaxHeaderListSize SettingID = 0x6
158)
159
160var settingName = map[SettingID]string{
161 SettingHeaderTableSize: "HEADER_TABLE_SIZE",
162 SettingEnablePush: "ENABLE_PUSH",
163 SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
164 SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
165 SettingMaxFrameSize: "MAX_FRAME_SIZE",
166 SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
167}
168
169func (s SettingID) String() string {
170 if v, ok := settingName[s]; ok {
171 return v
172 }
173 return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
174}
175
176var (
177 errInvalidHeaderFieldName = errors.New("http2: invalid header field name")
178 errInvalidHeaderFieldValue = errors.New("http2: invalid header field value")
179)
180
181// validWireHeaderFieldName reports whether v is a valid header field
182// name (key). See httplex.ValidHeaderName for the base rules.
183//
184// Further, http2 says:
185// "Just as in HTTP/1.x, header field names are strings of ASCII
186// characters that are compared in a case-insensitive
187// fashion. However, header field names MUST be converted to
188// lowercase prior to their encoding in HTTP/2. "
189func validWireHeaderFieldName(v string) bool {
190 if len(v) == 0 {
191 return false
192 }
193 for _, r := range v {
194 if !httplex.IsTokenRune(r) {
195 return false
196 }
197 if 'A' <= r && r <= 'Z' {
198 return false
199 }
200 }
201 return true
202}
203
204var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n)
205
206func init() {
207 for i := 100; i <= 999; i++ {
208 if v := http.StatusText(i); v != "" {
209 httpCodeStringCommon[i] = strconv.Itoa(i)
210 }
211 }
212}
213
214func httpCodeString(code int) string {
215 if s, ok := httpCodeStringCommon[code]; ok {
216 return s
217 }
218 return strconv.Itoa(code)
219}
220
221// from pkg io
222type stringWriter interface {
223 WriteString(s string) (n int, err error)
224}
225
226// A gate lets two goroutines coordinate their activities.
227type gate chan struct{}
228
229func (g gate) Done() { g <- struct{}{} }
230func (g gate) Wait() { <-g }
231
232// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
233type closeWaiter chan struct{}
234
235// Init makes a closeWaiter usable.
236// It exists because so a closeWaiter value can be placed inside a
237// larger struct and have the Mutex and Cond's memory in the same
238// allocation.
239func (cw *closeWaiter) Init() {
240 *cw = make(chan struct{})
241}
242
243// Close marks the closeWaiter as closed and unblocks any waiters.
244func (cw closeWaiter) Close() {
245 close(cw)
246}
247
248// Wait waits for the closeWaiter to become closed.
249func (cw closeWaiter) Wait() {
250 <-cw
251}
252
253// bufferedWriter is a buffered writer that writes to w.
254// Its buffered writer is lazily allocated as needed, to minimize
255// idle memory usage with many connections.
256type bufferedWriter struct {
257 w io.Writer // immutable
258 bw *bufio.Writer // non-nil when data is buffered
259}
260
261func newBufferedWriter(w io.Writer) *bufferedWriter {
262 return &bufferedWriter{w: w}
263}
264
265// bufWriterPoolBufferSize is the size of bufio.Writer's
266// buffers created using bufWriterPool.
267//
268// TODO: pick a less arbitrary value? this is a bit under
269// (3 x typical 1500 byte MTU) at least. Other than that,
270// not much thought went into it.
271const bufWriterPoolBufferSize = 4 << 10
272
273var bufWriterPool = sync.Pool{
274 New: func() interface{} {
275 return bufio.NewWriterSize(nil, bufWriterPoolBufferSize)
276 },
277}
278
279func (w *bufferedWriter) Available() int {
280 if w.bw == nil {
281 return bufWriterPoolBufferSize
282 }
283 return w.bw.Available()
284}
285
286func (w *bufferedWriter) Write(p []byte) (n int, err error) {
287 if w.bw == nil {
288 bw := bufWriterPool.Get().(*bufio.Writer)
289 bw.Reset(w.w)
290 w.bw = bw
291 }
292 return w.bw.Write(p)
293}
294
295func (w *bufferedWriter) Flush() error {
296 bw := w.bw
297 if bw == nil {
298 return nil
299 }
300 err := bw.Flush()
301 bw.Reset(nil)
302 bufWriterPool.Put(bw)
303 w.bw = nil
304 return err
305}
306
307func mustUint31(v int32) uint32 {
308 if v < 0 || v > 2147483647 {
309 panic("out of range")
310 }
311 return uint32(v)
312}
313
314// bodyAllowedForStatus reports whether a given response status code
315// permits a body. See RFC 2616, section 4.4.
316func bodyAllowedForStatus(status int) bool {
317 switch {
318 case status >= 100 && status <= 199:
319 return false
320 case status == 204:
321 return false
322 case status == 304:
323 return false
324 }
325 return true
326}
327
328type httpError struct {
329 msg string
330 timeout bool
331}
332
333func (e *httpError) Error() string { return e.msg }
334func (e *httpError) Timeout() bool { return e.timeout }
335func (e *httpError) Temporary() bool { return true }
336
337var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true}
338
339type connectionStater interface {
340 ConnectionState() tls.ConnectionState
341}
342
343var sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}
344
345type sorter struct {
346 v []string // owned by sorter
347}
348
349func (s *sorter) Len() int { return len(s.v) }
350func (s *sorter) Swap(i, j int) { s.v[i], s.v[j] = s.v[j], s.v[i] }
351func (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }
352
353// Keys returns the sorted keys of h.
354//
355// The returned slice is only valid until s used again or returned to
356// its pool.
357func (s *sorter) Keys(h http.Header) []string {
358 keys := s.v[:0]
359 for k := range h {
360 keys = append(keys, k)
361 }
362 s.v = keys
363 sort.Sort(s)
364 return keys
365}
366
367func (s *sorter) SortStrings(ss []string) {
368 // Our sorter works on s.v, which sorter owns, so
369 // stash it away while we sort the user's buffer.
370 save := s.v
371 s.v = ss
372 sort.Sort(s)
373 s.v = save
374}
375
376// validPseudoPath reports whether v is a valid :path pseudo-header
377// value. It must be either:
378//
379// *) a non-empty string starting with '/'
380// *) the string '*', for OPTIONS requests.
381//
382// For now this is only used a quick check for deciding when to clean
383// up Opaque URLs before sending requests from the Transport.
384// See golang.org/issue/16847
385//
386// We used to enforce that the path also didn't start with "//", but
387// Google's GFE accepts such paths and Chrome sends them, so ignore
388// that part of the spec. See golang.org/issue/19103.
389func validPseudoPath(v string) bool {
390 return (len(v) > 0 && v[0] == '/') || v == "*"
391}
diff --git a/vendor/golang.org/x/net/http2/not_go16.go b/vendor/golang.org/x/net/http2/not_go16.go
new file mode 100644
index 0000000..508cebc
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/not_go16.go
@@ -0,0 +1,21 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build !go1.6
6
7package http2
8
9import (
10 "net/http"
11 "time"
12)
13
14func configureTransport(t1 *http.Transport) (*Transport, error) {
15 return nil, errTransportVersion
16}
17
18func transportExpectContinueTimeout(t1 *http.Transport) time.Duration {
19 return 0
20
21}
diff --git a/vendor/golang.org/x/net/http2/not_go17.go b/vendor/golang.org/x/net/http2/not_go17.go
new file mode 100644
index 0000000..140434a
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/not_go17.go
@@ -0,0 +1,87 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build !go1.7
6
7package http2
8
9import (
10 "crypto/tls"
11 "net"
12 "net/http"
13 "time"
14)
15
16type contextContext interface {
17 Done() <-chan struct{}
18 Err() error
19}
20
21type fakeContext struct{}
22
23func (fakeContext) Done() <-chan struct{} { return nil }
24func (fakeContext) Err() error { panic("should not be called") }
25
26func reqContext(r *http.Request) fakeContext {
27 return fakeContext{}
28}
29
30func setResponseUncompressed(res *http.Response) {
31 // Nothing.
32}
33
34type clientTrace struct{}
35
36func requestTrace(*http.Request) *clientTrace { return nil }
37func traceGotConn(*http.Request, *ClientConn) {}
38func traceFirstResponseByte(*clientTrace) {}
39func traceWroteHeaders(*clientTrace) {}
40func traceWroteRequest(*clientTrace, error) {}
41func traceGot100Continue(trace *clientTrace) {}
42func traceWait100Continue(trace *clientTrace) {}
43
44func nop() {}
45
46func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) {
47 return nil, nop
48}
49
50func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) {
51 return ctx, nop
52}
53
54func requestWithContext(req *http.Request, ctx contextContext) *http.Request {
55 return req
56}
57
58// temporary copy of Go 1.6's private tls.Config.clone:
59func cloneTLSConfig(c *tls.Config) *tls.Config {
60 return &tls.Config{
61 Rand: c.Rand,
62 Time: c.Time,
63 Certificates: c.Certificates,
64 NameToCertificate: c.NameToCertificate,
65 GetCertificate: c.GetCertificate,
66 RootCAs: c.RootCAs,
67 NextProtos: c.NextProtos,
68 ServerName: c.ServerName,
69 ClientAuth: c.ClientAuth,
70 ClientCAs: c.ClientCAs,
71 InsecureSkipVerify: c.InsecureSkipVerify,
72 CipherSuites: c.CipherSuites,
73 PreferServerCipherSuites: c.PreferServerCipherSuites,
74 SessionTicketsDisabled: c.SessionTicketsDisabled,
75 SessionTicketKey: c.SessionTicketKey,
76 ClientSessionCache: c.ClientSessionCache,
77 MinVersion: c.MinVersion,
78 MaxVersion: c.MaxVersion,
79 CurvePreferences: c.CurvePreferences,
80 }
81}
82
83func (cc *ClientConn) Ping(ctx contextContext) error {
84 return cc.ping(ctx)
85}
86
87func (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
new file mode 100644
index 0000000..6f8d3f8
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/not_go18.go
@@ -0,0 +1,29 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build !go1.8
6
7package http2
8
9import (
10 "io"
11 "net/http"
12)
13
14func configureServer18(h1 *http.Server, h2 *Server) error {
15 // No IdleTimeout to sync prior to Go 1.8.
16 return nil
17}
18
19func shouldLogPanic(panicValue interface{}) bool {
20 return panicValue != nil
21}
22
23func reqGetBody(req *http.Request) func() (io.ReadCloser, error) {
24 return nil
25}
26
27func reqBodyIsNoBody(io.ReadCloser) bool { return false }
28
29func 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
new file mode 100644
index 0000000..5ae0772
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/not_go19.go
@@ -0,0 +1,16 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build !go1.9
6
7package http2
8
9import (
10 "net/http"
11)
12
13func configureServer19(s *http.Server, conf *Server) error {
14 // not supported prior to go1.9
15 return nil
16}
diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go
new file mode 100644
index 0000000..a614009
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/pipe.go
@@ -0,0 +1,163 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import (
8 "errors"
9 "io"
10 "sync"
11)
12
13// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like
14// io.Pipe except there are no PipeReader/PipeWriter halves, and the
15// underlying buffer is an interface. (io.Pipe is always unbuffered)
16type pipe struct {
17 mu sync.Mutex
18 c sync.Cond // c.L lazily initialized to &p.mu
19 b pipeBuffer // nil when done reading
20 err error // read error once empty. non-nil means closed.
21 breakErr error // immediate read error (caller doesn't see rest of b)
22 donec chan struct{} // closed on error
23 readFn func() // optional code to run in Read before error
24}
25
26type pipeBuffer interface {
27 Len() int
28 io.Writer
29 io.Reader
30}
31
32func (p *pipe) Len() int {
33 p.mu.Lock()
34 defer p.mu.Unlock()
35 if p.b == nil {
36 return 0
37 }
38 return p.b.Len()
39}
40
41// Read waits until data is available and copies bytes
42// from the buffer into p.
43func (p *pipe) Read(d []byte) (n int, err error) {
44 p.mu.Lock()
45 defer p.mu.Unlock()
46 if p.c.L == nil {
47 p.c.L = &p.mu
48 }
49 for {
50 if p.breakErr != nil {
51 return 0, p.breakErr
52 }
53 if p.b != nil && p.b.Len() > 0 {
54 return p.b.Read(d)
55 }
56 if p.err != nil {
57 if p.readFn != nil {
58 p.readFn() // e.g. copy trailers
59 p.readFn = nil // not sticky like p.err
60 }
61 p.b = nil
62 return 0, p.err
63 }
64 p.c.Wait()
65 }
66}
67
68var errClosedPipeWrite = errors.New("write on closed buffer")
69
70// Write copies bytes from p into the buffer and wakes a reader.
71// It is an error to write more data than the buffer can hold.
72func (p *pipe) Write(d []byte) (n int, err error) {
73 p.mu.Lock()
74 defer p.mu.Unlock()
75 if p.c.L == nil {
76 p.c.L = &p.mu
77 }
78 defer p.c.Signal()
79 if p.err != nil {
80 return 0, errClosedPipeWrite
81 }
82 if p.breakErr != nil {
83 return len(d), nil // discard when there is no reader
84 }
85 return p.b.Write(d)
86}
87
88// CloseWithError causes the next Read (waking up a current blocked
89// Read if needed) to return the provided err after all data has been
90// read.
91//
92// The error must be non-nil.
93func (p *pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }
94
95// BreakWithError causes the next Read (waking up a current blocked
96// Read if needed) to return the provided err immediately, without
97// waiting for unread data.
98func (p *pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }
99
100// closeWithErrorAndCode is like CloseWithError but also sets some code to run
101// in the caller's goroutine before returning the error.
102func (p *pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) }
103
104func (p *pipe) closeWithError(dst *error, err error, fn func()) {
105 if err == nil {
106 panic("err must be non-nil")
107 }
108 p.mu.Lock()
109 defer p.mu.Unlock()
110 if p.c.L == nil {
111 p.c.L = &p.mu
112 }
113 defer p.c.Signal()
114 if *dst != nil {
115 // Already been done.
116 return
117 }
118 p.readFn = fn
119 if dst == &p.breakErr {
120 p.b = nil
121 }
122 *dst = err
123 p.closeDoneLocked()
124}
125
126// requires p.mu be held.
127func (p *pipe) closeDoneLocked() {
128 if p.donec == nil {
129 return
130 }
131 // Close if unclosed. This isn't racy since we always
132 // hold p.mu while closing.
133 select {
134 case <-p.donec:
135 default:
136 close(p.donec)
137 }
138}
139
140// Err returns the error (if any) first set by BreakWithError or CloseWithError.
141func (p *pipe) Err() error {
142 p.mu.Lock()
143 defer p.mu.Unlock()
144 if p.breakErr != nil {
145 return p.breakErr
146 }
147 return p.err
148}
149
150// Done returns a channel which is closed if and when this pipe is closed
151// with CloseWithError.
152func (p *pipe) Done() <-chan struct{} {
153 p.mu.Lock()
154 defer p.mu.Unlock()
155 if p.donec == nil {
156 p.donec = make(chan struct{})
157 if p.err != nil || p.breakErr != nil {
158 // Already hit an error.
159 p.closeDoneLocked()
160 }
161 }
162 return p.donec
163}
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
new file mode 100644
index 0000000..eae143d
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -0,0 +1,2857 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// TODO: turn off the serve goroutine when idle, so
6// an idle conn only has the readFrames goroutine active. (which could
7// also be optimized probably to pin less memory in crypto/tls). This
8// would involve tracking when the serve goroutine is active (atomic
9// int32 read/CAS probably?) and starting it up when frames arrive,
10// and shutting it down when all handlers exit. the occasional PING
11// packets could use time.AfterFunc to call sc.wakeStartServeLoop()
12// (which is a no-op if already running) and then queue the PING write
13// as normal. The serve loop would then exit in most cases (if no
14// Handlers running) and not be woken up again until the PING packet
15// returns.
16
17// TODO (maybe): add a mechanism for Handlers to going into
18// half-closed-local mode (rw.(io.Closer) test?) but not exit their
19// handler, and continue to be able to read from the
20// Request.Body. This would be a somewhat semantic change from HTTP/1
21// (or at least what we expose in net/http), so I'd probably want to
22// add it there too. For now, this package says that returning from
23// the Handler ServeHTTP function means you're both done reading and
24// done writing, without a way to stop just one or the other.
25
26package http2
27
28import (
29 "bufio"
30 "bytes"
31 "crypto/tls"
32 "errors"
33 "fmt"
34 "io"
35 "log"
36 "math"
37 "net"
38 "net/http"
39 "net/textproto"
40 "net/url"
41 "os"
42 "reflect"
43 "runtime"
44 "strconv"
45 "strings"
46 "sync"
47 "time"
48
49 "golang.org/x/net/http2/hpack"
50)
51
52const (
53 prefaceTimeout = 10 * time.Second
54 firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
55 handlerChunkWriteSize = 4 << 10
56 defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
57)
58
59var (
60 errClientDisconnected = errors.New("client disconnected")
61 errClosedBody = errors.New("body closed by handler")
62 errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
63 errStreamClosed = errors.New("http2: stream closed")
64)
65
66var responseWriterStatePool = sync.Pool{
67 New: func() interface{} {
68 rws := &responseWriterState{}
69 rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)
70 return rws
71 },
72}
73
74// Test hooks.
75var (
76 testHookOnConn func()
77 testHookGetServerConn func(*serverConn)
78 testHookOnPanicMu *sync.Mutex // nil except in tests
79 testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
80)
81
82// Server is an HTTP/2 server.
83type Server struct {
84 // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
85 // which may run at a time over all connections.
86 // Negative or zero no limit.
87 // TODO: implement
88 MaxHandlers int
89
90 // MaxConcurrentStreams optionally specifies the number of
91 // concurrent streams that each client may have open at a
92 // time. This is unrelated to the number of http.Handler goroutines
93 // which may be active globally, which is MaxHandlers.
94 // If zero, MaxConcurrentStreams defaults to at least 100, per
95 // the HTTP/2 spec's recommendations.
96 MaxConcurrentStreams uint32
97
98 // MaxReadFrameSize optionally specifies the largest frame
99 // this server is willing to read. A valid value is between
100 // 16k and 16M, inclusive. If zero or otherwise invalid, a
101 // default value is used.
102 MaxReadFrameSize uint32
103
104 // PermitProhibitedCipherSuites, if true, permits the use of
105 // cipher suites prohibited by the HTTP/2 spec.
106 PermitProhibitedCipherSuites bool
107
108 // IdleTimeout specifies how long until idle clients should be
109 // closed with a GOAWAY frame. PING frames are not considered
110 // activity for the purposes of IdleTimeout.
111 IdleTimeout time.Duration
112
113 // MaxUploadBufferPerConnection is the size of the initial flow
114 // control window for each connections. The HTTP/2 spec does not
115 // allow this to be smaller than 65535 or larger than 2^32-1.
116 // If the value is outside this range, a default value will be
117 // used instead.
118 MaxUploadBufferPerConnection int32
119
120 // MaxUploadBufferPerStream is the size of the initial flow control
121 // window for each stream. The HTTP/2 spec does not allow this to
122 // be larger than 2^32-1. If the value is zero or larger than the
123 // maximum, a default value will be used instead.
124 MaxUploadBufferPerStream int32
125
126 // NewWriteScheduler constructs a write scheduler for a connection.
127 // If nil, a default scheduler is chosen.
128 NewWriteScheduler func() WriteScheduler
129
130 // Internal state. This is a pointer (rather than embedded directly)
131 // so that we don't embed a Mutex in this struct, which will make the
132 // struct non-copyable, which might break some callers.
133 state *serverInternalState
134}
135
136func (s *Server) initialConnRecvWindowSize() int32 {
137 if s.MaxUploadBufferPerConnection > initialWindowSize {
138 return s.MaxUploadBufferPerConnection
139 }
140 return 1 << 20
141}
142
143func (s *Server) initialStreamRecvWindowSize() int32 {
144 if s.MaxUploadBufferPerStream > 0 {
145 return s.MaxUploadBufferPerStream
146 }
147 return 1 << 20
148}
149
150func (s *Server) maxReadFrameSize() uint32 {
151 if v := s.MaxReadFrameSize; v >= minMaxFrameSize && v <= maxFrameSize {
152 return v
153 }
154 return defaultMaxReadFrameSize
155}
156
157func (s *Server) maxConcurrentStreams() uint32 {
158 if v := s.MaxConcurrentStreams; v > 0 {
159 return v
160 }
161 return defaultMaxStreams
162}
163
164type serverInternalState struct {
165 mu sync.Mutex
166 activeConns map[*serverConn]struct{}
167}
168
169func (s *serverInternalState) registerConn(sc *serverConn) {
170 if s == nil {
171 return // if the Server was used without calling ConfigureServer
172 }
173 s.mu.Lock()
174 s.activeConns[sc] = struct{}{}
175 s.mu.Unlock()
176}
177
178func (s *serverInternalState) unregisterConn(sc *serverConn) {
179 if s == nil {
180 return // if the Server was used without calling ConfigureServer
181 }
182 s.mu.Lock()
183 delete(s.activeConns, sc)
184 s.mu.Unlock()
185}
186
187func (s *serverInternalState) startGracefulShutdown() {
188 if s == nil {
189 return // if the Server was used without calling ConfigureServer
190 }
191 s.mu.Lock()
192 for sc := range s.activeConns {
193 sc.startGracefulShutdown()
194 }
195 s.mu.Unlock()
196}
197
198// ConfigureServer adds HTTP/2 support to a net/http Server.
199//
200// The configuration conf may be nil.
201//
202// ConfigureServer must be called before s begins serving.
203func ConfigureServer(s *http.Server, conf *Server) error {
204 if s == nil {
205 panic("nil *http.Server")
206 }
207 if conf == nil {
208 conf = new(Server)
209 }
210 conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
211 if err := configureServer18(s, conf); err != nil {
212 return err
213 }
214 if err := configureServer19(s, conf); err != nil {
215 return err
216 }
217
218 if s.TLSConfig == nil {
219 s.TLSConfig = new(tls.Config)
220 } else if s.TLSConfig.CipherSuites != nil {
221 // If they already provided a CipherSuite list, return
222 // an error if it has a bad order or is missing
223 // ECDHE_RSA_WITH_AES_128_GCM_SHA256.
224 const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
225 haveRequired := false
226 sawBad := false
227 for i, cs := range s.TLSConfig.CipherSuites {
228 if cs == requiredCipher {
229 haveRequired = true
230 }
231 if isBadCipher(cs) {
232 sawBad = true
233 } else if sawBad {
234 return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
235 }
236 }
237 if !haveRequired {
238 return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
239 }
240 }
241
242 // Note: not setting MinVersion to tls.VersionTLS12,
243 // as we don't want to interfere with HTTP/1.1 traffic
244 // on the user's server. We enforce TLS 1.2 later once
245 // we accept a connection. Ideally this should be done
246 // during next-proto selection, but using TLS <1.2 with
247 // HTTP/2 is still the client's bug.
248
249 s.TLSConfig.PreferServerCipherSuites = true
250
251 haveNPN := false
252 for _, p := range s.TLSConfig.NextProtos {
253 if p == NextProtoTLS {
254 haveNPN = true
255 break
256 }
257 }
258 if !haveNPN {
259 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
260 }
261
262 if s.TLSNextProto == nil {
263 s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
264 }
265 protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {
266 if testHookOnConn != nil {
267 testHookOnConn()
268 }
269 conf.ServeConn(c, &ServeConnOpts{
270 Handler: h,
271 BaseConfig: hs,
272 })
273 }
274 s.TLSNextProto[NextProtoTLS] = protoHandler
275 return nil
276}
277
278// ServeConnOpts are options for the Server.ServeConn method.
279type ServeConnOpts struct {
280 // BaseConfig optionally sets the base configuration
281 // for values. If nil, defaults are used.
282 BaseConfig *http.Server
283
284 // Handler specifies which handler to use for processing
285 // requests. If nil, BaseConfig.Handler is used. If BaseConfig
286 // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
287 Handler http.Handler
288}
289
290func (o *ServeConnOpts) baseConfig() *http.Server {
291 if o != nil && o.BaseConfig != nil {
292 return o.BaseConfig
293 }
294 return new(http.Server)
295}
296
297func (o *ServeConnOpts) handler() http.Handler {
298 if o != nil {
299 if o.Handler != nil {
300 return o.Handler
301 }
302 if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
303 return o.BaseConfig.Handler
304 }
305 }
306 return http.DefaultServeMux
307}
308
309// ServeConn serves HTTP/2 requests on the provided connection and
310// blocks until the connection is no longer readable.
311//
312// ServeConn starts speaking HTTP/2 assuming that c has not had any
313// reads or writes. It writes its initial settings frame and expects
314// to be able to read the preface and settings frame from the
315// client. If c has a ConnectionState method like a *tls.Conn, the
316// ConnectionState is used to verify the TLS ciphersuite and to set
317// the Request.TLS field in Handlers.
318//
319// ServeConn does not support h2c by itself. Any h2c support must be
320// implemented in terms of providing a suitably-behaving net.Conn.
321//
322// The opts parameter is optional. If nil, default values are used.
323func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
324 baseCtx, cancel := serverConnBaseContext(c, opts)
325 defer cancel()
326
327 sc := &serverConn{
328 srv: s,
329 hs: opts.baseConfig(),
330 conn: c,
331 baseCtx: baseCtx,
332 remoteAddrStr: c.RemoteAddr().String(),
333 bw: newBufferedWriter(c),
334 handler: opts.handler(),
335 streams: make(map[uint32]*stream),
336 readFrameCh: make(chan readFrameResult),
337 wantWriteFrameCh: make(chan FrameWriteRequest, 8),
338 serveMsgCh: make(chan interface{}, 8),
339 wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
340 bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way
341 doneServing: make(chan struct{}),
342 clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
343 advMaxStreams: s.maxConcurrentStreams(),
344 initialStreamSendWindowSize: initialWindowSize,
345 maxFrameSize: initialMaxFrameSize,
346 headerTableSize: initialHeaderTableSize,
347 serveG: newGoroutineLock(),
348 pushEnabled: true,
349 }
350
351 s.state.registerConn(sc)
352 defer s.state.unregisterConn(sc)
353
354 // The net/http package sets the write deadline from the
355 // http.Server.WriteTimeout during the TLS handshake, but then
356 // passes the connection off to us with the deadline already set.
357 // Write deadlines are set per stream in serverConn.newStream.
358 // Disarm the net.Conn write deadline here.
359 if sc.hs.WriteTimeout != 0 {
360 sc.conn.SetWriteDeadline(time.Time{})
361 }
362
363 if s.NewWriteScheduler != nil {
364 sc.writeSched = s.NewWriteScheduler()
365 } else {
366 sc.writeSched = NewRandomWriteScheduler()
367 }
368
369 // These start at the RFC-specified defaults. If there is a higher
370 // configured value for inflow, that will be updated when we send a
371 // WINDOW_UPDATE shortly after sending SETTINGS.
372 sc.flow.add(initialWindowSize)
373 sc.inflow.add(initialWindowSize)
374 sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
375
376 fr := NewFramer(sc.bw, c)
377 fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
378 fr.MaxHeaderListSize = sc.maxHeaderListSize()
379 fr.SetMaxReadFrameSize(s.maxReadFrameSize())
380 sc.framer = fr
381
382 if tc, ok := c.(connectionStater); ok {
383 sc.tlsState = new(tls.ConnectionState)
384 *sc.tlsState = tc.ConnectionState()
385 // 9.2 Use of TLS Features
386 // An implementation of HTTP/2 over TLS MUST use TLS
387 // 1.2 or higher with the restrictions on feature set
388 // and cipher suite described in this section. Due to
389 // implementation limitations, it might not be
390 // possible to fail TLS negotiation. An endpoint MUST
391 // immediately terminate an HTTP/2 connection that
392 // does not meet the TLS requirements described in
393 // this section with a connection error (Section
394 // 5.4.1) of type INADEQUATE_SECURITY.
395 if sc.tlsState.Version < tls.VersionTLS12 {
396 sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low")
397 return
398 }
399
400 if sc.tlsState.ServerName == "" {
401 // Client must use SNI, but we don't enforce that anymore,
402 // since it was causing problems when connecting to bare IP
403 // addresses during development.
404 //
405 // TODO: optionally enforce? Or enforce at the time we receive
406 // a new request, and verify the the ServerName matches the :authority?
407 // But that precludes proxy situations, perhaps.
408 //
409 // So for now, do nothing here again.
410 }
411
412 if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
413 // "Endpoints MAY choose to generate a connection error
414 // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
415 // the prohibited cipher suites are negotiated."
416 //
417 // We choose that. In my opinion, the spec is weak
418 // here. It also says both parties must support at least
419 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
420 // excuses here. If we really must, we could allow an
421 // "AllowInsecureWeakCiphers" option on the server later.
422 // Let's see how it plays out first.
423 sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
424 return
425 }
426 }
427
428 if hook := testHookGetServerConn; hook != nil {
429 hook(sc)
430 }
431 sc.serve()
432}
433
434func (sc *serverConn) rejectConn(err ErrCode, debug string) {
435 sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
436 // ignoring errors. hanging up anyway.
437 sc.framer.WriteGoAway(0, err, []byte(debug))
438 sc.bw.Flush()
439 sc.conn.Close()
440}
441
442type serverConn struct {
443 // Immutable:
444 srv *Server
445 hs *http.Server
446 conn net.Conn
447 bw *bufferedWriter // writing to conn
448 handler http.Handler
449 baseCtx contextContext
450 framer *Framer
451 doneServing chan struct{} // closed when serverConn.serve ends
452 readFrameCh chan readFrameResult // written by serverConn.readFrames
453 wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve
454 wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
455 bodyReadCh chan bodyReadMsg // from handlers -> serve
456 serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop
457 flow flow // conn-wide (not stream-specific) outbound flow control
458 inflow flow // conn-wide inbound flow control
459 tlsState *tls.ConnectionState // shared by all handlers, like net/http
460 remoteAddrStr string
461 writeSched WriteScheduler
462
463 // Everything following is owned by the serve loop; use serveG.check():
464 serveG goroutineLock // used to verify funcs are on serve()
465 pushEnabled bool
466 sawFirstSettings bool // got the initial SETTINGS frame after the preface
467 needToSendSettingsAck bool
468 unackedSettings int // how many SETTINGS have we sent without ACKs?
469 clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
470 advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
471 curClientStreams uint32 // number of open streams initiated by the client
472 curPushedStreams uint32 // number of open streams initiated by server push
473 maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests
474 maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes
475 streams map[uint32]*stream
476 initialStreamSendWindowSize int32
477 maxFrameSize int32
478 headerTableSize uint32
479 peerMaxHeaderListSize uint32 // zero means unknown (default)
480 canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
481 writingFrame bool // started writing a frame (on serve goroutine or separate)
482 writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
483 needsFrameFlush bool // last frame write wasn't a flush
484 inGoAway bool // we've started to or sent GOAWAY
485 inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop
486 needToSendGoAway bool // we need to schedule a GOAWAY frame write
487 goAwayCode ErrCode
488 shutdownTimer *time.Timer // nil until used
489 idleTimer *time.Timer // nil if unused
490
491 // Owned by the writeFrameAsync goroutine:
492 headerWriteBuf bytes.Buffer
493 hpackEncoder *hpack.Encoder
494
495 // Used by startGracefulShutdown.
496 shutdownOnce sync.Once
497}
498
499func (sc *serverConn) maxHeaderListSize() uint32 {
500 n := sc.hs.MaxHeaderBytes
501 if n <= 0 {
502 n = http.DefaultMaxHeaderBytes
503 }
504 // http2's count is in a slightly different unit and includes 32 bytes per pair.
505 // So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
506 const perFieldOverhead = 32 // per http2 spec
507 const typicalHeaders = 10 // conservative
508 return uint32(n + typicalHeaders*perFieldOverhead)
509}
510
511func (sc *serverConn) curOpenStreams() uint32 {
512 sc.serveG.check()
513 return sc.curClientStreams + sc.curPushedStreams
514}
515
516// stream represents a stream. This is the minimal metadata needed by
517// the serve goroutine. Most of the actual stream state is owned by
518// the http.Handler's goroutine in the responseWriter. Because the
519// responseWriter's responseWriterState is recycled at the end of a
520// handler, this struct intentionally has no pointer to the
521// *responseWriter{,State} itself, as the Handler ending nils out the
522// responseWriter's state field.
523type stream struct {
524 // immutable:
525 sc *serverConn
526 id uint32
527 body *pipe // non-nil if expecting DATA frames
528 cw closeWaiter // closed wait stream transitions to closed state
529 ctx contextContext
530 cancelCtx func()
531
532 // owned by serverConn's serve loop:
533 bodyBytes int64 // body bytes seen so far
534 declBodyBytes int64 // or -1 if undeclared
535 flow flow // limits writing from Handler to client
536 inflow flow // what the client is allowed to POST/etc to us
537 parent *stream // or nil
538 numTrailerValues int64
539 weight uint8
540 state streamState
541 resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
542 gotTrailerHeader bool // HEADER frame for trailers was seen
543 wroteHeaders bool // whether we wrote headers (not status 100)
544 writeDeadline *time.Timer // nil if unused
545
546 trailer http.Header // accumulated trailers
547 reqTrailer http.Header // handler's Request.Trailer
548}
549
550func (sc *serverConn) Framer() *Framer { return sc.framer }
551func (sc *serverConn) CloseConn() error { return sc.conn.Close() }
552func (sc *serverConn) Flush() error { return sc.bw.Flush() }
553func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
554 return sc.hpackEncoder, &sc.headerWriteBuf
555}
556
557func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
558 sc.serveG.check()
559 // http://tools.ietf.org/html/rfc7540#section-5.1
560 if st, ok := sc.streams[streamID]; ok {
561 return st.state, st
562 }
563 // "The first use of a new stream identifier implicitly closes all
564 // streams in the "idle" state that might have been initiated by
565 // that peer with a lower-valued stream identifier. For example, if
566 // a client sends a HEADERS frame on stream 7 without ever sending a
567 // frame on stream 5, then stream 5 transitions to the "closed"
568 // state when the first frame for stream 7 is sent or received."
569 if streamID%2 == 1 {
570 if streamID <= sc.maxClientStreamID {
571 return stateClosed, nil
572 }
573 } else {
574 if streamID <= sc.maxPushPromiseID {
575 return stateClosed, nil
576 }
577 }
578 return stateIdle, nil
579}
580
581// setConnState calls the net/http ConnState hook for this connection, if configured.
582// Note that the net/http package does StateNew and StateClosed for us.
583// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
584func (sc *serverConn) setConnState(state http.ConnState) {
585 if sc.hs.ConnState != nil {
586 sc.hs.ConnState(sc.conn, state)
587 }
588}
589
590func (sc *serverConn) vlogf(format string, args ...interface{}) {
591 if VerboseLogs {
592 sc.logf(format, args...)
593 }
594}
595
596func (sc *serverConn) logf(format string, args ...interface{}) {
597 if lg := sc.hs.ErrorLog; lg != nil {
598 lg.Printf(format, args...)
599 } else {
600 log.Printf(format, args...)
601 }
602}
603
604// errno returns v's underlying uintptr, else 0.
605//
606// TODO: remove this helper function once http2 can use build
607// tags. See comment in isClosedConnError.
608func errno(v error) uintptr {
609 if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
610 return uintptr(rv.Uint())
611 }
612 return 0
613}
614
615// isClosedConnError reports whether err is an error from use of a closed
616// network connection.
617func isClosedConnError(err error) bool {
618 if err == nil {
619 return false
620 }
621
622 // TODO: remove this string search and be more like the Windows
623 // case below. That might involve modifying the standard library
624 // to return better error types.
625 str := err.Error()
626 if strings.Contains(str, "use of closed network connection") {
627 return true
628 }
629
630 // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
631 // build tags, so I can't make an http2_windows.go file with
632 // Windows-specific stuff. Fix that and move this, once we
633 // have a way to bundle this into std's net/http somehow.
634 if runtime.GOOS == "windows" {
635 if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
636 if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
637 const WSAECONNABORTED = 10053
638 const WSAECONNRESET = 10054
639 if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
640 return true
641 }
642 }
643 }
644 }
645 return false
646}
647
648func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
649 if err == nil {
650 return
651 }
652 if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) {
653 // Boring, expected errors.
654 sc.vlogf(format, args...)
655 } else {
656 sc.logf(format, args...)
657 }
658}
659
660func (sc *serverConn) canonicalHeader(v string) string {
661 sc.serveG.check()
662 cv, ok := commonCanonHeader[v]
663 if ok {
664 return cv
665 }
666 cv, ok = sc.canonHeader[v]
667 if ok {
668 return cv
669 }
670 if sc.canonHeader == nil {
671 sc.canonHeader = make(map[string]string)
672 }
673 cv = http.CanonicalHeaderKey(v)
674 sc.canonHeader[v] = cv
675 return cv
676}
677
678type readFrameResult struct {
679 f Frame // valid until readMore is called
680 err error
681
682 // readMore should be called once the consumer no longer needs or
683 // retains f. After readMore, f is invalid and more frames can be
684 // read.
685 readMore func()
686}
687
688// readFrames is the loop that reads incoming frames.
689// It takes care to only read one frame at a time, blocking until the
690// consumer is done with the frame.
691// It's run on its own goroutine.
692func (sc *serverConn) readFrames() {
693 gate := make(gate)
694 gateDone := gate.Done
695 for {
696 f, err := sc.framer.ReadFrame()
697 select {
698 case sc.readFrameCh <- readFrameResult{f, err, gateDone}:
699 case <-sc.doneServing:
700 return
701 }
702 select {
703 case <-gate:
704 case <-sc.doneServing:
705 return
706 }
707 if terminalReadFrameError(err) {
708 return
709 }
710 }
711}
712
713// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
714type frameWriteResult struct {
715 wr FrameWriteRequest // what was written (or attempted)
716 err error // result of the writeFrame call
717}
718
719// writeFrameAsync runs in its own goroutine and writes a single frame
720// and then reports when it's done.
721// At most one goroutine can be running writeFrameAsync at a time per
722// serverConn.
723func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest) {
724 err := wr.write.writeFrame(sc)
725 sc.wroteFrameCh <- frameWriteResult{wr, err}
726}
727
728func (sc *serverConn) closeAllStreamsOnConnClose() {
729 sc.serveG.check()
730 for _, st := range sc.streams {
731 sc.closeStream(st, errClientDisconnected)
732 }
733}
734
735func (sc *serverConn) stopShutdownTimer() {
736 sc.serveG.check()
737 if t := sc.shutdownTimer; t != nil {
738 t.Stop()
739 }
740}
741
742func (sc *serverConn) notePanic() {
743 // Note: this is for serverConn.serve panicking, not http.Handler code.
744 if testHookOnPanicMu != nil {
745 testHookOnPanicMu.Lock()
746 defer testHookOnPanicMu.Unlock()
747 }
748 if testHookOnPanic != nil {
749 if e := recover(); e != nil {
750 if testHookOnPanic(sc, e) {
751 panic(e)
752 }
753 }
754 }
755}
756
757func (sc *serverConn) serve() {
758 sc.serveG.check()
759 defer sc.notePanic()
760 defer sc.conn.Close()
761 defer sc.closeAllStreamsOnConnClose()
762 defer sc.stopShutdownTimer()
763 defer close(sc.doneServing) // unblocks handlers trying to send
764
765 if VerboseLogs {
766 sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
767 }
768
769 sc.writeFrame(FrameWriteRequest{
770 write: writeSettings{
771 {SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
772 {SettingMaxConcurrentStreams, sc.advMaxStreams},
773 {SettingMaxHeaderListSize, sc.maxHeaderListSize()},
774 {SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
775 },
776 })
777 sc.unackedSettings++
778
779 // Each connection starts with intialWindowSize inflow tokens.
780 // If a higher value is configured, we add more tokens.
781 if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 {
782 sc.sendWindowUpdate(nil, int(diff))
783 }
784
785 if err := sc.readPreface(); err != nil {
786 sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
787 return
788 }
789 // Now that we've got the preface, get us out of the
790 // "StateNew" state. We can't go directly to idle, though.
791 // Active means we read some data and anticipate a request. We'll
792 // do another Active when we get a HEADERS frame.
793 sc.setConnState(http.StateActive)
794 sc.setConnState(http.StateIdle)
795
796 if sc.srv.IdleTimeout != 0 {
797 sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
798 defer sc.idleTimer.Stop()
799 }
800
801 go sc.readFrames() // closed by defer sc.conn.Close above
802
803 settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer)
804 defer settingsTimer.Stop()
805
806 loopNum := 0
807 for {
808 loopNum++
809 select {
810 case wr := <-sc.wantWriteFrameCh:
811 if se, ok := wr.write.(StreamError); ok {
812 sc.resetStream(se)
813 break
814 }
815 sc.writeFrame(wr)
816 case res := <-sc.wroteFrameCh:
817 sc.wroteFrame(res)
818 case res := <-sc.readFrameCh:
819 if !sc.processFrameFromReader(res) {
820 return
821 }
822 res.readMore()
823 if settingsTimer != nil {
824 settingsTimer.Stop()
825 settingsTimer = nil
826 }
827 case m := <-sc.bodyReadCh:
828 sc.noteBodyRead(m.st, m.n)
829 case msg := <-sc.serveMsgCh:
830 switch v := msg.(type) {
831 case func(int):
832 v(loopNum) // for testing
833 case *serverMessage:
834 switch v {
835 case settingsTimerMsg:
836 sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
837 return
838 case idleTimerMsg:
839 sc.vlogf("connection is idle")
840 sc.goAway(ErrCodeNo)
841 case shutdownTimerMsg:
842 sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
843 return
844 case gracefulShutdownMsg:
845 sc.startGracefulShutdownInternal()
846 default:
847 panic("unknown timer")
848 }
849 case *startPushRequest:
850 sc.startPush(v)
851 default:
852 panic(fmt.Sprintf("unexpected type %T", v))
853 }
854 }
855
856 if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame {
857 return
858 }
859 }
860}
861
862func (sc *serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) {
863 select {
864 case <-sc.doneServing:
865 case <-sharedCh:
866 close(privateCh)
867 }
868}
869
870type serverMessage int
871
872// Message values sent to serveMsgCh.
873var (
874 settingsTimerMsg = new(serverMessage)
875 idleTimerMsg = new(serverMessage)
876 shutdownTimerMsg = new(serverMessage)
877 gracefulShutdownMsg = new(serverMessage)
878)
879
880func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) }
881func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) }
882func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) }
883
884func (sc *serverConn) sendServeMsg(msg interface{}) {
885 sc.serveG.checkNotOn() // NOT
886 select {
887 case sc.serveMsgCh <- msg:
888 case <-sc.doneServing:
889 }
890}
891
892// readPreface reads the ClientPreface greeting from the peer
893// or returns an error on timeout or an invalid greeting.
894func (sc *serverConn) readPreface() error {
895 errc := make(chan error, 1)
896 go func() {
897 // Read the client preface
898 buf := make([]byte, len(ClientPreface))
899 if _, err := io.ReadFull(sc.conn, buf); err != nil {
900 errc <- err
901 } else if !bytes.Equal(buf, clientPreface) {
902 errc <- fmt.Errorf("bogus greeting %q", buf)
903 } else {
904 errc <- nil
905 }
906 }()
907 timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
908 defer timer.Stop()
909 select {
910 case <-timer.C:
911 return errors.New("timeout waiting for client preface")
912 case err := <-errc:
913 if err == nil {
914 if VerboseLogs {
915 sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
916 }
917 }
918 return err
919 }
920}
921
922var errChanPool = sync.Pool{
923 New: func() interface{} { return make(chan error, 1) },
924}
925
926var writeDataPool = sync.Pool{
927 New: func() interface{} { return new(writeData) },
928}
929
930// writeDataFromHandler writes DATA response frames from a handler on
931// the given stream.
932func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
933 ch := errChanPool.Get().(chan error)
934 writeArg := writeDataPool.Get().(*writeData)
935 *writeArg = writeData{stream.id, data, endStream}
936 err := sc.writeFrameFromHandler(FrameWriteRequest{
937 write: writeArg,
938 stream: stream,
939 done: ch,
940 })
941 if err != nil {
942 return err
943 }
944 var frameWriteDone bool // the frame write is done (successfully or not)
945 select {
946 case err = <-ch:
947 frameWriteDone = true
948 case <-sc.doneServing:
949 return errClientDisconnected
950 case <-stream.cw:
951 // If both ch and stream.cw were ready (as might
952 // happen on the final Write after an http.Handler
953 // ends), prefer the write result. Otherwise this
954 // might just be us successfully closing the stream.
955 // The writeFrameAsync and serve goroutines guarantee
956 // that the ch send will happen before the stream.cw
957 // close.
958 select {
959 case err = <-ch:
960 frameWriteDone = true
961 default:
962 return errStreamClosed
963 }
964 }
965 errChanPool.Put(ch)
966 if frameWriteDone {
967 writeDataPool.Put(writeArg)
968 }
969 return err
970}
971
972// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
973// if the connection has gone away.
974//
975// This must not be run from the serve goroutine itself, else it might
976// deadlock writing to sc.wantWriteFrameCh (which is only mildly
977// buffered and is read by serve itself). If you're on the serve
978// goroutine, call writeFrame instead.
979func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error {
980 sc.serveG.checkNotOn() // NOT
981 select {
982 case sc.wantWriteFrameCh <- wr:
983 return nil
984 case <-sc.doneServing:
985 // Serve loop is gone.
986 // Client has closed their connection to the server.
987 return errClientDisconnected
988 }
989}
990
991// writeFrame schedules a frame to write and sends it if there's nothing
992// already being written.
993//
994// There is no pushback here (the serve goroutine never blocks). It's
995// the http.Handlers that block, waiting for their previous frames to
996// make it onto the wire
997//
998// If you're not on the serve goroutine, use writeFrameFromHandler instead.
999func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
1000 sc.serveG.check()
1001
1002 // If true, wr will not be written and wr.done will not be signaled.
1003 var ignoreWrite bool
1004
1005 // We are not allowed to write frames on closed streams. RFC 7540 Section
1006 // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
1007 // a closed stream." Our server never sends PRIORITY, so that exception
1008 // does not apply.
1009 //
1010 // The serverConn might close an open stream while the stream's handler
1011 // is still running. For example, the server might close a stream when it
1012 // receives bad data from the client. If this happens, the handler might
1013 // attempt to write a frame after the stream has been closed (since the
1014 // handler hasn't yet been notified of the close). In this case, we simply
1015 // ignore the frame. The handler will notice that the stream is closed when
1016 // it waits for the frame to be written.
1017 //
1018 // As an exception to this rule, we allow sending RST_STREAM after close.
1019 // This allows us to immediately reject new streams without tracking any
1020 // state for those streams (except for the queued RST_STREAM frame). This
1021 // may result in duplicate RST_STREAMs in some cases, but the client should
1022 // ignore those.
1023 if wr.StreamID() != 0 {
1024 _, isReset := wr.write.(StreamError)
1025 if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset {
1026 ignoreWrite = true
1027 }
1028 }
1029
1030 // Don't send a 100-continue response if we've already sent headers.
1031 // See golang.org/issue/14030.
1032 switch wr.write.(type) {
1033 case *writeResHeaders:
1034 wr.stream.wroteHeaders = true
1035 case write100ContinueHeadersFrame:
1036 if wr.stream.wroteHeaders {
1037 // We do not need to notify wr.done because this frame is
1038 // never written with wr.done != nil.
1039 if wr.done != nil {
1040 panic("wr.done != nil for write100ContinueHeadersFrame")
1041 }
1042 ignoreWrite = true
1043 }
1044 }
1045
1046 if !ignoreWrite {
1047 sc.writeSched.Push(wr)
1048 }
1049 sc.scheduleFrameWrite()
1050}
1051
1052// startFrameWrite starts a goroutine to write wr (in a separate
1053// goroutine since that might block on the network), and updates the
1054// serve goroutine's state about the world, updated from info in wr.
1055func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
1056 sc.serveG.check()
1057 if sc.writingFrame {
1058 panic("internal error: can only be writing one frame at a time")
1059 }
1060
1061 st := wr.stream
1062 if st != nil {
1063 switch st.state {
1064 case stateHalfClosedLocal:
1065 switch wr.write.(type) {
1066 case StreamError, handlerPanicRST, writeWindowUpdate:
1067 // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
1068 // in this state. (We never send PRIORITY from the server, so that is not checked.)
1069 default:
1070 panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
1071 }
1072 case stateClosed:
1073 panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
1074 }
1075 }
1076 if wpp, ok := wr.write.(*writePushPromise); ok {
1077 var err error
1078 wpp.promisedID, err = wpp.allocatePromisedID()
1079 if err != nil {
1080 sc.writingFrameAsync = false
1081 wr.replyToWriter(err)
1082 return
1083 }
1084 }
1085
1086 sc.writingFrame = true
1087 sc.needsFrameFlush = true
1088 if wr.write.staysWithinBuffer(sc.bw.Available()) {
1089 sc.writingFrameAsync = false
1090 err := wr.write.writeFrame(sc)
1091 sc.wroteFrame(frameWriteResult{wr, err})
1092 } else {
1093 sc.writingFrameAsync = true
1094 go sc.writeFrameAsync(wr)
1095 }
1096}
1097
1098// errHandlerPanicked is the error given to any callers blocked in a read from
1099// Request.Body when the main goroutine panics. Since most handlers read in the
1100// the main ServeHTTP goroutine, this will show up rarely.
1101var errHandlerPanicked = errors.New("http2: handler panicked")
1102
1103// wroteFrame is called on the serve goroutine with the result of
1104// whatever happened on writeFrameAsync.
1105func (sc *serverConn) wroteFrame(res frameWriteResult) {
1106 sc.serveG.check()
1107 if !sc.writingFrame {
1108 panic("internal error: expected to be already writing a frame")
1109 }
1110 sc.writingFrame = false
1111 sc.writingFrameAsync = false
1112
1113 wr := res.wr
1114
1115 if writeEndsStream(wr.write) {
1116 st := wr.stream
1117 if st == nil {
1118 panic("internal error: expecting non-nil stream")
1119 }
1120 switch st.state {
1121 case stateOpen:
1122 // Here we would go to stateHalfClosedLocal in
1123 // theory, but since our handler is done and
1124 // the net/http package provides no mechanism
1125 // for closing a ResponseWriter while still
1126 // reading data (see possible TODO at top of
1127 // this file), we go into closed state here
1128 // anyway, after telling the peer we're
1129 // hanging up on them. We'll transition to
1130 // stateClosed after the RST_STREAM frame is
1131 // written.
1132 st.state = stateHalfClosedLocal
1133 // Section 8.1: a server MAY request that the client abort
1134 // transmission of a request without error by sending a
1135 // RST_STREAM with an error code of NO_ERROR after sending
1136 // a complete response.
1137 sc.resetStream(streamError(st.id, ErrCodeNo))
1138 case stateHalfClosedRemote:
1139 sc.closeStream(st, errHandlerComplete)
1140 }
1141 } else {
1142 switch v := wr.write.(type) {
1143 case StreamError:
1144 // st may be unknown if the RST_STREAM was generated to reject bad input.
1145 if st, ok := sc.streams[v.StreamID]; ok {
1146 sc.closeStream(st, v)
1147 }
1148 case handlerPanicRST:
1149 sc.closeStream(wr.stream, errHandlerPanicked)
1150 }
1151 }
1152
1153 // Reply (if requested) to unblock the ServeHTTP goroutine.
1154 wr.replyToWriter(res.err)
1155
1156 sc.scheduleFrameWrite()
1157}
1158
1159// scheduleFrameWrite tickles the frame writing scheduler.
1160//
1161// If a frame is already being written, nothing happens. This will be called again
1162// when the frame is done being written.
1163//
1164// If a frame isn't being written we need to send one, the best frame
1165// to send is selected, preferring first things that aren't
1166// stream-specific (e.g. ACKing settings), and then finding the
1167// highest priority stream.
1168//
1169// If a frame isn't being written and there's nothing else to send, we
1170// flush the write buffer.
1171func (sc *serverConn) scheduleFrameWrite() {
1172 sc.serveG.check()
1173 if sc.writingFrame || sc.inFrameScheduleLoop {
1174 return
1175 }
1176 sc.inFrameScheduleLoop = true
1177 for !sc.writingFrameAsync {
1178 if sc.needToSendGoAway {
1179 sc.needToSendGoAway = false
1180 sc.startFrameWrite(FrameWriteRequest{
1181 write: &writeGoAway{
1182 maxStreamID: sc.maxClientStreamID,
1183 code: sc.goAwayCode,
1184 },
1185 })
1186 continue
1187 }
1188 if sc.needToSendSettingsAck {
1189 sc.needToSendSettingsAck = false
1190 sc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}})
1191 continue
1192 }
1193 if !sc.inGoAway || sc.goAwayCode == ErrCodeNo {
1194 if wr, ok := sc.writeSched.Pop(); ok {
1195 sc.startFrameWrite(wr)
1196 continue
1197 }
1198 }
1199 if sc.needsFrameFlush {
1200 sc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}})
1201 sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
1202 continue
1203 }
1204 break
1205 }
1206 sc.inFrameScheduleLoop = false
1207}
1208
1209// startGracefulShutdown gracefully shuts down a connection. This
1210// sends GOAWAY with ErrCodeNo to tell the client we're gracefully
1211// shutting down. The connection isn't closed until all current
1212// streams are done.
1213//
1214// startGracefulShutdown returns immediately; it does not wait until
1215// the connection has shut down.
1216func (sc *serverConn) startGracefulShutdown() {
1217 sc.serveG.checkNotOn() // NOT
1218 sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
1219}
1220
1221func (sc *serverConn) startGracefulShutdownInternal() {
1222 sc.goAwayIn(ErrCodeNo, 0)
1223}
1224
1225func (sc *serverConn) goAway(code ErrCode) {
1226 sc.serveG.check()
1227 var forceCloseIn time.Duration
1228 if code != ErrCodeNo {
1229 forceCloseIn = 250 * time.Millisecond
1230 } else {
1231 // TODO: configurable
1232 forceCloseIn = 1 * time.Second
1233 }
1234 sc.goAwayIn(code, forceCloseIn)
1235}
1236
1237func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) {
1238 sc.serveG.check()
1239 if sc.inGoAway {
1240 return
1241 }
1242 if forceCloseIn != 0 {
1243 sc.shutDownIn(forceCloseIn)
1244 }
1245 sc.inGoAway = true
1246 sc.needToSendGoAway = true
1247 sc.goAwayCode = code
1248 sc.scheduleFrameWrite()
1249}
1250
1251func (sc *serverConn) shutDownIn(d time.Duration) {
1252 sc.serveG.check()
1253 sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
1254}
1255
1256func (sc *serverConn) resetStream(se StreamError) {
1257 sc.serveG.check()
1258 sc.writeFrame(FrameWriteRequest{write: se})
1259 if st, ok := sc.streams[se.StreamID]; ok {
1260 st.resetQueued = true
1261 }
1262}
1263
1264// processFrameFromReader processes the serve loop's read from readFrameCh from the
1265// frame-reading goroutine.
1266// processFrameFromReader returns whether the connection should be kept open.
1267func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
1268 sc.serveG.check()
1269 err := res.err
1270 if err != nil {
1271 if err == ErrFrameTooLarge {
1272 sc.goAway(ErrCodeFrameSize)
1273 return true // goAway will close the loop
1274 }
1275 clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)
1276 if clientGone {
1277 // TODO: could we also get into this state if
1278 // the peer does a half close
1279 // (e.g. CloseWrite) because they're done
1280 // sending frames but they're still wanting
1281 // our open replies? Investigate.
1282 // TODO: add CloseWrite to crypto/tls.Conn first
1283 // so we have a way to test this? I suppose
1284 // just for testing we could have a non-TLS mode.
1285 return false
1286 }
1287 } else {
1288 f := res.f
1289 if VerboseLogs {
1290 sc.vlogf("http2: server read frame %v", summarizeFrame(f))
1291 }
1292 err = sc.processFrame(f)
1293 if err == nil {
1294 return true
1295 }
1296 }
1297
1298 switch ev := err.(type) {
1299 case StreamError:
1300 sc.resetStream(ev)
1301 return true
1302 case goAwayFlowError:
1303 sc.goAway(ErrCodeFlowControl)
1304 return true
1305 case ConnectionError:
1306 sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
1307 sc.goAway(ErrCode(ev))
1308 return true // goAway will handle shutdown
1309 default:
1310 if res.err != nil {
1311 sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
1312 } else {
1313 sc.logf("http2: server closing client connection: %v", err)
1314 }
1315 return false
1316 }
1317}
1318
1319func (sc *serverConn) processFrame(f Frame) error {
1320 sc.serveG.check()
1321
1322 // First frame received must be SETTINGS.
1323 if !sc.sawFirstSettings {
1324 if _, ok := f.(*SettingsFrame); !ok {
1325 return ConnectionError(ErrCodeProtocol)
1326 }
1327 sc.sawFirstSettings = true
1328 }
1329
1330 switch f := f.(type) {
1331 case *SettingsFrame:
1332 return sc.processSettings(f)
1333 case *MetaHeadersFrame:
1334 return sc.processHeaders(f)
1335 case *WindowUpdateFrame:
1336 return sc.processWindowUpdate(f)
1337 case *PingFrame:
1338 return sc.processPing(f)
1339 case *DataFrame:
1340 return sc.processData(f)
1341 case *RSTStreamFrame:
1342 return sc.processResetStream(f)
1343 case *PriorityFrame:
1344 return sc.processPriority(f)
1345 case *GoAwayFrame:
1346 return sc.processGoAway(f)
1347 case *PushPromiseFrame:
1348 // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
1349 // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1350 return ConnectionError(ErrCodeProtocol)
1351 default:
1352 sc.vlogf("http2: server ignoring frame: %v", f.Header())
1353 return nil
1354 }
1355}
1356
1357func (sc *serverConn) processPing(f *PingFrame) error {
1358 sc.serveG.check()
1359 if f.IsAck() {
1360 // 6.7 PING: " An endpoint MUST NOT respond to PING frames
1361 // containing this flag."
1362 return nil
1363 }
1364 if f.StreamID != 0 {
1365 // "PING frames are not associated with any individual
1366 // stream. If a PING frame is received with a stream
1367 // identifier field value other than 0x0, the recipient MUST
1368 // respond with a connection error (Section 5.4.1) of type
1369 // PROTOCOL_ERROR."
1370 return ConnectionError(ErrCodeProtocol)
1371 }
1372 if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
1373 return nil
1374 }
1375 sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
1376 return nil
1377}
1378
1379func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
1380 sc.serveG.check()
1381 switch {
1382 case f.StreamID != 0: // stream-level flow control
1383 state, st := sc.state(f.StreamID)
1384 if state == stateIdle {
1385 // Section 5.1: "Receiving any frame other than HEADERS
1386 // or PRIORITY on a stream in this state MUST be
1387 // treated as a connection error (Section 5.4.1) of
1388 // type PROTOCOL_ERROR."
1389 return ConnectionError(ErrCodeProtocol)
1390 }
1391 if st == nil {
1392 // "WINDOW_UPDATE can be sent by a peer that has sent a
1393 // frame bearing the END_STREAM flag. This means that a
1394 // receiver could receive a WINDOW_UPDATE frame on a "half
1395 // closed (remote)" or "closed" stream. A receiver MUST
1396 // NOT treat this as an error, see Section 5.1."
1397 return nil
1398 }
1399 if !st.flow.add(int32(f.Increment)) {
1400 return streamError(f.StreamID, ErrCodeFlowControl)
1401 }
1402 default: // connection-level flow control
1403 if !sc.flow.add(int32(f.Increment)) {
1404 return goAwayFlowError{}
1405 }
1406 }
1407 sc.scheduleFrameWrite()
1408 return nil
1409}
1410
1411func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
1412 sc.serveG.check()
1413
1414 state, st := sc.state(f.StreamID)
1415 if state == stateIdle {
1416 // 6.4 "RST_STREAM frames MUST NOT be sent for a
1417 // stream in the "idle" state. If a RST_STREAM frame
1418 // identifying an idle stream is received, the
1419 // recipient MUST treat this as a connection error
1420 // (Section 5.4.1) of type PROTOCOL_ERROR.
1421 return ConnectionError(ErrCodeProtocol)
1422 }
1423 if st != nil {
1424 st.cancelCtx()
1425 sc.closeStream(st, streamError(f.StreamID, f.ErrCode))
1426 }
1427 return nil
1428}
1429
1430func (sc *serverConn) closeStream(st *stream, err error) {
1431 sc.serveG.check()
1432 if st.state == stateIdle || st.state == stateClosed {
1433 panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
1434 }
1435 st.state = stateClosed
1436 if st.writeDeadline != nil {
1437 st.writeDeadline.Stop()
1438 }
1439 if st.isPushed() {
1440 sc.curPushedStreams--
1441 } else {
1442 sc.curClientStreams--
1443 }
1444 delete(sc.streams, st.id)
1445 if len(sc.streams) == 0 {
1446 sc.setConnState(http.StateIdle)
1447 if sc.srv.IdleTimeout != 0 {
1448 sc.idleTimer.Reset(sc.srv.IdleTimeout)
1449 }
1450 if h1ServerKeepAlivesDisabled(sc.hs) {
1451 sc.startGracefulShutdownInternal()
1452 }
1453 }
1454 if p := st.body; p != nil {
1455 // Return any buffered unread bytes worth of conn-level flow control.
1456 // See golang.org/issue/16481
1457 sc.sendWindowUpdate(nil, p.Len())
1458
1459 p.CloseWithError(err)
1460 }
1461 st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
1462 sc.writeSched.CloseStream(st.id)
1463}
1464
1465func (sc *serverConn) processSettings(f *SettingsFrame) error {
1466 sc.serveG.check()
1467 if f.IsAck() {
1468 sc.unackedSettings--
1469 if sc.unackedSettings < 0 {
1470 // Why is the peer ACKing settings we never sent?
1471 // The spec doesn't mention this case, but
1472 // hang up on them anyway.
1473 return ConnectionError(ErrCodeProtocol)
1474 }
1475 return nil
1476 }
1477 if err := f.ForeachSetting(sc.processSetting); err != nil {
1478 return err
1479 }
1480 sc.needToSendSettingsAck = true
1481 sc.scheduleFrameWrite()
1482 return nil
1483}
1484
1485func (sc *serverConn) processSetting(s Setting) error {
1486 sc.serveG.check()
1487 if err := s.Valid(); err != nil {
1488 return err
1489 }
1490 if VerboseLogs {
1491 sc.vlogf("http2: server processing setting %v", s)
1492 }
1493 switch s.ID {
1494 case SettingHeaderTableSize:
1495 sc.headerTableSize = s.Val
1496 sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
1497 case SettingEnablePush:
1498 sc.pushEnabled = s.Val != 0
1499 case SettingMaxConcurrentStreams:
1500 sc.clientMaxStreams = s.Val
1501 case SettingInitialWindowSize:
1502 return sc.processSettingInitialWindowSize(s.Val)
1503 case SettingMaxFrameSize:
1504 sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
1505 case SettingMaxHeaderListSize:
1506 sc.peerMaxHeaderListSize = s.Val
1507 default:
1508 // Unknown setting: "An endpoint that receives a SETTINGS
1509 // frame with any unknown or unsupported identifier MUST
1510 // ignore that setting."
1511 if VerboseLogs {
1512 sc.vlogf("http2: server ignoring unknown setting %v", s)
1513 }
1514 }
1515 return nil
1516}
1517
1518func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
1519 sc.serveG.check()
1520 // Note: val already validated to be within range by
1521 // processSetting's Valid call.
1522
1523 // "A SETTINGS frame can alter the initial flow control window
1524 // size for all current streams. When the value of
1525 // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
1526 // adjust the size of all stream flow control windows that it
1527 // maintains by the difference between the new value and the
1528 // old value."
1529 old := sc.initialStreamSendWindowSize
1530 sc.initialStreamSendWindowSize = int32(val)
1531 growth := int32(val) - old // may be negative
1532 for _, st := range sc.streams {
1533 if !st.flow.add(growth) {
1534 // 6.9.2 Initial Flow Control Window Size
1535 // "An endpoint MUST treat a change to
1536 // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
1537 // control window to exceed the maximum size as a
1538 // connection error (Section 5.4.1) of type
1539 // FLOW_CONTROL_ERROR."
1540 return ConnectionError(ErrCodeFlowControl)
1541 }
1542 }
1543 return nil
1544}
1545
1546func (sc *serverConn) processData(f *DataFrame) error {
1547 sc.serveG.check()
1548 if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
1549 return nil
1550 }
1551 data := f.Data()
1552
1553 // "If a DATA frame is received whose stream is not in "open"
1554 // or "half closed (local)" state, the recipient MUST respond
1555 // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
1556 id := f.Header().StreamID
1557 state, st := sc.state(id)
1558 if id == 0 || state == stateIdle {
1559 // Section 5.1: "Receiving any frame other than HEADERS
1560 // or PRIORITY on a stream in this state MUST be
1561 // treated as a connection error (Section 5.4.1) of
1562 // type PROTOCOL_ERROR."
1563 return ConnectionError(ErrCodeProtocol)
1564 }
1565 if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
1566 // This includes sending a RST_STREAM if the stream is
1567 // in stateHalfClosedLocal (which currently means that
1568 // the http.Handler returned, so it's done reading &
1569 // done writing). Try to stop the client from sending
1570 // more DATA.
1571
1572 // But still enforce their connection-level flow control,
1573 // and return any flow control bytes since we're not going
1574 // to consume them.
1575 if sc.inflow.available() < int32(f.Length) {
1576 return streamError(id, ErrCodeFlowControl)
1577 }
1578 // Deduct the flow control from inflow, since we're
1579 // going to immediately add it back in
1580 // sendWindowUpdate, which also schedules sending the
1581 // frames.
1582 sc.inflow.take(int32(f.Length))
1583 sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
1584
1585 if st != nil && st.resetQueued {
1586 // Already have a stream error in flight. Don't send another.
1587 return nil
1588 }
1589 return streamError(id, ErrCodeStreamClosed)
1590 }
1591 if st.body == nil {
1592 panic("internal error: should have a body in this state")
1593 }
1594
1595 // Sender sending more than they'd declared?
1596 if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
1597 st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
1598 return streamError(id, ErrCodeStreamClosed)
1599 }
1600 if f.Length > 0 {
1601 // Check whether the client has flow control quota.
1602 if st.inflow.available() < int32(f.Length) {
1603 return streamError(id, ErrCodeFlowControl)
1604 }
1605 st.inflow.take(int32(f.Length))
1606
1607 if len(data) > 0 {
1608 wrote, err := st.body.Write(data)
1609 if err != nil {
1610 return streamError(id, ErrCodeStreamClosed)
1611 }
1612 if wrote != len(data) {
1613 panic("internal error: bad Writer")
1614 }
1615 st.bodyBytes += int64(len(data))
1616 }
1617
1618 // Return any padded flow control now, since we won't
1619 // refund it later on body reads.
1620 if pad := int32(f.Length) - int32(len(data)); pad > 0 {
1621 sc.sendWindowUpdate32(nil, pad)
1622 sc.sendWindowUpdate32(st, pad)
1623 }
1624 }
1625 if f.StreamEnded() {
1626 st.endStream()
1627 }
1628 return nil
1629}
1630
1631func (sc *serverConn) processGoAway(f *GoAwayFrame) error {
1632 sc.serveG.check()
1633 if f.ErrCode != ErrCodeNo {
1634 sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
1635 } else {
1636 sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
1637 }
1638 sc.startGracefulShutdownInternal()
1639 // http://tools.ietf.org/html/rfc7540#section-6.8
1640 // We should not create any new streams, which means we should disable push.
1641 sc.pushEnabled = false
1642 return nil
1643}
1644
1645// isPushed reports whether the stream is server-initiated.
1646func (st *stream) isPushed() bool {
1647 return st.id%2 == 0
1648}
1649
1650// endStream closes a Request.Body's pipe. It is called when a DATA
1651// frame says a request body is over (or after trailers).
1652func (st *stream) endStream() {
1653 sc := st.sc
1654 sc.serveG.check()
1655
1656 if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
1657 st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
1658 st.declBodyBytes, st.bodyBytes))
1659 } else {
1660 st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
1661 st.body.CloseWithError(io.EOF)
1662 }
1663 st.state = stateHalfClosedRemote
1664}
1665
1666// copyTrailersToHandlerRequest is run in the Handler's goroutine in
1667// its Request.Body.Read just before it gets io.EOF.
1668func (st *stream) copyTrailersToHandlerRequest() {
1669 for k, vv := range st.trailer {
1670 if _, ok := st.reqTrailer[k]; ok {
1671 // Only copy it over it was pre-declared.
1672 st.reqTrailer[k] = vv
1673 }
1674 }
1675}
1676
1677// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
1678// when the stream's WriteTimeout has fired.
1679func (st *stream) onWriteTimeout() {
1680 st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)})
1681}
1682
1683func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
1684 sc.serveG.check()
1685 id := f.StreamID
1686 if sc.inGoAway {
1687 // Ignore.
1688 return nil
1689 }
1690 // http://tools.ietf.org/html/rfc7540#section-5.1.1
1691 // Streams initiated by a client MUST use odd-numbered stream
1692 // identifiers. [...] An endpoint that receives an unexpected
1693 // stream identifier MUST respond with a connection error
1694 // (Section 5.4.1) of type PROTOCOL_ERROR.
1695 if id%2 != 1 {
1696 return ConnectionError(ErrCodeProtocol)
1697 }
1698 // A HEADERS frame can be used to create a new stream or
1699 // send a trailer for an open one. If we already have a stream
1700 // open, let it process its own HEADERS frame (trailers at this
1701 // point, if it's valid).
1702 if st := sc.streams[f.StreamID]; st != nil {
1703 if st.resetQueued {
1704 // We're sending RST_STREAM to close the stream, so don't bother
1705 // processing this frame.
1706 return nil
1707 }
1708 return st.processTrailerHeaders(f)
1709 }
1710
1711 // [...] The identifier of a newly established stream MUST be
1712 // numerically greater than all streams that the initiating
1713 // endpoint has opened or reserved. [...] An endpoint that
1714 // receives an unexpected stream identifier MUST respond with
1715 // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1716 if id <= sc.maxClientStreamID {
1717 return ConnectionError(ErrCodeProtocol)
1718 }
1719 sc.maxClientStreamID = id
1720
1721 if sc.idleTimer != nil {
1722 sc.idleTimer.Stop()
1723 }
1724
1725 // http://tools.ietf.org/html/rfc7540#section-5.1.2
1726 // [...] Endpoints MUST NOT exceed the limit set by their peer. An
1727 // endpoint that receives a HEADERS frame that causes their
1728 // advertised concurrent stream limit to be exceeded MUST treat
1729 // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
1730 // or REFUSED_STREAM.
1731 if sc.curClientStreams+1 > sc.advMaxStreams {
1732 if sc.unackedSettings == 0 {
1733 // They should know better.
1734 return streamError(id, ErrCodeProtocol)
1735 }
1736 // Assume it's a network race, where they just haven't
1737 // received our last SETTINGS update. But actually
1738 // this can't happen yet, because we don't yet provide
1739 // a way for users to adjust server parameters at
1740 // runtime.
1741 return streamError(id, ErrCodeRefusedStream)
1742 }
1743
1744 initialState := stateOpen
1745 if f.StreamEnded() {
1746 initialState = stateHalfClosedRemote
1747 }
1748 st := sc.newStream(id, 0, initialState)
1749
1750 if f.HasPriority() {
1751 if err := checkPriority(f.StreamID, f.Priority); err != nil {
1752 return err
1753 }
1754 sc.writeSched.AdjustStream(st.id, f.Priority)
1755 }
1756
1757 rw, req, err := sc.newWriterAndRequest(st, f)
1758 if err != nil {
1759 return err
1760 }
1761 st.reqTrailer = req.Trailer
1762 if st.reqTrailer != nil {
1763 st.trailer = make(http.Header)
1764 }
1765 st.body = req.Body.(*requestBody).pipe // may be nil
1766 st.declBodyBytes = req.ContentLength
1767
1768 handler := sc.handler.ServeHTTP
1769 if f.Truncated {
1770 // Their header list was too long. Send a 431 error.
1771 handler = handleHeaderListTooLong
1772 } else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil {
1773 handler = new400Handler(err)
1774 }
1775
1776 // The net/http package sets the read deadline from the
1777 // http.Server.ReadTimeout during the TLS handshake, but then
1778 // passes the connection off to us with the deadline already
1779 // set. Disarm it here after the request headers are read,
1780 // similar to how the http1 server works. Here it's
1781 // technically more like the http1 Server's ReadHeaderTimeout
1782 // (in Go 1.8), though. That's a more sane option anyway.
1783 if sc.hs.ReadTimeout != 0 {
1784 sc.conn.SetReadDeadline(time.Time{})
1785 }
1786
1787 go sc.runHandler(rw, req, handler)
1788 return nil
1789}
1790
1791func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
1792 sc := st.sc
1793 sc.serveG.check()
1794 if st.gotTrailerHeader {
1795 return ConnectionError(ErrCodeProtocol)
1796 }
1797 st.gotTrailerHeader = true
1798 if !f.StreamEnded() {
1799 return streamError(st.id, ErrCodeProtocol)
1800 }
1801
1802 if len(f.PseudoFields()) > 0 {
1803 return streamError(st.id, ErrCodeProtocol)
1804 }
1805 if st.trailer != nil {
1806 for _, hf := range f.RegularFields() {
1807 key := sc.canonicalHeader(hf.Name)
1808 if !ValidTrailerHeader(key) {
1809 // TODO: send more details to the peer somehow. But http2 has
1810 // no way to send debug data at a stream level. Discuss with
1811 // HTTP folk.
1812 return streamError(st.id, ErrCodeProtocol)
1813 }
1814 st.trailer[key] = append(st.trailer[key], hf.Value)
1815 }
1816 }
1817 st.endStream()
1818 return nil
1819}
1820
1821func checkPriority(streamID uint32, p PriorityParam) error {
1822 if streamID == p.StreamDep {
1823 // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
1824 // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
1825 // Section 5.3.3 says that a stream can depend on one of its dependencies,
1826 // so it's only self-dependencies that are forbidden.
1827 return streamError(streamID, ErrCodeProtocol)
1828 }
1829 return nil
1830}
1831
1832func (sc *serverConn) processPriority(f *PriorityFrame) error {
1833 if sc.inGoAway {
1834 return nil
1835 }
1836 if err := checkPriority(f.StreamID, f.PriorityParam); err != nil {
1837 return err
1838 }
1839 sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
1840 return nil
1841}
1842
1843func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream {
1844 sc.serveG.check()
1845 if id == 0 {
1846 panic("internal error: cannot create stream with id 0")
1847 }
1848
1849 ctx, cancelCtx := contextWithCancel(sc.baseCtx)
1850 st := &stream{
1851 sc: sc,
1852 id: id,
1853 state: state,
1854 ctx: ctx,
1855 cancelCtx: cancelCtx,
1856 }
1857 st.cw.Init()
1858 st.flow.conn = &sc.flow // link to conn-level counter
1859 st.flow.add(sc.initialStreamSendWindowSize)
1860 st.inflow.conn = &sc.inflow // link to conn-level counter
1861 st.inflow.add(sc.srv.initialStreamRecvWindowSize())
1862 if sc.hs.WriteTimeout != 0 {
1863 st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
1864 }
1865
1866 sc.streams[id] = st
1867 sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID})
1868 if st.isPushed() {
1869 sc.curPushedStreams++
1870 } else {
1871 sc.curClientStreams++
1872 }
1873 if sc.curOpenStreams() == 1 {
1874 sc.setConnState(http.StateActive)
1875 }
1876
1877 return st
1878}
1879
1880func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
1881 sc.serveG.check()
1882
1883 rp := requestParam{
1884 method: f.PseudoValue("method"),
1885 scheme: f.PseudoValue("scheme"),
1886 authority: f.PseudoValue("authority"),
1887 path: f.PseudoValue("path"),
1888 }
1889
1890 isConnect := rp.method == "CONNECT"
1891 if isConnect {
1892 if rp.path != "" || rp.scheme != "" || rp.authority == "" {
1893 return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
1894 }
1895 } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
1896 // See 8.1.2.6 Malformed Requests and Responses:
1897 //
1898 // Malformed requests or responses that are detected
1899 // MUST be treated as a stream error (Section 5.4.2)
1900 // of type PROTOCOL_ERROR."
1901 //
1902 // 8.1.2.3 Request Pseudo-Header Fields
1903 // "All HTTP/2 requests MUST include exactly one valid
1904 // value for the :method, :scheme, and :path
1905 // pseudo-header fields"
1906 return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
1907 }
1908
1909 bodyOpen := !f.StreamEnded()
1910 if rp.method == "HEAD" && bodyOpen {
1911 // HEAD requests can't have bodies
1912 return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
1913 }
1914
1915 rp.header = make(http.Header)
1916 for _, hf := range f.RegularFields() {
1917 rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
1918 }
1919 if rp.authority == "" {
1920 rp.authority = rp.header.Get("Host")
1921 }
1922
1923 rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
1924 if err != nil {
1925 return nil, nil, err
1926 }
1927 if bodyOpen {
1928 if vv, ok := rp.header["Content-Length"]; ok {
1929 req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
1930 } else {
1931 req.ContentLength = -1
1932 }
1933 req.Body.(*requestBody).pipe = &pipe{
1934 b: &dataBuffer{expected: req.ContentLength},
1935 }
1936 }
1937 return rw, req, nil
1938}
1939
1940type requestParam struct {
1941 method string
1942 scheme, authority, path string
1943 header http.Header
1944}
1945
1946func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) {
1947 sc.serveG.check()
1948
1949 var tlsState *tls.ConnectionState // nil if not scheme https
1950 if rp.scheme == "https" {
1951 tlsState = sc.tlsState
1952 }
1953
1954 needsContinue := rp.header.Get("Expect") == "100-continue"
1955 if needsContinue {
1956 rp.header.Del("Expect")
1957 }
1958 // Merge Cookie headers into one "; "-delimited value.
1959 if cookies := rp.header["Cookie"]; len(cookies) > 1 {
1960 rp.header.Set("Cookie", strings.Join(cookies, "; "))
1961 }
1962
1963 // Setup Trailers
1964 var trailer http.Header
1965 for _, v := range rp.header["Trailer"] {
1966 for _, key := range strings.Split(v, ",") {
1967 key = http.CanonicalHeaderKey(strings.TrimSpace(key))
1968 switch key {
1969 case "Transfer-Encoding", "Trailer", "Content-Length":
1970 // Bogus. (copy of http1 rules)
1971 // Ignore.
1972 default:
1973 if trailer == nil {
1974 trailer = make(http.Header)
1975 }
1976 trailer[key] = nil
1977 }
1978 }
1979 }
1980 delete(rp.header, "Trailer")
1981
1982 var url_ *url.URL
1983 var requestURI string
1984 if rp.method == "CONNECT" {
1985 url_ = &url.URL{Host: rp.authority}
1986 requestURI = rp.authority // mimic HTTP/1 server behavior
1987 } else {
1988 var err error
1989 url_, err = url.ParseRequestURI(rp.path)
1990 if err != nil {
1991 return nil, nil, streamError(st.id, ErrCodeProtocol)
1992 }
1993 requestURI = rp.path
1994 }
1995
1996 body := &requestBody{
1997 conn: sc,
1998 stream: st,
1999 needsContinue: needsContinue,
2000 }
2001 req := &http.Request{
2002 Method: rp.method,
2003 URL: url_,
2004 RemoteAddr: sc.remoteAddrStr,
2005 Header: rp.header,
2006 RequestURI: requestURI,
2007 Proto: "HTTP/2.0",
2008 ProtoMajor: 2,
2009 ProtoMinor: 0,
2010 TLS: tlsState,
2011 Host: rp.authority,
2012 Body: body,
2013 Trailer: trailer,
2014 }
2015 req = requestWithContext(req, st.ctx)
2016
2017 rws := responseWriterStatePool.Get().(*responseWriterState)
2018 bwSave := rws.bw
2019 *rws = responseWriterState{} // zero all the fields
2020 rws.conn = sc
2021 rws.bw = bwSave
2022 rws.bw.Reset(chunkWriter{rws})
2023 rws.stream = st
2024 rws.req = req
2025 rws.body = body
2026
2027 rw := &responseWriter{rws: rws}
2028 return rw, req, nil
2029}
2030
2031// Run on its own goroutine.
2032func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
2033 didPanic := true
2034 defer func() {
2035 rw.rws.stream.cancelCtx()
2036 if didPanic {
2037 e := recover()
2038 sc.writeFrameFromHandler(FrameWriteRequest{
2039 write: handlerPanicRST{rw.rws.stream.id},
2040 stream: rw.rws.stream,
2041 })
2042 // Same as net/http:
2043 if shouldLogPanic(e) {
2044 const size = 64 << 10
2045 buf := make([]byte, size)
2046 buf = buf[:runtime.Stack(buf, false)]
2047 sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
2048 }
2049 return
2050 }
2051 rw.handlerDone()
2052 }()
2053 handler(rw, req)
2054 didPanic = false
2055}
2056
2057func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {
2058 // 10.5.1 Limits on Header Block Size:
2059 // .. "A server that receives a larger header block than it is
2060 // willing to handle can send an HTTP 431 (Request Header Fields Too
2061 // Large) status code"
2062 const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
2063 w.WriteHeader(statusRequestHeaderFieldsTooLarge)
2064 io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
2065}
2066
2067// called from handler goroutines.
2068// h may be nil.
2069func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {
2070 sc.serveG.checkNotOn() // NOT on
2071 var errc chan error
2072 if headerData.h != nil {
2073 // If there's a header map (which we don't own), so we have to block on
2074 // waiting for this frame to be written, so an http.Flush mid-handler
2075 // writes out the correct value of keys, before a handler later potentially
2076 // mutates it.
2077 errc = errChanPool.Get().(chan error)
2078 }
2079 if err := sc.writeFrameFromHandler(FrameWriteRequest{
2080 write: headerData,
2081 stream: st,
2082 done: errc,
2083 }); err != nil {
2084 return err
2085 }
2086 if errc != nil {
2087 select {
2088 case err := <-errc:
2089 errChanPool.Put(errc)
2090 return err
2091 case <-sc.doneServing:
2092 return errClientDisconnected
2093 case <-st.cw:
2094 return errStreamClosed
2095 }
2096 }
2097 return nil
2098}
2099
2100// called from handler goroutines.
2101func (sc *serverConn) write100ContinueHeaders(st *stream) {
2102 sc.writeFrameFromHandler(FrameWriteRequest{
2103 write: write100ContinueHeadersFrame{st.id},
2104 stream: st,
2105 })
2106}
2107
2108// A bodyReadMsg tells the server loop that the http.Handler read n
2109// bytes of the DATA from the client on the given stream.
2110type bodyReadMsg struct {
2111 st *stream
2112 n int
2113}
2114
2115// called from handler goroutines.
2116// Notes that the handler for the given stream ID read n bytes of its body
2117// and schedules flow control tokens to be sent.
2118func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) {
2119 sc.serveG.checkNotOn() // NOT on
2120 if n > 0 {
2121 select {
2122 case sc.bodyReadCh <- bodyReadMsg{st, n}:
2123 case <-sc.doneServing:
2124 }
2125 }
2126}
2127
2128func (sc *serverConn) noteBodyRead(st *stream, n int) {
2129 sc.serveG.check()
2130 sc.sendWindowUpdate(nil, n) // conn-level
2131 if st.state != stateHalfClosedRemote && st.state != stateClosed {
2132 // Don't send this WINDOW_UPDATE if the stream is closed
2133 // remotely.
2134 sc.sendWindowUpdate(st, n)
2135 }
2136}
2137
2138// st may be nil for conn-level
2139func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
2140 sc.serveG.check()
2141 // "The legal range for the increment to the flow control
2142 // window is 1 to 2^31-1 (2,147,483,647) octets."
2143 // A Go Read call on 64-bit machines could in theory read
2144 // a larger Read than this. Very unlikely, but we handle it here
2145 // rather than elsewhere for now.
2146 const maxUint31 = 1<<31 - 1
2147 for n >= maxUint31 {
2148 sc.sendWindowUpdate32(st, maxUint31)
2149 n -= maxUint31
2150 }
2151 sc.sendWindowUpdate32(st, int32(n))
2152}
2153
2154// st may be nil for conn-level
2155func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {
2156 sc.serveG.check()
2157 if n == 0 {
2158 return
2159 }
2160 if n < 0 {
2161 panic("negative update")
2162 }
2163 var streamID uint32
2164 if st != nil {
2165 streamID = st.id
2166 }
2167 sc.writeFrame(FrameWriteRequest{
2168 write: writeWindowUpdate{streamID: streamID, n: uint32(n)},
2169 stream: st,
2170 })
2171 var ok bool
2172 if st == nil {
2173 ok = sc.inflow.add(n)
2174 } else {
2175 ok = st.inflow.add(n)
2176 }
2177 if !ok {
2178 panic("internal error; sent too many window updates without decrements?")
2179 }
2180}
2181
2182// requestBody is the Handler's Request.Body type.
2183// Read and Close may be called concurrently.
2184type requestBody struct {
2185 stream *stream
2186 conn *serverConn
2187 closed bool // for use by Close only
2188 sawEOF bool // for use by Read only
2189 pipe *pipe // non-nil if we have a HTTP entity message body
2190 needsContinue bool // need to send a 100-continue
2191}
2192
2193func (b *requestBody) Close() error {
2194 if b.pipe != nil && !b.closed {
2195 b.pipe.BreakWithError(errClosedBody)
2196 }
2197 b.closed = true
2198 return nil
2199}
2200
2201func (b *requestBody) Read(p []byte) (n int, err error) {
2202 if b.needsContinue {
2203 b.needsContinue = false
2204 b.conn.write100ContinueHeaders(b.stream)
2205 }
2206 if b.pipe == nil || b.sawEOF {
2207 return 0, io.EOF
2208 }
2209 n, err = b.pipe.Read(p)
2210 if err == io.EOF {
2211 b.sawEOF = true
2212 }
2213 if b.conn == nil && inTests {
2214 return
2215 }
2216 b.conn.noteBodyReadFromHandler(b.stream, n, err)
2217 return
2218}
2219
2220// responseWriter is the http.ResponseWriter implementation. It's
2221// intentionally small (1 pointer wide) to minimize garbage. The
2222// responseWriterState pointer inside is zeroed at the end of a
2223// request (in handlerDone) and calls on the responseWriter thereafter
2224// simply crash (caller's mistake), but the much larger responseWriterState
2225// and buffers are reused between multiple requests.
2226type responseWriter struct {
2227 rws *responseWriterState
2228}
2229
2230// Optional http.ResponseWriter interfaces implemented.
2231var (
2232 _ http.CloseNotifier = (*responseWriter)(nil)
2233 _ http.Flusher = (*responseWriter)(nil)
2234 _ stringWriter = (*responseWriter)(nil)
2235)
2236
2237type responseWriterState struct {
2238 // immutable within a request:
2239 stream *stream
2240 req *http.Request
2241 body *requestBody // to close at end of request, if DATA frames didn't
2242 conn *serverConn
2243
2244 // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
2245 bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
2246
2247 // mutated by http.Handler goroutine:
2248 handlerHeader http.Header // nil until called
2249 snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
2250 trailers []string // set in writeChunk
2251 status int // status code passed to WriteHeader
2252 wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
2253 sentHeader bool // have we sent the header frame?
2254 handlerDone bool // handler has finished
2255 dirty bool // a Write failed; don't reuse this responseWriterState
2256
2257 sentContentLen int64 // non-zero if handler set a Content-Length header
2258 wroteBytes int64
2259
2260 closeNotifierMu sync.Mutex // guards closeNotifierCh
2261 closeNotifierCh chan bool // nil until first used
2262}
2263
2264type chunkWriter struct{ rws *responseWriterState }
2265
2266func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
2267
2268func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 }
2269
2270// declareTrailer is called for each Trailer header when the
2271// response header is written. It notes that a header will need to be
2272// written in the trailers at the end of the response.
2273func (rws *responseWriterState) declareTrailer(k string) {
2274 k = http.CanonicalHeaderKey(k)
2275 if !ValidTrailerHeader(k) {
2276 // Forbidden by RFC 2616 14.40.
2277 rws.conn.logf("ignoring invalid trailer %q", k)
2278 return
2279 }
2280 if !strSliceContains(rws.trailers, k) {
2281 rws.trailers = append(rws.trailers, k)
2282 }
2283}
2284
2285// writeChunk writes chunks from the bufio.Writer. But because
2286// bufio.Writer may bypass its chunking, sometimes p may be
2287// arbitrarily large.
2288//
2289// writeChunk is also responsible (on the first chunk) for sending the
2290// HEADER response.
2291func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
2292 if !rws.wroteHeader {
2293 rws.writeHeader(200)
2294 }
2295
2296 isHeadResp := rws.req.Method == "HEAD"
2297 if !rws.sentHeader {
2298 rws.sentHeader = true
2299 var ctype, clen string
2300 if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
2301 rws.snapHeader.Del("Content-Length")
2302 clen64, err := strconv.ParseInt(clen, 10, 64)
2303 if err == nil && clen64 >= 0 {
2304 rws.sentContentLen = clen64
2305 } else {
2306 clen = ""
2307 }
2308 }
2309 if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
2310 clen = strconv.Itoa(len(p))
2311 }
2312 _, hasContentType := rws.snapHeader["Content-Type"]
2313 if !hasContentType && bodyAllowedForStatus(rws.status) {
2314 ctype = http.DetectContentType(p)
2315 }
2316 var date string
2317 if _, ok := rws.snapHeader["Date"]; !ok {
2318 // TODO(bradfitz): be faster here, like net/http? measure.
2319 date = time.Now().UTC().Format(http.TimeFormat)
2320 }
2321
2322 for _, v := range rws.snapHeader["Trailer"] {
2323 foreachHeaderElement(v, rws.declareTrailer)
2324 }
2325
2326 endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
2327 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2328 streamID: rws.stream.id,
2329 httpResCode: rws.status,
2330 h: rws.snapHeader,
2331 endStream: endStream,
2332 contentType: ctype,
2333 contentLength: clen,
2334 date: date,
2335 })
2336 if err != nil {
2337 rws.dirty = true
2338 return 0, err
2339 }
2340 if endStream {
2341 return 0, nil
2342 }
2343 }
2344 if isHeadResp {
2345 return len(p), nil
2346 }
2347 if len(p) == 0 && !rws.handlerDone {
2348 return 0, nil
2349 }
2350
2351 if rws.handlerDone {
2352 rws.promoteUndeclaredTrailers()
2353 }
2354
2355 endStream := rws.handlerDone && !rws.hasTrailers()
2356 if len(p) > 0 || endStream {
2357 // only send a 0 byte DATA frame if we're ending the stream.
2358 if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
2359 rws.dirty = true
2360 return 0, err
2361 }
2362 }
2363
2364 if rws.handlerDone && rws.hasTrailers() {
2365 err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
2366 streamID: rws.stream.id,
2367 h: rws.handlerHeader,
2368 trailers: rws.trailers,
2369 endStream: true,
2370 })
2371 if err != nil {
2372 rws.dirty = true
2373 }
2374 return len(p), err
2375 }
2376 return len(p), nil
2377}
2378
2379// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
2380// that, if present, signals that the map entry is actually for
2381// the response trailers, and not the response headers. The prefix
2382// is stripped after the ServeHTTP call finishes and the values are
2383// sent in the trailers.
2384//
2385// This mechanism is intended only for trailers that are not known
2386// prior to the headers being written. If the set of trailers is fixed
2387// or known before the header is written, the normal Go trailers mechanism
2388// is preferred:
2389// https://golang.org/pkg/net/http/#ResponseWriter
2390// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
2391const TrailerPrefix = "Trailer:"
2392
2393// promoteUndeclaredTrailers permits http.Handlers to set trailers
2394// after the header has already been flushed. Because the Go
2395// ResponseWriter interface has no way to set Trailers (only the
2396// Header), and because we didn't want to expand the ResponseWriter
2397// interface, and because nobody used trailers, and because RFC 2616
2398// says you SHOULD (but not must) predeclare any trailers in the
2399// header, the official ResponseWriter rules said trailers in Go must
2400// be predeclared, and then we reuse the same ResponseWriter.Header()
2401// map to mean both Headers and Trailers. When it's time to write the
2402// Trailers, we pick out the fields of Headers that were declared as
2403// trailers. That worked for a while, until we found the first major
2404// user of Trailers in the wild: gRPC (using them only over http2),
2405// and gRPC libraries permit setting trailers mid-stream without
2406// predeclarnig them. So: change of plans. We still permit the old
2407// way, but we also permit this hack: if a Header() key begins with
2408// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
2409// invalid token byte anyway, there is no ambiguity. (And it's already
2410// filtered out) It's mildly hacky, but not terrible.
2411//
2412// This method runs after the Handler is done and promotes any Header
2413// fields to be trailers.
2414func (rws *responseWriterState) promoteUndeclaredTrailers() {
2415 for k, vv := range rws.handlerHeader {
2416 if !strings.HasPrefix(k, TrailerPrefix) {
2417 continue
2418 }
2419 trailerKey := strings.TrimPrefix(k, TrailerPrefix)
2420 rws.declareTrailer(trailerKey)
2421 rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
2422 }
2423
2424 if len(rws.trailers) > 1 {
2425 sorter := sorterPool.Get().(*sorter)
2426 sorter.SortStrings(rws.trailers)
2427 sorterPool.Put(sorter)
2428 }
2429}
2430
2431func (w *responseWriter) Flush() {
2432 rws := w.rws
2433 if rws == nil {
2434 panic("Header called after Handler finished")
2435 }
2436 if rws.bw.Buffered() > 0 {
2437 if err := rws.bw.Flush(); err != nil {
2438 // Ignore the error. The frame writer already knows.
2439 return
2440 }
2441 } else {
2442 // The bufio.Writer won't call chunkWriter.Write
2443 // (writeChunk with zero bytes, so we have to do it
2444 // ourselves to force the HTTP response header and/or
2445 // final DATA frame (with END_STREAM) to be sent.
2446 rws.writeChunk(nil)
2447 }
2448}
2449
2450func (w *responseWriter) CloseNotify() <-chan bool {
2451 rws := w.rws
2452 if rws == nil {
2453 panic("CloseNotify called after Handler finished")
2454 }
2455 rws.closeNotifierMu.Lock()
2456 ch := rws.closeNotifierCh
2457 if ch == nil {
2458 ch = make(chan bool, 1)
2459 rws.closeNotifierCh = ch
2460 cw := rws.stream.cw
2461 go func() {
2462 cw.Wait() // wait for close
2463 ch <- true
2464 }()
2465 }
2466 rws.closeNotifierMu.Unlock()
2467 return ch
2468}
2469
2470func (w *responseWriter) Header() http.Header {
2471 rws := w.rws
2472 if rws == nil {
2473 panic("Header called after Handler finished")
2474 }
2475 if rws.handlerHeader == nil {
2476 rws.handlerHeader = make(http.Header)
2477 }
2478 return rws.handlerHeader
2479}
2480
2481func (w *responseWriter) WriteHeader(code int) {
2482 rws := w.rws
2483 if rws == nil {
2484 panic("WriteHeader called after Handler finished")
2485 }
2486 rws.writeHeader(code)
2487}
2488
2489func (rws *responseWriterState) writeHeader(code int) {
2490 if !rws.wroteHeader {
2491 rws.wroteHeader = true
2492 rws.status = code
2493 if len(rws.handlerHeader) > 0 {
2494 rws.snapHeader = cloneHeader(rws.handlerHeader)
2495 }
2496 }
2497}
2498
2499func cloneHeader(h http.Header) http.Header {
2500 h2 := make(http.Header, len(h))
2501 for k, vv := range h {
2502 vv2 := make([]string, len(vv))
2503 copy(vv2, vv)
2504 h2[k] = vv2
2505 }
2506 return h2
2507}
2508
2509// The Life Of A Write is like this:
2510//
2511// * Handler calls w.Write or w.WriteString ->
2512// * -> rws.bw (*bufio.Writer) ->
2513// * (Handler might call Flush)
2514// * -> chunkWriter{rws}
2515// * -> responseWriterState.writeChunk(p []byte)
2516// * -> responseWriterState.writeChunk (most of the magic; see comment there)
2517func (w *responseWriter) Write(p []byte) (n int, err error) {
2518 return w.write(len(p), p, "")
2519}
2520
2521func (w *responseWriter) WriteString(s string) (n int, err error) {
2522 return w.write(len(s), nil, s)
2523}
2524
2525// either dataB or dataS is non-zero.
2526func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
2527 rws := w.rws
2528 if rws == nil {
2529 panic("Write called after Handler finished")
2530 }
2531 if !rws.wroteHeader {
2532 w.WriteHeader(200)
2533 }
2534 if !bodyAllowedForStatus(rws.status) {
2535 return 0, http.ErrBodyNotAllowed
2536 }
2537 rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
2538 if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
2539 // TODO: send a RST_STREAM
2540 return 0, errors.New("http2: handler wrote more than declared Content-Length")
2541 }
2542
2543 if dataB != nil {
2544 return rws.bw.Write(dataB)
2545 } else {
2546 return rws.bw.WriteString(dataS)
2547 }
2548}
2549
2550func (w *responseWriter) handlerDone() {
2551 rws := w.rws
2552 dirty := rws.dirty
2553 rws.handlerDone = true
2554 w.Flush()
2555 w.rws = nil
2556 if !dirty {
2557 // Only recycle the pool if all prior Write calls to
2558 // the serverConn goroutine completed successfully. If
2559 // they returned earlier due to resets from the peer
2560 // there might still be write goroutines outstanding
2561 // from the serverConn referencing the rws memory. See
2562 // issue 20704.
2563 responseWriterStatePool.Put(rws)
2564 }
2565}
2566
2567// Push errors.
2568var (
2569 ErrRecursivePush = errors.New("http2: recursive push not allowed")
2570 ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
2571)
2572
2573// pushOptions is the internal version of http.PushOptions, which we
2574// cannot include here because it's only defined in Go 1.8 and later.
2575type pushOptions struct {
2576 Method string
2577 Header http.Header
2578}
2579
2580func (w *responseWriter) push(target string, opts pushOptions) error {
2581 st := w.rws.stream
2582 sc := st.sc
2583 sc.serveG.checkNotOn()
2584
2585 // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
2586 // http://tools.ietf.org/html/rfc7540#section-6.6
2587 if st.isPushed() {
2588 return ErrRecursivePush
2589 }
2590
2591 // Default options.
2592 if opts.Method == "" {
2593 opts.Method = "GET"
2594 }
2595 if opts.Header == nil {
2596 opts.Header = http.Header{}
2597 }
2598 wantScheme := "http"
2599 if w.rws.req.TLS != nil {
2600 wantScheme = "https"
2601 }
2602
2603 // Validate the request.
2604 u, err := url.Parse(target)
2605 if err != nil {
2606 return err
2607 }
2608 if u.Scheme == "" {
2609 if !strings.HasPrefix(target, "/") {
2610 return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target)
2611 }
2612 u.Scheme = wantScheme
2613 u.Host = w.rws.req.Host
2614 } else {
2615 if u.Scheme != wantScheme {
2616 return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme)
2617 }
2618 if u.Host == "" {
2619 return errors.New("URL must have a host")
2620 }
2621 }
2622 for k := range opts.Header {
2623 if strings.HasPrefix(k, ":") {
2624 return fmt.Errorf("promised request headers cannot include pseudo header %q", k)
2625 }
2626 // These headers are meaningful only if the request has a body,
2627 // but PUSH_PROMISE requests cannot have a body.
2628 // http://tools.ietf.org/html/rfc7540#section-8.2
2629 // Also disallow Host, since the promised URL must be absolute.
2630 switch strings.ToLower(k) {
2631 case "content-length", "content-encoding", "trailer", "te", "expect", "host":
2632 return fmt.Errorf("promised request headers cannot include %q", k)
2633 }
2634 }
2635 if err := checkValidHTTP2RequestHeaders(opts.Header); err != nil {
2636 return err
2637 }
2638
2639 // The RFC effectively limits promised requests to GET and HEAD:
2640 // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
2641 // http://tools.ietf.org/html/rfc7540#section-8.2
2642 if opts.Method != "GET" && opts.Method != "HEAD" {
2643 return fmt.Errorf("method %q must be GET or HEAD", opts.Method)
2644 }
2645
2646 msg := &startPushRequest{
2647 parent: st,
2648 method: opts.Method,
2649 url: u,
2650 header: cloneHeader(opts.Header),
2651 done: errChanPool.Get().(chan error),
2652 }
2653
2654 select {
2655 case <-sc.doneServing:
2656 return errClientDisconnected
2657 case <-st.cw:
2658 return errStreamClosed
2659 case sc.serveMsgCh <- msg:
2660 }
2661
2662 select {
2663 case <-sc.doneServing:
2664 return errClientDisconnected
2665 case <-st.cw:
2666 return errStreamClosed
2667 case err := <-msg.done:
2668 errChanPool.Put(msg.done)
2669 return err
2670 }
2671}
2672
2673type startPushRequest struct {
2674 parent *stream
2675 method string
2676 url *url.URL
2677 header http.Header
2678 done chan error
2679}
2680
2681func (sc *serverConn) startPush(msg *startPushRequest) {
2682 sc.serveG.check()
2683
2684 // http://tools.ietf.org/html/rfc7540#section-6.6.
2685 // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
2686 // is in either the "open" or "half-closed (remote)" state.
2687 if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {
2688 // responseWriter.Push checks that the stream is peer-initiaed.
2689 msg.done <- errStreamClosed
2690 return
2691 }
2692
2693 // http://tools.ietf.org/html/rfc7540#section-6.6.
2694 if !sc.pushEnabled {
2695 msg.done <- http.ErrNotSupported
2696 return
2697 }
2698
2699 // PUSH_PROMISE frames must be sent in increasing order by stream ID, so
2700 // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
2701 // is written. Once the ID is allocated, we start the request handler.
2702 allocatePromisedID := func() (uint32, error) {
2703 sc.serveG.check()
2704
2705 // Check this again, just in case. Technically, we might have received
2706 // an updated SETTINGS by the time we got around to writing this frame.
2707 if !sc.pushEnabled {
2708 return 0, http.ErrNotSupported
2709 }
2710 // http://tools.ietf.org/html/rfc7540#section-6.5.2.
2711 if sc.curPushedStreams+1 > sc.clientMaxStreams {
2712 return 0, ErrPushLimitReached
2713 }
2714
2715 // http://tools.ietf.org/html/rfc7540#section-5.1.1.
2716 // Streams initiated by the server MUST use even-numbered identifiers.
2717 // A server that is unable to establish a new stream identifier can send a GOAWAY
2718 // frame so that the client is forced to open a new connection for new streams.
2719 if sc.maxPushPromiseID+2 >= 1<<31 {
2720 sc.startGracefulShutdownInternal()
2721 return 0, ErrPushLimitReached
2722 }
2723 sc.maxPushPromiseID += 2
2724 promisedID := sc.maxPushPromiseID
2725
2726 // http://tools.ietf.org/html/rfc7540#section-8.2.
2727 // Strictly speaking, the new stream should start in "reserved (local)", then
2728 // transition to "half closed (remote)" after sending the initial HEADERS, but
2729 // we start in "half closed (remote)" for simplicity.
2730 // See further comments at the definition of stateHalfClosedRemote.
2731 promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
2732 rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{
2733 method: msg.method,
2734 scheme: msg.url.Scheme,
2735 authority: msg.url.Host,
2736 path: msg.url.RequestURI(),
2737 header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
2738 })
2739 if err != nil {
2740 // Should not happen, since we've already validated msg.url.
2741 panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
2742 }
2743
2744 go sc.runHandler(rw, req, sc.handler.ServeHTTP)
2745 return promisedID, nil
2746 }
2747
2748 sc.writeFrame(FrameWriteRequest{
2749 write: &writePushPromise{
2750 streamID: msg.parent.id,
2751 method: msg.method,
2752 url: msg.url,
2753 h: msg.header,
2754 allocatePromisedID: allocatePromisedID,
2755 },
2756 stream: msg.parent,
2757 done: msg.done,
2758 })
2759}
2760
2761// foreachHeaderElement splits v according to the "#rule" construction
2762// in RFC 2616 section 2.1 and calls fn for each non-empty element.
2763func foreachHeaderElement(v string, fn func(string)) {
2764 v = textproto.TrimString(v)
2765 if v == "" {
2766 return
2767 }
2768 if !strings.Contains(v, ",") {
2769 fn(v)
2770 return
2771 }
2772 for _, f := range strings.Split(v, ",") {
2773 if f = textproto.TrimString(f); f != "" {
2774 fn(f)
2775 }
2776 }
2777}
2778
2779// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
2780var connHeaders = []string{
2781 "Connection",
2782 "Keep-Alive",
2783 "Proxy-Connection",
2784 "Transfer-Encoding",
2785 "Upgrade",
2786}
2787
2788// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
2789// per RFC 7540 Section 8.1.2.2.
2790// The returned error is reported to users.
2791func checkValidHTTP2RequestHeaders(h http.Header) error {
2792 for _, k := range connHeaders {
2793 if _, ok := h[k]; ok {
2794 return fmt.Errorf("request header %q is not valid in HTTP/2", k)
2795 }
2796 }
2797 te := h["Te"]
2798 if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
2799 return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
2800 }
2801 return nil
2802}
2803
2804func new400Handler(err error) http.HandlerFunc {
2805 return func(w http.ResponseWriter, r *http.Request) {
2806 http.Error(w, err.Error(), http.StatusBadRequest)
2807 }
2808}
2809
2810// ValidTrailerHeader reports whether name is a valid header field name to appear
2811// in trailers.
2812// See: http://tools.ietf.org/html/rfc7230#section-4.1.2
2813func ValidTrailerHeader(name string) bool {
2814 name = http.CanonicalHeaderKey(name)
2815 if strings.HasPrefix(name, "If-") || badTrailer[name] {
2816 return false
2817 }
2818 return true
2819}
2820
2821var badTrailer = map[string]bool{
2822 "Authorization": true,
2823 "Cache-Control": true,
2824 "Connection": true,
2825 "Content-Encoding": true,
2826 "Content-Length": true,
2827 "Content-Range": true,
2828 "Content-Type": true,
2829 "Expect": true,
2830 "Host": true,
2831 "Keep-Alive": true,
2832 "Max-Forwards": true,
2833 "Pragma": true,
2834 "Proxy-Authenticate": true,
2835 "Proxy-Authorization": true,
2836 "Proxy-Connection": true,
2837 "Range": true,
2838 "Realm": true,
2839 "Te": true,
2840 "Trailer": true,
2841 "Transfer-Encoding": true,
2842 "Www-Authenticate": true,
2843}
2844
2845// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
2846// disabled. See comments on h1ServerShutdownChan above for why
2847// the code is written this way.
2848func h1ServerKeepAlivesDisabled(hs *http.Server) bool {
2849 var x interface{} = hs
2850 type I interface {
2851 doKeepAlives() bool
2852 }
2853 if hs, ok := x.(I); ok {
2854 return !hs.doKeepAlives()
2855 }
2856 return false
2857}
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
new file mode 100644
index 0000000..adb77ff
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -0,0 +1,2275 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Transport code.
6
7package http2
8
9import (
10 "bufio"
11 "bytes"
12 "compress/gzip"
13 "crypto/rand"
14 "crypto/tls"
15 "errors"
16 "fmt"
17 "io"
18 "io/ioutil"
19 "log"
20 "math"
21 mathrand "math/rand"
22 "net"
23 "net/http"
24 "sort"
25 "strconv"
26 "strings"
27 "sync"
28 "time"
29
30 "golang.org/x/net/http2/hpack"
31 "golang.org/x/net/idna"
32 "golang.org/x/net/lex/httplex"
33)
34
35const (
36 // transportDefaultConnFlow is how many connection-level flow control
37 // tokens we give the server at start-up, past the default 64k.
38 transportDefaultConnFlow = 1 << 30
39
40 // transportDefaultStreamFlow is how many stream-level flow
41 // control tokens we announce to the peer, and how many bytes
42 // we buffer per stream.
43 transportDefaultStreamFlow = 4 << 20
44
45 // transportDefaultStreamMinRefresh is the minimum number of bytes we'll send
46 // a stream-level WINDOW_UPDATE for at a time.
47 transportDefaultStreamMinRefresh = 4 << 10
48
49 defaultUserAgent = "Go-http-client/2.0"
50)
51
52// Transport is an HTTP/2 Transport.
53//
54// A Transport internally caches connections to servers. It is safe
55// for concurrent use by multiple goroutines.
56type Transport struct {
57 // DialTLS specifies an optional dial function for creating
58 // TLS connections for requests.
59 //
60 // If DialTLS is nil, tls.Dial is used.
61 //
62 // If the returned net.Conn has a ConnectionState method like tls.Conn,
63 // it will be used to set http.Response.TLS.
64 DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
65
66 // TLSClientConfig specifies the TLS configuration to use with
67 // tls.Client. If nil, the default configuration is used.
68 TLSClientConfig *tls.Config
69
70 // ConnPool optionally specifies an alternate connection pool to use.
71 // If nil, the default is used.
72 ConnPool ClientConnPool
73
74 // DisableCompression, if true, prevents the Transport from
75 // requesting compression with an "Accept-Encoding: gzip"
76 // request header when the Request contains no existing
77 // Accept-Encoding value. If the Transport requests gzip on
78 // its own and gets a gzipped response, it's transparently
79 // decoded in the Response.Body. However, if the user
80 // explicitly requested gzip it is not automatically
81 // uncompressed.
82 DisableCompression bool
83
84 // AllowHTTP, if true, permits HTTP/2 requests using the insecure,
85 // plain-text "http" scheme. Note that this does not enable h2c support.
86 AllowHTTP bool
87
88 // MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
89 // send in the initial settings frame. It is how many bytes
90 // of response headers are allowed. Unlike the http2 spec, zero here
91 // means to use a default limit (currently 10MB). If you actually
92 // want to advertise an ulimited value to the peer, Transport
93 // interprets the highest possible value here (0xffffffff or 1<<32-1)
94 // to mean no limit.
95 MaxHeaderListSize uint32
96
97 // t1, if non-nil, is the standard library Transport using
98 // this transport. Its settings are used (but not its
99 // RoundTrip method, etc).
100 t1 *http.Transport
101
102 connPoolOnce sync.Once
103 connPoolOrDef ClientConnPool // non-nil version of ConnPool
104}
105
106func (t *Transport) maxHeaderListSize() uint32 {
107 if t.MaxHeaderListSize == 0 {
108 return 10 << 20
109 }
110 if t.MaxHeaderListSize == 0xffffffff {
111 return 0
112 }
113 return t.MaxHeaderListSize
114}
115
116func (t *Transport) disableCompression() bool {
117 return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
118}
119
120var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6")
121
122// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
123// It requires Go 1.6 or later and returns an error if the net/http package is too old
124// or if t1 has already been HTTP/2-enabled.
125func ConfigureTransport(t1 *http.Transport) error {
126 _, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go
127 return err
128}
129
130func (t *Transport) connPool() ClientConnPool {
131 t.connPoolOnce.Do(t.initConnPool)
132 return t.connPoolOrDef
133}
134
135func (t *Transport) initConnPool() {
136 if t.ConnPool != nil {
137 t.connPoolOrDef = t.ConnPool
138 } else {
139 t.connPoolOrDef = &clientConnPool{t: t}
140 }
141}
142
143// ClientConn is the state of a single HTTP/2 client connection to an
144// HTTP/2 server.
145type ClientConn struct {
146 t *Transport
147 tconn net.Conn // usually *tls.Conn, except specialized impls
148 tlsState *tls.ConnectionState // nil only for specialized impls
149 singleUse bool // whether being used for a single http.Request
150
151 // readLoop goroutine fields:
152 readerDone chan struct{} // closed on error
153 readerErr error // set before readerDone is closed
154
155 idleTimeout time.Duration // or 0 for never
156 idleTimer *time.Timer
157
158 mu sync.Mutex // guards following
159 cond *sync.Cond // hold mu; broadcast on flow/closed changes
160 flow flow // our conn-level flow control quota (cs.flow is per stream)
161 inflow flow // peer's conn-level flow control
162 closed bool
163 wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back
164 goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received
165 goAwayDebug string // goAway frame's debug data, retained as a string
166 streams map[uint32]*clientStream // client-initiated
167 nextStreamID uint32
168 pendingRequests int // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams
169 pings map[[8]byte]chan struct{} // in flight ping data to notification channel
170 bw *bufio.Writer
171 br *bufio.Reader
172 fr *Framer
173 lastActive time.Time
174 // Settings from peer: (also guarded by mu)
175 maxFrameSize uint32
176 maxConcurrentStreams uint32
177 peerMaxHeaderListSize uint64
178 initialWindowSize uint32
179
180 hbuf bytes.Buffer // HPACK encoder writes into this
181 henc *hpack.Encoder
182 freeBuf [][]byte
183
184 wmu sync.Mutex // held while writing; acquire AFTER mu if holding both
185 werr error // first write error that has occurred
186}
187
188// clientStream is the state for a single HTTP/2 stream. One of these
189// is created for each Transport.RoundTrip call.
190type clientStream struct {
191 cc *ClientConn
192 req *http.Request
193 trace *clientTrace // or nil
194 ID uint32
195 resc chan resAndError
196 bufPipe pipe // buffered pipe with the flow-controlled response payload
197 startedWrite bool // started request body write; guarded by cc.mu
198 requestedGzip bool
199 on100 func() // optional code to run if get a 100 continue response
200
201 flow flow // guarded by cc.mu
202 inflow flow // guarded by cc.mu
203 bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
204 readErr error // sticky read error; owned by transportResponseBody.Read
205 stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu
206 didReset bool // whether we sent a RST_STREAM to the server; guarded by cc.mu
207
208 peerReset chan struct{} // closed on peer reset
209 resetErr error // populated before peerReset is closed
210
211 done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
212
213 // owned by clientConnReadLoop:
214 firstByte bool // got the first response byte
215 pastHeaders bool // got first MetaHeadersFrame (actual headers)
216 pastTrailers bool // got optional second MetaHeadersFrame (trailers)
217
218 trailer http.Header // accumulated trailers
219 resTrailer *http.Header // client's Response.Trailer
220}
221
222// awaitRequestCancel waits for the user to cancel a request or for the done
223// channel to be signaled. A non-nil error is returned only if the request was
224// canceled.
225func awaitRequestCancel(req *http.Request, done <-chan struct{}) error {
226 ctx := reqContext(req)
227 if req.Cancel == nil && ctx.Done() == nil {
228 return nil
229 }
230 select {
231 case <-req.Cancel:
232 return errRequestCanceled
233 case <-ctx.Done():
234 return ctx.Err()
235 case <-done:
236 return nil
237 }
238}
239
240// awaitRequestCancel waits for the user to cancel a request, its context to
241// expire, or for the request to be done (any way it might be removed from the
242// cc.streams map: peer reset, successful completion, TCP connection breakage,
243// etc). If the request is canceled, then cs will be canceled and closed.
244func (cs *clientStream) awaitRequestCancel(req *http.Request) {
245 if err := awaitRequestCancel(req, cs.done); err != nil {
246 cs.cancelStream()
247 cs.bufPipe.CloseWithError(err)
248 }
249}
250
251func (cs *clientStream) cancelStream() {
252 cc := cs.cc
253 cc.mu.Lock()
254 didReset := cs.didReset
255 cs.didReset = true
256 cc.mu.Unlock()
257
258 if !didReset {
259 cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
260 cc.forgetStreamID(cs.ID)
261 }
262}
263
264// checkResetOrDone reports any error sent in a RST_STREAM frame by the
265// server, or errStreamClosed if the stream is complete.
266func (cs *clientStream) checkResetOrDone() error {
267 select {
268 case <-cs.peerReset:
269 return cs.resetErr
270 case <-cs.done:
271 return errStreamClosed
272 default:
273 return nil
274 }
275}
276
277func (cs *clientStream) abortRequestBodyWrite(err error) {
278 if err == nil {
279 panic("nil error")
280 }
281 cc := cs.cc
282 cc.mu.Lock()
283 cs.stopReqBody = err
284 cc.cond.Broadcast()
285 cc.mu.Unlock()
286}
287
288type stickyErrWriter struct {
289 w io.Writer
290 err *error
291}
292
293func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
294 if *sew.err != nil {
295 return 0, *sew.err
296 }
297 n, err = sew.w.Write(p)
298 *sew.err = err
299 return
300}
301
302var ErrNoCachedConn = errors.New("http2: no cached connection was available")
303
304// RoundTripOpt are options for the Transport.RoundTripOpt method.
305type RoundTripOpt struct {
306 // OnlyCachedConn controls whether RoundTripOpt may
307 // create a new TCP connection. If set true and
308 // no cached connection is available, RoundTripOpt
309 // will return ErrNoCachedConn.
310 OnlyCachedConn bool
311}
312
313func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
314 return t.RoundTripOpt(req, RoundTripOpt{})
315}
316
317// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
318// and returns a host:port. The port 443 is added if needed.
319func authorityAddr(scheme string, authority string) (addr string) {
320 host, port, err := net.SplitHostPort(authority)
321 if err != nil { // authority didn't have a port
322 port = "443"
323 if scheme == "http" {
324 port = "80"
325 }
326 host = authority
327 }
328 if a, err := idna.ToASCII(host); err == nil {
329 host = a
330 }
331 // IPv6 address literal, without a port:
332 if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
333 return host + ":" + port
334 }
335 return net.JoinHostPort(host, port)
336}
337
338// RoundTripOpt is like RoundTrip, but takes options.
339func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
340 if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
341 return nil, errors.New("http2: unsupported scheme")
342 }
343
344 addr := authorityAddr(req.URL.Scheme, req.URL.Host)
345 for retry := 0; ; retry++ {
346 cc, err := t.connPool().GetClientConn(req, addr)
347 if err != nil {
348 t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err)
349 return nil, err
350 }
351 traceGotConn(req, cc)
352 res, err := cc.RoundTrip(req)
353 if err != nil && retry <= 6 {
354 afterBodyWrite := false
355 if e, ok := err.(afterReqBodyWriteError); ok {
356 err = e
357 afterBodyWrite = true
358 }
359 if req, err = shouldRetryRequest(req, err, afterBodyWrite); err == nil {
360 // After the first retry, do exponential backoff with 10% jitter.
361 if retry == 0 {
362 continue
363 }
364 backoff := float64(uint(1) << (uint(retry) - 1))
365 backoff += backoff * (0.1 * mathrand.Float64())
366 select {
367 case <-time.After(time.Second * time.Duration(backoff)):
368 continue
369 case <-reqContext(req).Done():
370 return nil, reqContext(req).Err()
371 }
372 }
373 }
374 if err != nil {
375 t.vlogf("RoundTrip failure: %v", err)
376 return nil, err
377 }
378 return res, nil
379 }
380}
381
382// CloseIdleConnections closes any connections which were previously
383// connected from previous requests but are now sitting idle.
384// It does not interrupt any connections currently in use.
385func (t *Transport) CloseIdleConnections() {
386 if cp, ok := t.connPool().(clientConnPoolIdleCloser); ok {
387 cp.closeIdleConnections()
388 }
389}
390
391var (
392 errClientConnClosed = errors.New("http2: client conn is closed")
393 errClientConnUnusable = errors.New("http2: client conn not usable")
394 errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
395)
396
397// afterReqBodyWriteError is a wrapper around errors returned by ClientConn.RoundTrip.
398// It is used to signal that err happened after part of Request.Body was sent to the server.
399type afterReqBodyWriteError struct {
400 err error
401}
402
403func (e afterReqBodyWriteError) Error() string {
404 return e.err.Error() + "; some request body already written"
405}
406
407// shouldRetryRequest is called by RoundTrip when a request fails to get
408// response headers. It is always called with a non-nil error.
409// It returns either a request to retry (either the same request, or a
410// modified clone), or an error if the request can't be replayed.
411func shouldRetryRequest(req *http.Request, err error, afterBodyWrite bool) (*http.Request, error) {
412 if !canRetryError(err) {
413 return nil, err
414 }
415 if !afterBodyWrite {
416 return req, nil
417 }
418 // If the Body is nil (or http.NoBody), it's safe to reuse
419 // this request and its Body.
420 if req.Body == nil || reqBodyIsNoBody(req.Body) {
421 return req, nil
422 }
423 // Otherwise we depend on the Request having its GetBody
424 // func defined.
425 getBody := reqGetBody(req) // Go 1.8: getBody = req.GetBody
426 if getBody == nil {
427 return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
428 }
429 body, err := getBody()
430 if err != nil {
431 return nil, err
432 }
433 newReq := *req
434 newReq.Body = body
435 return &newReq, nil
436}
437
438func canRetryError(err error) bool {
439 if err == errClientConnUnusable || err == errClientConnGotGoAway {
440 return true
441 }
442 if se, ok := err.(StreamError); ok {
443 return se.Code == ErrCodeRefusedStream
444 }
445 return false
446}
447
448func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, error) {
449 host, _, err := net.SplitHostPort(addr)
450 if err != nil {
451 return nil, err
452 }
453 tconn, err := t.dialTLS()("tcp", addr, t.newTLSConfig(host))
454 if err != nil {
455 return nil, err
456 }
457 return t.newClientConn(tconn, singleUse)
458}
459
460func (t *Transport) newTLSConfig(host string) *tls.Config {
461 cfg := new(tls.Config)
462 if t.TLSClientConfig != nil {
463 *cfg = *cloneTLSConfig(t.TLSClientConfig)
464 }
465 if !strSliceContains(cfg.NextProtos, NextProtoTLS) {
466 cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)
467 }
468 if cfg.ServerName == "" {
469 cfg.ServerName = host
470 }
471 return cfg
472}
473
474func (t *Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) {
475 if t.DialTLS != nil {
476 return t.DialTLS
477 }
478 return t.dialTLSDefault
479}
480
481func (t *Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) {
482 cn, err := tls.Dial(network, addr, cfg)
483 if err != nil {
484 return nil, err
485 }
486 if err := cn.Handshake(); err != nil {
487 return nil, err
488 }
489 if !cfg.InsecureSkipVerify {
490 if err := cn.VerifyHostname(cfg.ServerName); err != nil {
491 return nil, err
492 }
493 }
494 state := cn.ConnectionState()
495 if p := state.NegotiatedProtocol; p != NextProtoTLS {
496 return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS)
497 }
498 if !state.NegotiatedProtocolIsMutual {
499 return nil, errors.New("http2: could not negotiate protocol mutually")
500 }
501 return cn, nil
502}
503
504// disableKeepAlives reports whether connections should be closed as
505// soon as possible after handling the first request.
506func (t *Transport) disableKeepAlives() bool {
507 return t.t1 != nil && t.t1.DisableKeepAlives
508}
509
510func (t *Transport) expectContinueTimeout() time.Duration {
511 if t.t1 == nil {
512 return 0
513 }
514 return transportExpectContinueTimeout(t.t1)
515}
516
517func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
518 return t.newClientConn(c, false)
519}
520
521func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {
522 cc := &ClientConn{
523 t: t,
524 tconn: c,
525 readerDone: make(chan struct{}),
526 nextStreamID: 1,
527 maxFrameSize: 16 << 10, // spec default
528 initialWindowSize: 65535, // spec default
529 maxConcurrentStreams: 1000, // "infinite", per spec. 1000 seems good enough.
530 peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead.
531 streams: make(map[uint32]*clientStream),
532 singleUse: singleUse,
533 wantSettingsAck: true,
534 pings: make(map[[8]byte]chan struct{}),
535 }
536 if d := t.idleConnTimeout(); d != 0 {
537 cc.idleTimeout = d
538 cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
539 }
540 if VerboseLogs {
541 t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
542 }
543
544 cc.cond = sync.NewCond(&cc.mu)
545 cc.flow.add(int32(initialWindowSize))
546
547 // TODO: adjust this writer size to account for frame size +
548 // MTU + crypto/tls record padding.
549 cc.bw = bufio.NewWriter(stickyErrWriter{c, &cc.werr})
550 cc.br = bufio.NewReader(c)
551 cc.fr = NewFramer(cc.bw, cc.br)
552 cc.fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
553 cc.fr.MaxHeaderListSize = t.maxHeaderListSize()
554
555 // TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on
556 // henc in response to SETTINGS frames?
557 cc.henc = hpack.NewEncoder(&cc.hbuf)
558
559 if cs, ok := c.(connectionStater); ok {
560 state := cs.ConnectionState()
561 cc.tlsState = &state
562 }
563
564 initialSettings := []Setting{
565 {ID: SettingEnablePush, Val: 0},
566 {ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow},
567 }
568 if max := t.maxHeaderListSize(); max != 0 {
569 initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max})
570 }
571
572 cc.bw.Write(clientPreface)
573 cc.fr.WriteSettings(initialSettings...)
574 cc.fr.WriteWindowUpdate(0, transportDefaultConnFlow)
575 cc.inflow.add(transportDefaultConnFlow + initialWindowSize)
576 cc.bw.Flush()
577 if cc.werr != nil {
578 return nil, cc.werr
579 }
580
581 go cc.readLoop()
582 return cc, nil
583}
584
585func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
586 cc.mu.Lock()
587 defer cc.mu.Unlock()
588
589 old := cc.goAway
590 cc.goAway = f
591
592 // Merge the previous and current GoAway error frames.
593 if cc.goAwayDebug == "" {
594 cc.goAwayDebug = string(f.DebugData())
595 }
596 if old != nil && old.ErrCode != ErrCodeNo {
597 cc.goAway.ErrCode = old.ErrCode
598 }
599 last := f.LastStreamID
600 for streamID, cs := range cc.streams {
601 if streamID > last {
602 select {
603 case cs.resc <- resAndError{err: errClientConnGotGoAway}:
604 default:
605 }
606 }
607 }
608}
609
610// CanTakeNewRequest reports whether the connection can take a new request,
611// meaning it has not been closed or received or sent a GOAWAY.
612func (cc *ClientConn) CanTakeNewRequest() bool {
613 cc.mu.Lock()
614 defer cc.mu.Unlock()
615 return cc.canTakeNewRequestLocked()
616}
617
618func (cc *ClientConn) canTakeNewRequestLocked() bool {
619 if cc.singleUse && cc.nextStreamID > 1 {
620 return false
621 }
622 return cc.goAway == nil && !cc.closed &&
623 int64(cc.nextStreamID)+int64(cc.pendingRequests) < math.MaxInt32
624}
625
626// onIdleTimeout is called from a time.AfterFunc goroutine. It will
627// only be called when we're idle, but because we're coming from a new
628// goroutine, there could be a new request coming in at the same time,
629// so this simply calls the synchronized closeIfIdle to shut down this
630// connection. The timer could just call closeIfIdle, but this is more
631// clear.
632func (cc *ClientConn) onIdleTimeout() {
633 cc.closeIfIdle()
634}
635
636func (cc *ClientConn) closeIfIdle() {
637 cc.mu.Lock()
638 if len(cc.streams) > 0 {
639 cc.mu.Unlock()
640 return
641 }
642 cc.closed = true
643 nextID := cc.nextStreamID
644 // TODO: do clients send GOAWAY too? maybe? Just Close:
645 cc.mu.Unlock()
646
647 if VerboseLogs {
648 cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2)
649 }
650 cc.tconn.Close()
651}
652
653const maxAllocFrameSize = 512 << 10
654
655// frameBuffer returns a scratch buffer suitable for writing DATA frames.
656// They're capped at the min of the peer's max frame size or 512KB
657// (kinda arbitrarily), but definitely capped so we don't allocate 4GB
658// bufers.
659func (cc *ClientConn) frameScratchBuffer() []byte {
660 cc.mu.Lock()
661 size := cc.maxFrameSize
662 if size > maxAllocFrameSize {
663 size = maxAllocFrameSize
664 }
665 for i, buf := range cc.freeBuf {
666 if len(buf) >= int(size) {
667 cc.freeBuf[i] = nil
668 cc.mu.Unlock()
669 return buf[:size]
670 }
671 }
672 cc.mu.Unlock()
673 return make([]byte, size)
674}
675
676func (cc *ClientConn) putFrameScratchBuffer(buf []byte) {
677 cc.mu.Lock()
678 defer cc.mu.Unlock()
679 const maxBufs = 4 // arbitrary; 4 concurrent requests per conn? investigate.
680 if len(cc.freeBuf) < maxBufs {
681 cc.freeBuf = append(cc.freeBuf, buf)
682 return
683 }
684 for i, old := range cc.freeBuf {
685 if old == nil {
686 cc.freeBuf[i] = buf
687 return
688 }
689 }
690 // forget about it.
691}
692
693// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
694// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.
695var errRequestCanceled = errors.New("net/http: request canceled")
696
697func commaSeparatedTrailers(req *http.Request) (string, error) {
698 keys := make([]string, 0, len(req.Trailer))
699 for k := range req.Trailer {
700 k = http.CanonicalHeaderKey(k)
701 switch k {
702 case "Transfer-Encoding", "Trailer", "Content-Length":
703 return "", &badStringError{"invalid Trailer key", k}
704 }
705 keys = append(keys, k)
706 }
707 if len(keys) > 0 {
708 sort.Strings(keys)
709 return strings.Join(keys, ","), nil
710 }
711 return "", nil
712}
713
714func (cc *ClientConn) responseHeaderTimeout() time.Duration {
715 if cc.t.t1 != nil {
716 return cc.t.t1.ResponseHeaderTimeout
717 }
718 // No way to do this (yet?) with just an http2.Transport. Probably
719 // no need. Request.Cancel this is the new way. We only need to support
720 // this for compatibility with the old http.Transport fields when
721 // we're doing transparent http2.
722 return 0
723}
724
725// checkConnHeaders checks whether req has any invalid connection-level headers.
726// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields.
727// Certain headers are special-cased as okay but not transmitted later.
728func checkConnHeaders(req *http.Request) error {
729 if v := req.Header.Get("Upgrade"); v != "" {
730 return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"])
731 }
732 if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
733 return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv)
734 }
735 if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "close" && vv[0] != "keep-alive") {
736 return fmt.Errorf("http2: invalid Connection request header: %q", vv)
737 }
738 return nil
739}
740
741// actualContentLength returns a sanitized version of
742// req.ContentLength, where 0 actually means zero (not unknown) and -1
743// means unknown.
744func actualContentLength(req *http.Request) int64 {
745 if req.Body == nil || reqBodyIsNoBody(req.Body) {
746 return 0
747 }
748 if req.ContentLength != 0 {
749 return req.ContentLength
750 }
751 return -1
752}
753
754func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
755 if err := checkConnHeaders(req); err != nil {
756 return nil, err
757 }
758 if cc.idleTimer != nil {
759 cc.idleTimer.Stop()
760 }
761
762 trailers, err := commaSeparatedTrailers(req)
763 if err != nil {
764 return nil, err
765 }
766 hasTrailers := trailers != ""
767
768 cc.mu.Lock()
769 if err := cc.awaitOpenSlotForRequest(req); err != nil {
770 cc.mu.Unlock()
771 return nil, err
772 }
773
774 body := req.Body
775 contentLen := actualContentLength(req)
776 hasBody := contentLen != 0
777
778 // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
779 var requestedGzip bool
780 if !cc.t.disableCompression() &&
781 req.Header.Get("Accept-Encoding") == "" &&
782 req.Header.Get("Range") == "" &&
783 req.Method != "HEAD" {
784 // Request gzip only, not deflate. Deflate is ambiguous and
785 // not as universally supported anyway.
786 // See: http://www.gzip.org/zlib/zlib_faq.html#faq38
787 //
788 // Note that we don't request this for HEAD requests,
789 // due to a bug in nginx:
790 // http://trac.nginx.org/nginx/ticket/358
791 // https://golang.org/issue/5522
792 //
793 // We don't request gzip if the request is for a range, since
794 // auto-decoding a portion of a gzipped document will just fail
795 // anyway. See https://golang.org/issue/8923
796 requestedGzip = true
797 }
798
799 // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
800 // sent by writeRequestBody below, along with any Trailers,
801 // again in form HEADERS{1}, CONTINUATION{0,})
802 hdrs, err := cc.encodeHeaders(req, requestedGzip, trailers, contentLen)
803 if err != nil {
804 cc.mu.Unlock()
805 return nil, err
806 }
807
808 cs := cc.newStream()
809 cs.req = req
810 cs.trace = requestTrace(req)
811 cs.requestedGzip = requestedGzip
812 bodyWriter := cc.t.getBodyWriterState(cs, body)
813 cs.on100 = bodyWriter.on100
814
815 cc.wmu.Lock()
816 endStream := !hasBody && !hasTrailers
817 werr := cc.writeHeaders(cs.ID, endStream, hdrs)
818 cc.wmu.Unlock()
819 traceWroteHeaders(cs.trace)
820 cc.mu.Unlock()
821
822 if werr != nil {
823 if hasBody {
824 req.Body.Close() // per RoundTripper contract
825 bodyWriter.cancel()
826 }
827 cc.forgetStreamID(cs.ID)
828 // Don't bother sending a RST_STREAM (our write already failed;
829 // no need to keep writing)
830 traceWroteRequest(cs.trace, werr)
831 return nil, werr
832 }
833
834 var respHeaderTimer <-chan time.Time
835 if hasBody {
836 bodyWriter.scheduleBodyWrite()
837 } else {
838 traceWroteRequest(cs.trace, nil)
839 if d := cc.responseHeaderTimeout(); d != 0 {
840 timer := time.NewTimer(d)
841 defer timer.Stop()
842 respHeaderTimer = timer.C
843 }
844 }
845
846 readLoopResCh := cs.resc
847 bodyWritten := false
848 ctx := reqContext(req)
849
850 handleReadLoopResponse := func(re resAndError) (*http.Response, error) {
851 res := re.res
852 if re.err != nil || res.StatusCode > 299 {
853 // On error or status code 3xx, 4xx, 5xx, etc abort any
854 // ongoing write, assuming that the server doesn't care
855 // about our request body. If the server replied with 1xx or
856 // 2xx, however, then assume the server DOES potentially
857 // want our body (e.g. full-duplex streaming:
858 // golang.org/issue/13444). If it turns out the server
859 // doesn't, they'll RST_STREAM us soon enough. This is a
860 // heuristic to avoid adding knobs to Transport. Hopefully
861 // we can keep it.
862 bodyWriter.cancel()
863 cs.abortRequestBodyWrite(errStopReqBodyWrite)
864 }
865 if re.err != nil {
866 cc.mu.Lock()
867 afterBodyWrite := cs.startedWrite
868 cc.mu.Unlock()
869 cc.forgetStreamID(cs.ID)
870 if afterBodyWrite {
871 return nil, afterReqBodyWriteError{re.err}
872 }
873 return nil, re.err
874 }
875 res.Request = req
876 res.TLS = cc.tlsState
877 return res, nil
878 }
879
880 for {
881 select {
882 case re := <-readLoopResCh:
883 return handleReadLoopResponse(re)
884 case <-respHeaderTimer:
885 if !hasBody || bodyWritten {
886 cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
887 } else {
888 bodyWriter.cancel()
889 cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
890 }
891 cc.forgetStreamID(cs.ID)
892 return nil, errTimeout
893 case <-ctx.Done():
894 if !hasBody || bodyWritten {
895 cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
896 } else {
897 bodyWriter.cancel()
898 cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
899 }
900 cc.forgetStreamID(cs.ID)
901 return nil, ctx.Err()
902 case <-req.Cancel:
903 if !hasBody || bodyWritten {
904 cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
905 } else {
906 bodyWriter.cancel()
907 cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
908 }
909 cc.forgetStreamID(cs.ID)
910 return nil, errRequestCanceled
911 case <-cs.peerReset:
912 // processResetStream already removed the
913 // stream from the streams map; no need for
914 // forgetStreamID.
915 return nil, cs.resetErr
916 case err := <-bodyWriter.resc:
917 // Prefer the read loop's response, if available. Issue 16102.
918 select {
919 case re := <-readLoopResCh:
920 return handleReadLoopResponse(re)
921 default:
922 }
923 if err != nil {
924 return nil, err
925 }
926 bodyWritten = true
927 if d := cc.responseHeaderTimeout(); d != 0 {
928 timer := time.NewTimer(d)
929 defer timer.Stop()
930 respHeaderTimer = timer.C
931 }
932 }
933 }
934}
935
936// awaitOpenSlotForRequest waits until len(streams) < maxConcurrentStreams.
937// Must hold cc.mu.
938func (cc *ClientConn) awaitOpenSlotForRequest(req *http.Request) error {
939 var waitingForConn chan struct{}
940 var waitingForConnErr error // guarded by cc.mu
941 for {
942 cc.lastActive = time.Now()
943 if cc.closed || !cc.canTakeNewRequestLocked() {
944 return errClientConnUnusable
945 }
946 if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) {
947 if waitingForConn != nil {
948 close(waitingForConn)
949 }
950 return nil
951 }
952 // Unfortunately, we cannot wait on a condition variable and channel at
953 // the same time, so instead, we spin up a goroutine to check if the
954 // request is canceled while we wait for a slot to open in the connection.
955 if waitingForConn == nil {
956 waitingForConn = make(chan struct{})
957 go func() {
958 if err := awaitRequestCancel(req, waitingForConn); err != nil {
959 cc.mu.Lock()
960 waitingForConnErr = err
961 cc.cond.Broadcast()
962 cc.mu.Unlock()
963 }
964 }()
965 }
966 cc.pendingRequests++
967 cc.cond.Wait()
968 cc.pendingRequests--
969 if waitingForConnErr != nil {
970 return waitingForConnErr
971 }
972 }
973}
974
975// requires cc.wmu be held
976func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error {
977 first := true // first frame written (HEADERS is first, then CONTINUATION)
978 frameSize := int(cc.maxFrameSize)
979 for len(hdrs) > 0 && cc.werr == nil {
980 chunk := hdrs
981 if len(chunk) > frameSize {
982 chunk = chunk[:frameSize]
983 }
984 hdrs = hdrs[len(chunk):]
985 endHeaders := len(hdrs) == 0
986 if first {
987 cc.fr.WriteHeaders(HeadersFrameParam{
988 StreamID: streamID,
989 BlockFragment: chunk,
990 EndStream: endStream,
991 EndHeaders: endHeaders,
992 })
993 first = false
994 } else {
995 cc.fr.WriteContinuation(streamID, endHeaders, chunk)
996 }
997 }
998 // TODO(bradfitz): this Flush could potentially block (as
999 // could the WriteHeaders call(s) above), which means they
1000 // wouldn't respond to Request.Cancel being readable. That's
1001 // rare, but this should probably be in a goroutine.
1002 cc.bw.Flush()
1003 return cc.werr
1004}
1005
1006// internal error values; they don't escape to callers
1007var (
1008 // abort request body write; don't send cancel
1009 errStopReqBodyWrite = errors.New("http2: aborting request body write")
1010
1011 // abort request body write, but send stream reset of cancel.
1012 errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
1013)
1014
1015func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) {
1016 cc := cs.cc
1017 sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
1018 buf := cc.frameScratchBuffer()
1019 defer cc.putFrameScratchBuffer(buf)
1020
1021 defer func() {
1022 traceWroteRequest(cs.trace, err)
1023 // TODO: write h12Compare test showing whether
1024 // Request.Body is closed by the Transport,
1025 // and in multiple cases: server replies <=299 and >299
1026 // while still writing request body
1027 cerr := bodyCloser.Close()
1028 if err == nil {
1029 err = cerr
1030 }
1031 }()
1032
1033 req := cs.req
1034 hasTrailers := req.Trailer != nil
1035
1036 var sawEOF bool
1037 for !sawEOF {
1038 n, err := body.Read(buf)
1039 if err == io.EOF {
1040 sawEOF = true
1041 err = nil
1042 } else if err != nil {
1043 return err
1044 }
1045
1046 remain := buf[:n]
1047 for len(remain) > 0 && err == nil {
1048 var allowed int32
1049 allowed, err = cs.awaitFlowControl(len(remain))
1050 switch {
1051 case err == errStopReqBodyWrite:
1052 return err
1053 case err == errStopReqBodyWriteAndCancel:
1054 cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
1055 return err
1056 case err != nil:
1057 return err
1058 }
1059 cc.wmu.Lock()
1060 data := remain[:allowed]
1061 remain = remain[allowed:]
1062 sentEnd = sawEOF && len(remain) == 0 && !hasTrailers
1063 err = cc.fr.WriteData(cs.ID, sentEnd, data)
1064 if err == nil {
1065 // TODO(bradfitz): this flush is for latency, not bandwidth.
1066 // Most requests won't need this. Make this opt-in or
1067 // opt-out? Use some heuristic on the body type? Nagel-like
1068 // timers? Based on 'n'? Only last chunk of this for loop,
1069 // unless flow control tokens are low? For now, always.
1070 // If we change this, see comment below.
1071 err = cc.bw.Flush()
1072 }
1073 cc.wmu.Unlock()
1074 }
1075 if err != nil {
1076 return err
1077 }
1078 }
1079
1080 if sentEnd {
1081 // Already sent END_STREAM (which implies we have no
1082 // trailers) and flushed, because currently all
1083 // WriteData frames above get a flush. So we're done.
1084 return nil
1085 }
1086
1087 var trls []byte
1088 if hasTrailers {
1089 cc.mu.Lock()
1090 trls, err = cc.encodeTrailers(req)
1091 cc.mu.Unlock()
1092 if err != nil {
1093 cc.writeStreamReset(cs.ID, ErrCodeInternal, err)
1094 cc.forgetStreamID(cs.ID)
1095 return err
1096 }
1097 }
1098
1099 cc.wmu.Lock()
1100 defer cc.wmu.Unlock()
1101
1102 // Two ways to send END_STREAM: either with trailers, or
1103 // with an empty DATA frame.
1104 if len(trls) > 0 {
1105 err = cc.writeHeaders(cs.ID, true, trls)
1106 } else {
1107 err = cc.fr.WriteData(cs.ID, true, nil)
1108 }
1109 if ferr := cc.bw.Flush(); ferr != nil && err == nil {
1110 err = ferr
1111 }
1112 return err
1113}
1114
1115// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow
1116// control tokens from the server.
1117// It returns either the non-zero number of tokens taken or an error
1118// if the stream is dead.
1119func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
1120 cc := cs.cc
1121 cc.mu.Lock()
1122 defer cc.mu.Unlock()
1123 for {
1124 if cc.closed {
1125 return 0, errClientConnClosed
1126 }
1127 if cs.stopReqBody != nil {
1128 return 0, cs.stopReqBody
1129 }
1130 if err := cs.checkResetOrDone(); err != nil {
1131 return 0, err
1132 }
1133 if a := cs.flow.available(); a > 0 {
1134 take := a
1135 if int(take) > maxBytes {
1136
1137 take = int32(maxBytes) // can't truncate int; take is int32
1138 }
1139 if take > int32(cc.maxFrameSize) {
1140 take = int32(cc.maxFrameSize)
1141 }
1142 cs.flow.take(take)
1143 return take, nil
1144 }
1145 cc.cond.Wait()
1146 }
1147}
1148
1149type badStringError struct {
1150 what string
1151 str string
1152}
1153
1154func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
1155
1156// requires cc.mu be held.
1157func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) {
1158 cc.hbuf.Reset()
1159
1160 host := req.Host
1161 if host == "" {
1162 host = req.URL.Host
1163 }
1164 host, err := httplex.PunycodeHostPort(host)
1165 if err != nil {
1166 return nil, err
1167 }
1168
1169 var path string
1170 if req.Method != "CONNECT" {
1171 path = req.URL.RequestURI()
1172 if !validPseudoPath(path) {
1173 orig := path
1174 path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host)
1175 if !validPseudoPath(path) {
1176 if req.URL.Opaque != "" {
1177 return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque)
1178 } else {
1179 return nil, fmt.Errorf("invalid request :path %q", orig)
1180 }
1181 }
1182 }
1183 }
1184
1185 // Check for any invalid headers and return an error before we
1186 // potentially pollute our hpack state. (We want to be able to
1187 // continue to reuse the hpack encoder for future requests)
1188 for k, vv := range req.Header {
1189 if !httplex.ValidHeaderFieldName(k) {
1190 return nil, fmt.Errorf("invalid HTTP header name %q", k)
1191 }
1192 for _, v := range vv {
1193 if !httplex.ValidHeaderFieldValue(v) {
1194 return nil, fmt.Errorf("invalid HTTP header value %q for header %q", v, k)
1195 }
1196 }
1197 }
1198
1199 enumerateHeaders := func(f func(name, value string)) {
1200 // 8.1.2.3 Request Pseudo-Header Fields
1201 // The :path pseudo-header field includes the path and query parts of the
1202 // target URI (the path-absolute production and optionally a '?' character
1203 // followed by the query production (see Sections 3.3 and 3.4 of
1204 // [RFC3986]).
1205 f(":authority", host)
1206 f(":method", req.Method)
1207 if req.Method != "CONNECT" {
1208 f(":path", path)
1209 f(":scheme", req.URL.Scheme)
1210 }
1211 if trailers != "" {
1212 f("trailer", trailers)
1213 }
1214
1215 var didUA bool
1216 for k, vv := range req.Header {
1217 if strings.EqualFold(k, "host") || strings.EqualFold(k, "content-length") {
1218 // Host is :authority, already sent.
1219 // Content-Length is automatic, set below.
1220 continue
1221 } else if strings.EqualFold(k, "connection") || strings.EqualFold(k, "proxy-connection") ||
1222 strings.EqualFold(k, "transfer-encoding") || strings.EqualFold(k, "upgrade") ||
1223 strings.EqualFold(k, "keep-alive") {
1224 // Per 8.1.2.2 Connection-Specific Header
1225 // Fields, don't send connection-specific
1226 // fields. We have already checked if any
1227 // are error-worthy so just ignore the rest.
1228 continue
1229 } else if strings.EqualFold(k, "user-agent") {
1230 // Match Go's http1 behavior: at most one
1231 // User-Agent. If set to nil or empty string,
1232 // then omit it. Otherwise if not mentioned,
1233 // include the default (below).
1234 didUA = true
1235 if len(vv) < 1 {
1236 continue
1237 }
1238 vv = vv[:1]
1239 if vv[0] == "" {
1240 continue
1241 }
1242
1243 }
1244
1245 for _, v := range vv {
1246 f(k, v)
1247 }
1248 }
1249 if shouldSendReqContentLength(req.Method, contentLength) {
1250 f("content-length", strconv.FormatInt(contentLength, 10))
1251 }
1252 if addGzipHeader {
1253 f("accept-encoding", "gzip")
1254 }
1255 if !didUA {
1256 f("user-agent", defaultUserAgent)
1257 }
1258 }
1259
1260 // Do a first pass over the headers counting bytes to ensure
1261 // we don't exceed cc.peerMaxHeaderListSize. This is done as a
1262 // separate pass before encoding the headers to prevent
1263 // modifying the hpack state.
1264 hlSize := uint64(0)
1265 enumerateHeaders(func(name, value string) {
1266 hf := hpack.HeaderField{Name: name, Value: value}
1267 hlSize += uint64(hf.Size())
1268 })
1269
1270 if hlSize > cc.peerMaxHeaderListSize {
1271 return nil, errRequestHeaderListSize
1272 }
1273
1274 // Header list size is ok. Write the headers.
1275 enumerateHeaders(func(name, value string) {
1276 cc.writeHeader(strings.ToLower(name), value)
1277 })
1278
1279 return cc.hbuf.Bytes(), nil
1280}
1281
1282// shouldSendReqContentLength reports whether the http2.Transport should send
1283// a "content-length" request header. This logic is basically a copy of the net/http
1284// transferWriter.shouldSendContentLength.
1285// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown).
1286// -1 means unknown.
1287func shouldSendReqContentLength(method string, contentLength int64) bool {
1288 if contentLength > 0 {
1289 return true
1290 }
1291 if contentLength < 0 {
1292 return false
1293 }
1294 // For zero bodies, whether we send a content-length depends on the method.
1295 // It also kinda doesn't matter for http2 either way, with END_STREAM.
1296 switch method {
1297 case "POST", "PUT", "PATCH":
1298 return true
1299 default:
1300 return false
1301 }
1302}
1303
1304// requires cc.mu be held.
1305func (cc *ClientConn) encodeTrailers(req *http.Request) ([]byte, error) {
1306 cc.hbuf.Reset()
1307
1308 hlSize := uint64(0)
1309 for k, vv := range req.Trailer {
1310 for _, v := range vv {
1311 hf := hpack.HeaderField{Name: k, Value: v}
1312 hlSize += uint64(hf.Size())
1313 }
1314 }
1315 if hlSize > cc.peerMaxHeaderListSize {
1316 return nil, errRequestHeaderListSize
1317 }
1318
1319 for k, vv := range req.Trailer {
1320 // Transfer-Encoding, etc.. have already been filtered at the
1321 // start of RoundTrip
1322 lowKey := strings.ToLower(k)
1323 for _, v := range vv {
1324 cc.writeHeader(lowKey, v)
1325 }
1326 }
1327 return cc.hbuf.Bytes(), nil
1328}
1329
1330func (cc *ClientConn) writeHeader(name, value string) {
1331 if VerboseLogs {
1332 log.Printf("http2: Transport encoding header %q = %q", name, value)
1333 }
1334 cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
1335}
1336
1337type resAndError struct {
1338 res *http.Response
1339 err error
1340}
1341
1342// requires cc.mu be held.
1343func (cc *ClientConn) newStream() *clientStream {
1344 cs := &clientStream{
1345 cc: cc,
1346 ID: cc.nextStreamID,
1347 resc: make(chan resAndError, 1),
1348 peerReset: make(chan struct{}),
1349 done: make(chan struct{}),
1350 }
1351 cs.flow.add(int32(cc.initialWindowSize))
1352 cs.flow.setConnFlow(&cc.flow)
1353 cs.inflow.add(transportDefaultStreamFlow)
1354 cs.inflow.setConnFlow(&cc.inflow)
1355 cc.nextStreamID += 2
1356 cc.streams[cs.ID] = cs
1357 return cs
1358}
1359
1360func (cc *ClientConn) forgetStreamID(id uint32) {
1361 cc.streamByID(id, true)
1362}
1363
1364func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
1365 cc.mu.Lock()
1366 defer cc.mu.Unlock()
1367 cs := cc.streams[id]
1368 if andRemove && cs != nil && !cc.closed {
1369 cc.lastActive = time.Now()
1370 delete(cc.streams, id)
1371 if len(cc.streams) == 0 && cc.idleTimer != nil {
1372 cc.idleTimer.Reset(cc.idleTimeout)
1373 }
1374 close(cs.done)
1375 // Wake up checkResetOrDone via clientStream.awaitFlowControl and
1376 // wake up RoundTrip if there is a pending request.
1377 cc.cond.Broadcast()
1378 }
1379 return cs
1380}
1381
1382// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
1383type clientConnReadLoop struct {
1384 cc *ClientConn
1385 activeRes map[uint32]*clientStream // keyed by streamID
1386 closeWhenIdle bool
1387}
1388
1389// readLoop runs in its own goroutine and reads and dispatches frames.
1390func (cc *ClientConn) readLoop() {
1391 rl := &clientConnReadLoop{
1392 cc: cc,
1393 activeRes: make(map[uint32]*clientStream),
1394 }
1395
1396 defer rl.cleanup()
1397 cc.readerErr = rl.run()
1398 if ce, ok := cc.readerErr.(ConnectionError); ok {
1399 cc.wmu.Lock()
1400 cc.fr.WriteGoAway(0, ErrCode(ce), nil)
1401 cc.wmu.Unlock()
1402 }
1403}
1404
1405// GoAwayError is returned by the Transport when the server closes the
1406// TCP connection after sending a GOAWAY frame.
1407type GoAwayError struct {
1408 LastStreamID uint32
1409 ErrCode ErrCode
1410 DebugData string
1411}
1412
1413func (e GoAwayError) Error() string {
1414 return fmt.Sprintf("http2: server sent GOAWAY and closed the connection; LastStreamID=%v, ErrCode=%v, debug=%q",
1415 e.LastStreamID, e.ErrCode, e.DebugData)
1416}
1417
1418func isEOFOrNetReadError(err error) bool {
1419 if err == io.EOF {
1420 return true
1421 }
1422 ne, ok := err.(*net.OpError)
1423 return ok && ne.Op == "read"
1424}
1425
1426func (rl *clientConnReadLoop) cleanup() {
1427 cc := rl.cc
1428 defer cc.tconn.Close()
1429 defer cc.t.connPool().MarkDead(cc)
1430 defer close(cc.readerDone)
1431
1432 if cc.idleTimer != nil {
1433 cc.idleTimer.Stop()
1434 }
1435
1436 // Close any response bodies if the server closes prematurely.
1437 // TODO: also do this if we've written the headers but not
1438 // gotten a response yet.
1439 err := cc.readerErr
1440 cc.mu.Lock()
1441 if cc.goAway != nil && isEOFOrNetReadError(err) {
1442 err = GoAwayError{
1443 LastStreamID: cc.goAway.LastStreamID,
1444 ErrCode: cc.goAway.ErrCode,
1445 DebugData: cc.goAwayDebug,
1446 }
1447 } else if err == io.EOF {
1448 err = io.ErrUnexpectedEOF
1449 }
1450 for _, cs := range rl.activeRes {
1451 cs.bufPipe.CloseWithError(err)
1452 }
1453 for _, cs := range cc.streams {
1454 select {
1455 case cs.resc <- resAndError{err: err}:
1456 default:
1457 }
1458 close(cs.done)
1459 }
1460 cc.closed = true
1461 cc.cond.Broadcast()
1462 cc.mu.Unlock()
1463}
1464
1465func (rl *clientConnReadLoop) run() error {
1466 cc := rl.cc
1467 rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
1468 gotReply := false // ever saw a HEADERS reply
1469 gotSettings := false
1470 for {
1471 f, err := cc.fr.ReadFrame()
1472 if err != nil {
1473 cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
1474 }
1475 if se, ok := err.(StreamError); ok {
1476 if cs := cc.streamByID(se.StreamID, false); cs != nil {
1477 cs.cc.writeStreamReset(cs.ID, se.Code, err)
1478 cs.cc.forgetStreamID(cs.ID)
1479 if se.Cause == nil {
1480 se.Cause = cc.fr.errDetail
1481 }
1482 rl.endStreamError(cs, se)
1483 }
1484 continue
1485 } else if err != nil {
1486 return err
1487 }
1488 if VerboseLogs {
1489 cc.vlogf("http2: Transport received %s", summarizeFrame(f))
1490 }
1491 if !gotSettings {
1492 if _, ok := f.(*SettingsFrame); !ok {
1493 cc.logf("protocol error: received %T before a SETTINGS frame", f)
1494 return ConnectionError(ErrCodeProtocol)
1495 }
1496 gotSettings = true
1497 }
1498 maybeIdle := false // whether frame might transition us to idle
1499
1500 switch f := f.(type) {
1501 case *MetaHeadersFrame:
1502 err = rl.processHeaders(f)
1503 maybeIdle = true
1504 gotReply = true
1505 case *DataFrame:
1506 err = rl.processData(f)
1507 maybeIdle = true
1508 case *GoAwayFrame:
1509 err = rl.processGoAway(f)
1510 maybeIdle = true
1511 case *RSTStreamFrame:
1512 err = rl.processResetStream(f)
1513 maybeIdle = true
1514 case *SettingsFrame:
1515 err = rl.processSettings(f)
1516 case *PushPromiseFrame:
1517 err = rl.processPushPromise(f)
1518 case *WindowUpdateFrame:
1519 err = rl.processWindowUpdate(f)
1520 case *PingFrame:
1521 err = rl.processPing(f)
1522 default:
1523 cc.logf("Transport: unhandled response frame type %T", f)
1524 }
1525 if err != nil {
1526 if VerboseLogs {
1527 cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, summarizeFrame(f), err)
1528 }
1529 return err
1530 }
1531 if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
1532 cc.closeIfIdle()
1533 }
1534 }
1535}
1536
1537func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error {
1538 cc := rl.cc
1539 cs := cc.streamByID(f.StreamID, f.StreamEnded())
1540 if cs == nil {
1541 // We'd get here if we canceled a request while the
1542 // server had its response still in flight. So if this
1543 // was just something we canceled, ignore it.
1544 return nil
1545 }
1546 if !cs.firstByte {
1547 if cs.trace != nil {
1548 // TODO(bradfitz): move first response byte earlier,
1549 // when we first read the 9 byte header, not waiting
1550 // until all the HEADERS+CONTINUATION frames have been
1551 // merged. This works for now.
1552 traceFirstResponseByte(cs.trace)
1553 }
1554 cs.firstByte = true
1555 }
1556 if !cs.pastHeaders {
1557 cs.pastHeaders = true
1558 } else {
1559 return rl.processTrailers(cs, f)
1560 }
1561
1562 res, err := rl.handleResponse(cs, f)
1563 if err != nil {
1564 if _, ok := err.(ConnectionError); ok {
1565 return err
1566 }
1567 // Any other error type is a stream error.
1568 cs.cc.writeStreamReset(f.StreamID, ErrCodeProtocol, err)
1569 cs.resc <- resAndError{err: err}
1570 return nil // return nil from process* funcs to keep conn alive
1571 }
1572 if res == nil {
1573 // (nil, nil) special case. See handleResponse docs.
1574 return nil
1575 }
1576 if res.Body != noBody {
1577 rl.activeRes[cs.ID] = cs
1578 }
1579 cs.resTrailer = &res.Trailer
1580 cs.resc <- resAndError{res: res}
1581 return nil
1582}
1583
1584// may return error types nil, or ConnectionError. Any other error value
1585// is a StreamError of type ErrCodeProtocol. The returned error in that case
1586// is the detail.
1587//
1588// As a special case, handleResponse may return (nil, nil) to skip the
1589// frame (currently only used for 100 expect continue). This special
1590// case is going away after Issue 13851 is fixed.
1591func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {
1592 if f.Truncated {
1593 return nil, errResponseHeaderListSize
1594 }
1595
1596 status := f.PseudoValue("status")
1597 if status == "" {
1598 return nil, errors.New("missing status pseudo header")
1599 }
1600 statusCode, err := strconv.Atoi(status)
1601 if err != nil {
1602 return nil, errors.New("malformed non-numeric status pseudo header")
1603 }
1604
1605 if statusCode == 100 {
1606 traceGot100Continue(cs.trace)
1607 if cs.on100 != nil {
1608 cs.on100() // forces any write delay timer to fire
1609 }
1610 cs.pastHeaders = false // do it all again
1611 return nil, nil
1612 }
1613
1614 header := make(http.Header)
1615 res := &http.Response{
1616 Proto: "HTTP/2.0",
1617 ProtoMajor: 2,
1618 Header: header,
1619 StatusCode: statusCode,
1620 Status: status + " " + http.StatusText(statusCode),
1621 }
1622 for _, hf := range f.RegularFields() {
1623 key := http.CanonicalHeaderKey(hf.Name)
1624 if key == "Trailer" {
1625 t := res.Trailer
1626 if t == nil {
1627 t = make(http.Header)
1628 res.Trailer = t
1629 }
1630 foreachHeaderElement(hf.Value, func(v string) {
1631 t[http.CanonicalHeaderKey(v)] = nil
1632 })
1633 } else {
1634 header[key] = append(header[key], hf.Value)
1635 }
1636 }
1637
1638 streamEnded := f.StreamEnded()
1639 isHead := cs.req.Method == "HEAD"
1640 if !streamEnded || isHead {
1641 res.ContentLength = -1
1642 if clens := res.Header["Content-Length"]; len(clens) == 1 {
1643 if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
1644 res.ContentLength = clen64
1645 } else {
1646 // TODO: care? unlike http/1, it won't mess up our framing, so it's
1647 // more safe smuggling-wise to ignore.
1648 }
1649 } else if len(clens) > 1 {
1650 // TODO: care? unlike http/1, it won't mess up our framing, so it's
1651 // more safe smuggling-wise to ignore.
1652 }
1653 }
1654
1655 if streamEnded || isHead {
1656 res.Body = noBody
1657 return res, nil
1658 }
1659
1660 cs.bufPipe = pipe{b: &dataBuffer{expected: res.ContentLength}}
1661 cs.bytesRemain = res.ContentLength
1662 res.Body = transportResponseBody{cs}
1663 go cs.awaitRequestCancel(cs.req)
1664
1665 if cs.requestedGzip && res.Header.Get("Content-Encoding") == "gzip" {
1666 res.Header.Del("Content-Encoding")
1667 res.Header.Del("Content-Length")
1668 res.ContentLength = -1
1669 res.Body = &gzipReader{body: res.Body}
1670 setResponseUncompressed(res)
1671 }
1672 return res, nil
1673}
1674
1675func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFrame) error {
1676 if cs.pastTrailers {
1677 // Too many HEADERS frames for this stream.
1678 return ConnectionError(ErrCodeProtocol)
1679 }
1680 cs.pastTrailers = true
1681 if !f.StreamEnded() {
1682 // We expect that any headers for trailers also
1683 // has END_STREAM.
1684 return ConnectionError(ErrCodeProtocol)
1685 }
1686 if len(f.PseudoFields()) > 0 {
1687 // No pseudo header fields are defined for trailers.
1688 // TODO: ConnectionError might be overly harsh? Check.
1689 return ConnectionError(ErrCodeProtocol)
1690 }
1691
1692 trailer := make(http.Header)
1693 for _, hf := range f.RegularFields() {
1694 key := http.CanonicalHeaderKey(hf.Name)
1695 trailer[key] = append(trailer[key], hf.Value)
1696 }
1697 cs.trailer = trailer
1698
1699 rl.endStream(cs)
1700 return nil
1701}
1702
1703// transportResponseBody is the concrete type of Transport.RoundTrip's
1704// Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body.
1705// On Close it sends RST_STREAM if EOF wasn't already seen.
1706type transportResponseBody struct {
1707 cs *clientStream
1708}
1709
1710func (b transportResponseBody) Read(p []byte) (n int, err error) {
1711 cs := b.cs
1712 cc := cs.cc
1713
1714 if cs.readErr != nil {
1715 return 0, cs.readErr
1716 }
1717 n, err = b.cs.bufPipe.Read(p)
1718 if cs.bytesRemain != -1 {
1719 if int64(n) > cs.bytesRemain {
1720 n = int(cs.bytesRemain)
1721 if err == nil {
1722 err = errors.New("net/http: server replied with more than declared Content-Length; truncated")
1723 cc.writeStreamReset(cs.ID, ErrCodeProtocol, err)
1724 }
1725 cs.readErr = err
1726 return int(cs.bytesRemain), err
1727 }
1728 cs.bytesRemain -= int64(n)
1729 if err == io.EOF && cs.bytesRemain > 0 {
1730 err = io.ErrUnexpectedEOF
1731 cs.readErr = err
1732 return n, err
1733 }
1734 }
1735 if n == 0 {
1736 // No flow control tokens to send back.
1737 return
1738 }
1739
1740 cc.mu.Lock()
1741 defer cc.mu.Unlock()
1742
1743 var connAdd, streamAdd int32
1744 // Check the conn-level first, before the stream-level.
1745 if v := cc.inflow.available(); v < transportDefaultConnFlow/2 {
1746 connAdd = transportDefaultConnFlow - v
1747 cc.inflow.add(connAdd)
1748 }
1749 if err == nil { // No need to refresh if the stream is over or failed.
1750 // Consider any buffered body data (read from the conn but not
1751 // consumed by the client) when computing flow control for this
1752 // stream.
1753 v := int(cs.inflow.available()) + cs.bufPipe.Len()
1754 if v < transportDefaultStreamFlow-transportDefaultStreamMinRefresh {
1755 streamAdd = int32(transportDefaultStreamFlow - v)
1756 cs.inflow.add(streamAdd)
1757 }
1758 }
1759 if connAdd != 0 || streamAdd != 0 {
1760 cc.wmu.Lock()
1761 defer cc.wmu.Unlock()
1762 if connAdd != 0 {
1763 cc.fr.WriteWindowUpdate(0, mustUint31(connAdd))
1764 }
1765 if streamAdd != 0 {
1766 cc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd))
1767 }
1768 cc.bw.Flush()
1769 }
1770 return
1771}
1772
1773var errClosedResponseBody = errors.New("http2: response body closed")
1774
1775func (b transportResponseBody) Close() error {
1776 cs := b.cs
1777 cc := cs.cc
1778
1779 serverSentStreamEnd := cs.bufPipe.Err() == io.EOF
1780 unread := cs.bufPipe.Len()
1781
1782 if unread > 0 || !serverSentStreamEnd {
1783 cc.mu.Lock()
1784 cc.wmu.Lock()
1785 if !serverSentStreamEnd {
1786 cc.fr.WriteRSTStream(cs.ID, ErrCodeCancel)
1787 cs.didReset = true
1788 }
1789 // Return connection-level flow control.
1790 if unread > 0 {
1791 cc.inflow.add(int32(unread))
1792 cc.fr.WriteWindowUpdate(0, uint32(unread))
1793 }
1794 cc.bw.Flush()
1795 cc.wmu.Unlock()
1796 cc.mu.Unlock()
1797 }
1798
1799 cs.bufPipe.BreakWithError(errClosedResponseBody)
1800 cc.forgetStreamID(cs.ID)
1801 return nil
1802}
1803
1804func (rl *clientConnReadLoop) processData(f *DataFrame) error {
1805 cc := rl.cc
1806 cs := cc.streamByID(f.StreamID, f.StreamEnded())
1807 data := f.Data()
1808 if cs == nil {
1809 cc.mu.Lock()
1810 neverSent := cc.nextStreamID
1811 cc.mu.Unlock()
1812 if f.StreamID >= neverSent {
1813 // We never asked for this.
1814 cc.logf("http2: Transport received unsolicited DATA frame; closing connection")
1815 return ConnectionError(ErrCodeProtocol)
1816 }
1817 // We probably did ask for this, but canceled. Just ignore it.
1818 // TODO: be stricter here? only silently ignore things which
1819 // we canceled, but not things which were closed normally
1820 // by the peer? Tough without accumulating too much state.
1821
1822 // But at least return their flow control:
1823 if f.Length > 0 {
1824 cc.mu.Lock()
1825 cc.inflow.add(int32(f.Length))
1826 cc.mu.Unlock()
1827
1828 cc.wmu.Lock()
1829 cc.fr.WriteWindowUpdate(0, uint32(f.Length))
1830 cc.bw.Flush()
1831 cc.wmu.Unlock()
1832 }
1833 return nil
1834 }
1835 if !cs.firstByte {
1836 cc.logf("protocol error: received DATA before a HEADERS frame")
1837 rl.endStreamError(cs, StreamError{
1838 StreamID: f.StreamID,
1839 Code: ErrCodeProtocol,
1840 })
1841 return nil
1842 }
1843 if f.Length > 0 {
1844 // Check connection-level flow control.
1845 cc.mu.Lock()
1846 if cs.inflow.available() >= int32(f.Length) {
1847 cs.inflow.take(int32(f.Length))
1848 } else {
1849 cc.mu.Unlock()
1850 return ConnectionError(ErrCodeFlowControl)
1851 }
1852 // Return any padded flow control now, since we won't
1853 // refund it later on body reads.
1854 var refund int
1855 if pad := int(f.Length) - len(data); pad > 0 {
1856 refund += pad
1857 }
1858 // Return len(data) now if the stream is already closed,
1859 // since data will never be read.
1860 didReset := cs.didReset
1861 if didReset {
1862 refund += len(data)
1863 }
1864 if refund > 0 {
1865 cc.inflow.add(int32(refund))
1866 cc.wmu.Lock()
1867 cc.fr.WriteWindowUpdate(0, uint32(refund))
1868 if !didReset {
1869 cs.inflow.add(int32(refund))
1870 cc.fr.WriteWindowUpdate(cs.ID, uint32(refund))
1871 }
1872 cc.bw.Flush()
1873 cc.wmu.Unlock()
1874 }
1875 cc.mu.Unlock()
1876
1877 if len(data) > 0 && !didReset {
1878 if _, err := cs.bufPipe.Write(data); err != nil {
1879 rl.endStreamError(cs, err)
1880 return err
1881 }
1882 }
1883 }
1884
1885 if f.StreamEnded() {
1886 rl.endStream(cs)
1887 }
1888 return nil
1889}
1890
1891var errInvalidTrailers = errors.New("http2: invalid trailers")
1892
1893func (rl *clientConnReadLoop) endStream(cs *clientStream) {
1894 // TODO: check that any declared content-length matches, like
1895 // server.go's (*stream).endStream method.
1896 rl.endStreamError(cs, nil)
1897}
1898
1899func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) {
1900 var code func()
1901 if err == nil {
1902 err = io.EOF
1903 code = cs.copyTrailers
1904 }
1905 cs.bufPipe.closeWithErrorAndCode(err, code)
1906 delete(rl.activeRes, cs.ID)
1907 if isConnectionCloseRequest(cs.req) {
1908 rl.closeWhenIdle = true
1909 }
1910
1911 select {
1912 case cs.resc <- resAndError{err: err}:
1913 default:
1914 }
1915}
1916
1917func (cs *clientStream) copyTrailers() {
1918 for k, vv := range cs.trailer {
1919 t := cs.resTrailer
1920 if *t == nil {
1921 *t = make(http.Header)
1922 }
1923 (*t)[k] = vv
1924 }
1925}
1926
1927func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {
1928 cc := rl.cc
1929 cc.t.connPool().MarkDead(cc)
1930 if f.ErrCode != 0 {
1931 // TODO: deal with GOAWAY more. particularly the error code
1932 cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode)
1933 }
1934 cc.setGoAway(f)
1935 return nil
1936}
1937
1938func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error {
1939 cc := rl.cc
1940 cc.mu.Lock()
1941 defer cc.mu.Unlock()
1942
1943 if f.IsAck() {
1944 if cc.wantSettingsAck {
1945 cc.wantSettingsAck = false
1946 return nil
1947 }
1948 return ConnectionError(ErrCodeProtocol)
1949 }
1950
1951 err := f.ForeachSetting(func(s Setting) error {
1952 switch s.ID {
1953 case SettingMaxFrameSize:
1954 cc.maxFrameSize = s.Val
1955 case SettingMaxConcurrentStreams:
1956 cc.maxConcurrentStreams = s.Val
1957 case SettingMaxHeaderListSize:
1958 cc.peerMaxHeaderListSize = uint64(s.Val)
1959 case SettingInitialWindowSize:
1960 // Values above the maximum flow-control
1961 // window size of 2^31-1 MUST be treated as a
1962 // connection error (Section 5.4.1) of type
1963 // FLOW_CONTROL_ERROR.
1964 if s.Val > math.MaxInt32 {
1965 return ConnectionError(ErrCodeFlowControl)
1966 }
1967
1968 // Adjust flow control of currently-open
1969 // frames by the difference of the old initial
1970 // window size and this one.
1971 delta := int32(s.Val) - int32(cc.initialWindowSize)
1972 for _, cs := range cc.streams {
1973 cs.flow.add(delta)
1974 }
1975 cc.cond.Broadcast()
1976
1977 cc.initialWindowSize = s.Val
1978 default:
1979 // TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably.
1980 cc.vlogf("Unhandled Setting: %v", s)
1981 }
1982 return nil
1983 })
1984 if err != nil {
1985 return err
1986 }
1987
1988 cc.wmu.Lock()
1989 defer cc.wmu.Unlock()
1990
1991 cc.fr.WriteSettingsAck()
1992 cc.bw.Flush()
1993 return cc.werr
1994}
1995
1996func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
1997 cc := rl.cc
1998 cs := cc.streamByID(f.StreamID, false)
1999 if f.StreamID != 0 && cs == nil {
2000 return nil
2001 }
2002
2003 cc.mu.Lock()
2004 defer cc.mu.Unlock()
2005
2006 fl := &cc.flow
2007 if cs != nil {
2008 fl = &cs.flow
2009 }
2010 if !fl.add(int32(f.Increment)) {
2011 return ConnectionError(ErrCodeFlowControl)
2012 }
2013 cc.cond.Broadcast()
2014 return nil
2015}
2016
2017func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {
2018 cs := rl.cc.streamByID(f.StreamID, true)
2019 if cs == nil {
2020 // TODO: return error if server tries to RST_STEAM an idle stream
2021 return nil
2022 }
2023 select {
2024 case <-cs.peerReset:
2025 // Already reset.
2026 // This is the only goroutine
2027 // which closes this, so there
2028 // isn't a race.
2029 default:
2030 err := streamError(cs.ID, f.ErrCode)
2031 cs.resetErr = err
2032 close(cs.peerReset)
2033 cs.bufPipe.CloseWithError(err)
2034 cs.cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
2035 }
2036 delete(rl.activeRes, cs.ID)
2037 return nil
2038}
2039
2040// Ping sends a PING frame to the server and waits for the ack.
2041// Public implementation is in go17.go and not_go17.go
2042func (cc *ClientConn) ping(ctx contextContext) error {
2043 c := make(chan struct{})
2044 // Generate a random payload
2045 var p [8]byte
2046 for {
2047 if _, err := rand.Read(p[:]); err != nil {
2048 return err
2049 }
2050 cc.mu.Lock()
2051 // check for dup before insert
2052 if _, found := cc.pings[p]; !found {
2053 cc.pings[p] = c
2054 cc.mu.Unlock()
2055 break
2056 }
2057 cc.mu.Unlock()
2058 }
2059 cc.wmu.Lock()
2060 if err := cc.fr.WritePing(false, p); err != nil {
2061 cc.wmu.Unlock()
2062 return err
2063 }
2064 if err := cc.bw.Flush(); err != nil {
2065 cc.wmu.Unlock()
2066 return err
2067 }
2068 cc.wmu.Unlock()
2069 select {
2070 case <-c:
2071 return nil
2072 case <-ctx.Done():
2073 return ctx.Err()
2074 case <-cc.readerDone:
2075 // connection closed
2076 return cc.readerErr
2077 }
2078}
2079
2080func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
2081 if f.IsAck() {
2082 cc := rl.cc
2083 cc.mu.Lock()
2084 defer cc.mu.Unlock()
2085 // If ack, notify listener if any
2086 if c, ok := cc.pings[f.Data]; ok {
2087 close(c)
2088 delete(cc.pings, f.Data)
2089 }
2090 return nil
2091 }
2092 cc := rl.cc
2093 cc.wmu.Lock()
2094 defer cc.wmu.Unlock()
2095 if err := cc.fr.WritePing(true, f.Data); err != nil {
2096 return err
2097 }
2098 return cc.bw.Flush()
2099}
2100
2101func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error {
2102 // We told the peer we don't want them.
2103 // Spec says:
2104 // "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH
2105 // setting of the peer endpoint is set to 0. An endpoint that
2106 // has set this setting and has received acknowledgement MUST
2107 // treat the receipt of a PUSH_PROMISE frame as a connection
2108 // error (Section 5.4.1) of type PROTOCOL_ERROR."
2109 return ConnectionError(ErrCodeProtocol)
2110}
2111
2112func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) {
2113 // TODO: map err to more interesting error codes, once the
2114 // HTTP community comes up with some. But currently for
2115 // RST_STREAM there's no equivalent to GOAWAY frame's debug
2116 // data, and the error codes are all pretty vague ("cancel").
2117 cc.wmu.Lock()
2118 cc.fr.WriteRSTStream(streamID, code)
2119 cc.bw.Flush()
2120 cc.wmu.Unlock()
2121}
2122
2123var (
2124 errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
2125 errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit")
2126 errPseudoTrailers = errors.New("http2: invalid pseudo header in trailers")
2127)
2128
2129func (cc *ClientConn) logf(format string, args ...interface{}) {
2130 cc.t.logf(format, args...)
2131}
2132
2133func (cc *ClientConn) vlogf(format string, args ...interface{}) {
2134 cc.t.vlogf(format, args...)
2135}
2136
2137func (t *Transport) vlogf(format string, args ...interface{}) {
2138 if VerboseLogs {
2139 t.logf(format, args...)
2140 }
2141}
2142
2143func (t *Transport) logf(format string, args ...interface{}) {
2144 log.Printf(format, args...)
2145}
2146
2147var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil))
2148
2149func strSliceContains(ss []string, s string) bool {
2150 for _, v := range ss {
2151 if v == s {
2152 return true
2153 }
2154 }
2155 return false
2156}
2157
2158type erringRoundTripper struct{ err error }
2159
2160func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }
2161
2162// gzipReader wraps a response body so it can lazily
2163// call gzip.NewReader on the first call to Read
2164type gzipReader struct {
2165 body io.ReadCloser // underlying Response.Body
2166 zr *gzip.Reader // lazily-initialized gzip reader
2167 zerr error // sticky error
2168}
2169
2170func (gz *gzipReader) Read(p []byte) (n int, err error) {
2171 if gz.zerr != nil {
2172 return 0, gz.zerr
2173 }
2174 if gz.zr == nil {
2175 gz.zr, err = gzip.NewReader(gz.body)
2176 if err != nil {
2177 gz.zerr = err
2178 return 0, err
2179 }
2180 }
2181 return gz.zr.Read(p)
2182}
2183
2184func (gz *gzipReader) Close() error {
2185 return gz.body.Close()
2186}
2187
2188type errorReader struct{ err error }
2189
2190func (r errorReader) Read(p []byte) (int, error) { return 0, r.err }
2191
2192// bodyWriterState encapsulates various state around the Transport's writing
2193// of the request body, particularly regarding doing delayed writes of the body
2194// when the request contains "Expect: 100-continue".
2195type bodyWriterState struct {
2196 cs *clientStream
2197 timer *time.Timer // if non-nil, we're doing a delayed write
2198 fnonce *sync.Once // to call fn with
2199 fn func() // the code to run in the goroutine, writing the body
2200 resc chan error // result of fn's execution
2201 delay time.Duration // how long we should delay a delayed write for
2202}
2203
2204func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s bodyWriterState) {
2205 s.cs = cs
2206 if body == nil {
2207 return
2208 }
2209 resc := make(chan error, 1)
2210 s.resc = resc
2211 s.fn = func() {
2212 cs.cc.mu.Lock()
2213 cs.startedWrite = true
2214 cs.cc.mu.Unlock()
2215 resc <- cs.writeRequestBody(body, cs.req.Body)
2216 }
2217 s.delay = t.expectContinueTimeout()
2218 if s.delay == 0 ||
2219 !httplex.HeaderValuesContainsToken(
2220 cs.req.Header["Expect"],
2221 "100-continue") {
2222 return
2223 }
2224 s.fnonce = new(sync.Once)
2225
2226 // Arm the timer with a very large duration, which we'll
2227 // intentionally lower later. It has to be large now because
2228 // we need a handle to it before writing the headers, but the
2229 // s.delay value is defined to not start until after the
2230 // request headers were written.
2231 const hugeDuration = 365 * 24 * time.Hour
2232 s.timer = time.AfterFunc(hugeDuration, func() {
2233 s.fnonce.Do(s.fn)
2234 })
2235 return
2236}
2237
2238func (s bodyWriterState) cancel() {
2239 if s.timer != nil {
2240 s.timer.Stop()
2241 }
2242}
2243
2244func (s bodyWriterState) on100() {
2245 if s.timer == nil {
2246 // If we didn't do a delayed write, ignore the server's
2247 // bogus 100 continue response.
2248 return
2249 }
2250 s.timer.Stop()
2251 go func() { s.fnonce.Do(s.fn) }()
2252}
2253
2254// scheduleBodyWrite starts writing the body, either immediately (in
2255// the common case) or after the delay timeout. It should not be
2256// called until after the headers have been written.
2257func (s bodyWriterState) scheduleBodyWrite() {
2258 if s.timer == nil {
2259 // We're not doing a delayed write (see
2260 // getBodyWriterState), so just start the writing
2261 // goroutine immediately.
2262 go s.fn()
2263 return
2264 }
2265 traceWait100Continue(s.cs.trace)
2266 if s.timer.Stop() {
2267 s.timer.Reset(s.delay)
2268 }
2269}
2270
2271// isConnectionCloseRequest reports whether req should use its own
2272// connection for a single request and then close the connection.
2273func isConnectionCloseRequest(req *http.Request) bool {
2274 return req.Close || httplex.HeaderValuesContainsToken(req.Header["Connection"], "close")
2275}
diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go
new file mode 100644
index 0000000..6b0dfae
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/write.go
@@ -0,0 +1,370 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import (
8 "bytes"
9 "fmt"
10 "log"
11 "net/http"
12 "net/url"
13 "time"
14
15 "golang.org/x/net/http2/hpack"
16 "golang.org/x/net/lex/httplex"
17)
18
19// writeFramer is implemented by any type that is used to write frames.
20type writeFramer interface {
21 writeFrame(writeContext) error
22
23 // staysWithinBuffer reports whether this writer promises that
24 // it will only write less than or equal to size bytes, and it
25 // won't Flush the write context.
26 staysWithinBuffer(size int) bool
27}
28
29// writeContext is the interface needed by the various frame writer
30// types below. All the writeFrame methods below are scheduled via the
31// frame writing scheduler (see writeScheduler in writesched.go).
32//
33// This interface is implemented by *serverConn.
34//
35// TODO: decide whether to a) use this in the client code (which didn't
36// end up using this yet, because it has a simpler design, not
37// currently implementing priorities), or b) delete this and
38// make the server code a bit more concrete.
39type writeContext interface {
40 Framer() *Framer
41 Flush() error
42 CloseConn() error
43 // HeaderEncoder returns an HPACK encoder that writes to the
44 // returned buffer.
45 HeaderEncoder() (*hpack.Encoder, *bytes.Buffer)
46}
47
48// writeEndsStream reports whether w writes a frame that will transition
49// the stream to a half-closed local state. This returns false for RST_STREAM,
50// which closes the entire stream (not just the local half).
51func writeEndsStream(w writeFramer) bool {
52 switch v := w.(type) {
53 case *writeData:
54 return v.endStream
55 case *writeResHeaders:
56 return v.endStream
57 case nil:
58 // This can only happen if the caller reuses w after it's
59 // been intentionally nil'ed out to prevent use. Keep this
60 // here to catch future refactoring breaking it.
61 panic("writeEndsStream called on nil writeFramer")
62 }
63 return false
64}
65
66type flushFrameWriter struct{}
67
68func (flushFrameWriter) writeFrame(ctx writeContext) error {
69 return ctx.Flush()
70}
71
72func (flushFrameWriter) staysWithinBuffer(max int) bool { return false }
73
74type writeSettings []Setting
75
76func (s writeSettings) staysWithinBuffer(max int) bool {
77 const settingSize = 6 // uint16 + uint32
78 return frameHeaderLen+settingSize*len(s) <= max
79
80}
81
82func (s writeSettings) writeFrame(ctx writeContext) error {
83 return ctx.Framer().WriteSettings([]Setting(s)...)
84}
85
86type writeGoAway struct {
87 maxStreamID uint32
88 code ErrCode
89}
90
91func (p *writeGoAway) writeFrame(ctx writeContext) error {
92 err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)
93 if p.code != 0 {
94 ctx.Flush() // ignore error: we're hanging up on them anyway
95 time.Sleep(50 * time.Millisecond)
96 ctx.CloseConn()
97 }
98 return err
99}
100
101func (*writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes
102
103type writeData struct {
104 streamID uint32
105 p []byte
106 endStream bool
107}
108
109func (w *writeData) String() string {
110 return fmt.Sprintf("writeData(stream=%d, p=%d, endStream=%v)", w.streamID, len(w.p), w.endStream)
111}
112
113func (w *writeData) writeFrame(ctx writeContext) error {
114 return ctx.Framer().WriteData(w.streamID, w.endStream, w.p)
115}
116
117func (w *writeData) staysWithinBuffer(max int) bool {
118 return frameHeaderLen+len(w.p) <= max
119}
120
121// handlerPanicRST is the message sent from handler goroutines when
122// the handler panics.
123type handlerPanicRST struct {
124 StreamID uint32
125}
126
127func (hp handlerPanicRST) writeFrame(ctx writeContext) error {
128 return ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal)
129}
130
131func (hp handlerPanicRST) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
132
133func (se StreamError) writeFrame(ctx writeContext) error {
134 return ctx.Framer().WriteRSTStream(se.StreamID, se.Code)
135}
136
137func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
138
139type writePingAck struct{ pf *PingFrame }
140
141func (w writePingAck) writeFrame(ctx writeContext) error {
142 return ctx.Framer().WritePing(true, w.pf.Data)
143}
144
145func (w writePingAck) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.pf.Data) <= max }
146
147type writeSettingsAck struct{}
148
149func (writeSettingsAck) writeFrame(ctx writeContext) error {
150 return ctx.Framer().WriteSettingsAck()
151}
152
153func (writeSettingsAck) staysWithinBuffer(max int) bool { return frameHeaderLen <= max }
154
155// splitHeaderBlock splits headerBlock into fragments so that each fragment fits
156// in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true
157// for the first/last fragment, respectively.
158func splitHeaderBlock(ctx writeContext, headerBlock []byte, fn func(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error) error {
159 // For now we're lazy and just pick the minimum MAX_FRAME_SIZE
160 // that all peers must support (16KB). Later we could care
161 // more and send larger frames if the peer advertised it, but
162 // there's little point. Most headers are small anyway (so we
163 // generally won't have CONTINUATION frames), and extra frames
164 // only waste 9 bytes anyway.
165 const maxFrameSize = 16384
166
167 first := true
168 for len(headerBlock) > 0 {
169 frag := headerBlock
170 if len(frag) > maxFrameSize {
171 frag = frag[:maxFrameSize]
172 }
173 headerBlock = headerBlock[len(frag):]
174 if err := fn(ctx, frag, first, len(headerBlock) == 0); err != nil {
175 return err
176 }
177 first = false
178 }
179 return nil
180}
181
182// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames
183// for HTTP response headers or trailers from a server handler.
184type writeResHeaders struct {
185 streamID uint32
186 httpResCode int // 0 means no ":status" line
187 h http.Header // may be nil
188 trailers []string // if non-nil, which keys of h to write. nil means all.
189 endStream bool
190
191 date string
192 contentType string
193 contentLength string
194}
195
196func encKV(enc *hpack.Encoder, k, v string) {
197 if VerboseLogs {
198 log.Printf("http2: server encoding header %q = %q", k, v)
199 }
200 enc.WriteField(hpack.HeaderField{Name: k, Value: v})
201}
202
203func (w *writeResHeaders) staysWithinBuffer(max int) bool {
204 // TODO: this is a common one. It'd be nice to return true
205 // here and get into the fast path if we could be clever and
206 // calculate the size fast enough, or at least a conservative
207 // uppper bound that usually fires. (Maybe if w.h and
208 // w.trailers are nil, so we don't need to enumerate it.)
209 // Otherwise I'm afraid that just calculating the length to
210 // answer this question would be slower than the ~2µs benefit.
211 return false
212}
213
214func (w *writeResHeaders) writeFrame(ctx writeContext) error {
215 enc, buf := ctx.HeaderEncoder()
216 buf.Reset()
217
218 if w.httpResCode != 0 {
219 encKV(enc, ":status", httpCodeString(w.httpResCode))
220 }
221
222 encodeHeaders(enc, w.h, w.trailers)
223
224 if w.contentType != "" {
225 encKV(enc, "content-type", w.contentType)
226 }
227 if w.contentLength != "" {
228 encKV(enc, "content-length", w.contentLength)
229 }
230 if w.date != "" {
231 encKV(enc, "date", w.date)
232 }
233
234 headerBlock := buf.Bytes()
235 if len(headerBlock) == 0 && w.trailers == nil {
236 panic("unexpected empty hpack")
237 }
238
239 return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
240}
241
242func (w *writeResHeaders) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error {
243 if firstFrag {
244 return ctx.Framer().WriteHeaders(HeadersFrameParam{
245 StreamID: w.streamID,
246 BlockFragment: frag,
247 EndStream: w.endStream,
248 EndHeaders: lastFrag,
249 })
250 } else {
251 return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
252 }
253}
254
255// writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames.
256type writePushPromise struct {
257 streamID uint32 // pusher stream
258 method string // for :method
259 url *url.URL // for :scheme, :authority, :path
260 h http.Header
261
262 // Creates an ID for a pushed stream. This runs on serveG just before
263 // the frame is written. The returned ID is copied to promisedID.
264 allocatePromisedID func() (uint32, error)
265 promisedID uint32
266}
267
268func (w *writePushPromise) staysWithinBuffer(max int) bool {
269 // TODO: see writeResHeaders.staysWithinBuffer
270 return false
271}
272
273func (w *writePushPromise) writeFrame(ctx writeContext) error {
274 enc, buf := ctx.HeaderEncoder()
275 buf.Reset()
276
277 encKV(enc, ":method", w.method)
278 encKV(enc, ":scheme", w.url.Scheme)
279 encKV(enc, ":authority", w.url.Host)
280 encKV(enc, ":path", w.url.RequestURI())
281 encodeHeaders(enc, w.h, nil)
282
283 headerBlock := buf.Bytes()
284 if len(headerBlock) == 0 {
285 panic("unexpected empty hpack")
286 }
287
288 return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
289}
290
291func (w *writePushPromise) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error {
292 if firstFrag {
293 return ctx.Framer().WritePushPromise(PushPromiseParam{
294 StreamID: w.streamID,
295 PromiseID: w.promisedID,
296 BlockFragment: frag,
297 EndHeaders: lastFrag,
298 })
299 } else {
300 return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
301 }
302}
303
304type write100ContinueHeadersFrame struct {
305 streamID uint32
306}
307
308func (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error {
309 enc, buf := ctx.HeaderEncoder()
310 buf.Reset()
311 encKV(enc, ":status", "100")
312 return ctx.Framer().WriteHeaders(HeadersFrameParam{
313 StreamID: w.streamID,
314 BlockFragment: buf.Bytes(),
315 EndStream: false,
316 EndHeaders: true,
317 })
318}
319
320func (w write100ContinueHeadersFrame) staysWithinBuffer(max int) bool {
321 // Sloppy but conservative:
322 return 9+2*(len(":status")+len("100")) <= max
323}
324
325type writeWindowUpdate struct {
326 streamID uint32 // or 0 for conn-level
327 n uint32
328}
329
330func (wu writeWindowUpdate) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
331
332func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
333 return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n)
334}
335
336// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])
337// is encoded only only if k is in keys.
338func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
339 if keys == nil {
340 sorter := sorterPool.Get().(*sorter)
341 // Using defer here, since the returned keys from the
342 // sorter.Keys method is only valid until the sorter
343 // is returned:
344 defer sorterPool.Put(sorter)
345 keys = sorter.Keys(h)
346 }
347 for _, k := range keys {
348 vv := h[k]
349 k = lowerHeader(k)
350 if !validWireHeaderFieldName(k) {
351 // Skip it as backup paranoia. Per
352 // golang.org/issue/14048, these should
353 // already be rejected at a higher level.
354 continue
355 }
356 isTE := k == "transfer-encoding"
357 for _, v := range vv {
358 if !httplex.ValidHeaderFieldValue(v) {
359 // TODO: return an error? golang.org/issue/14048
360 // For now just omit it.
361 continue
362 }
363 // TODO: more of "8.1.2.2 Connection-Specific Header Fields"
364 if isTE && v != "trailers" {
365 continue
366 }
367 encKV(enc, k, v)
368 }
369 }
370}
diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go
new file mode 100644
index 0000000..4fe3073
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/writesched.go
@@ -0,0 +1,242 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import "fmt"
8
9// WriteScheduler is the interface implemented by HTTP/2 write schedulers.
10// Methods are never called concurrently.
11type WriteScheduler interface {
12 // OpenStream opens a new stream in the write scheduler.
13 // It is illegal to call this with streamID=0 or with a streamID that is
14 // already open -- the call may panic.
15 OpenStream(streamID uint32, options OpenStreamOptions)
16
17 // CloseStream closes a stream in the write scheduler. Any frames queued on
18 // this stream should be discarded. It is illegal to call this on a stream
19 // that is not open -- the call may panic.
20 CloseStream(streamID uint32)
21
22 // AdjustStream adjusts the priority of the given stream. This may be called
23 // on a stream that has not yet been opened or has been closed. Note that
24 // RFC 7540 allows PRIORITY frames to be sent on streams in any state. See:
25 // https://tools.ietf.org/html/rfc7540#section-5.1
26 AdjustStream(streamID uint32, priority PriorityParam)
27
28 // Push queues a frame in the scheduler. In most cases, this will not be
29 // called with wr.StreamID()!=0 unless that stream is currently open. The one
30 // exception is RST_STREAM frames, which may be sent on idle or closed streams.
31 Push(wr FrameWriteRequest)
32
33 // Pop dequeues the next frame to write. Returns false if no frames can
34 // be written. Frames with a given wr.StreamID() are Pop'd in the same
35 // order they are Push'd.
36 Pop() (wr FrameWriteRequest, ok bool)
37}
38
39// OpenStreamOptions specifies extra options for WriteScheduler.OpenStream.
40type OpenStreamOptions struct {
41 // PusherID is zero if the stream was initiated by the client. Otherwise,
42 // PusherID names the stream that pushed the newly opened stream.
43 PusherID uint32
44}
45
46// FrameWriteRequest is a request to write a frame.
47type FrameWriteRequest struct {
48 // write is the interface value that does the writing, once the
49 // WriteScheduler has selected this frame to write. The write
50 // functions are all defined in write.go.
51 write writeFramer
52
53 // stream is the stream on which this frame will be written.
54 // nil for non-stream frames like PING and SETTINGS.
55 stream *stream
56
57 // done, if non-nil, must be a buffered channel with space for
58 // 1 message and is sent the return value from write (or an
59 // earlier error) when the frame has been written.
60 done chan error
61}
62
63// StreamID returns the id of the stream this frame will be written to.
64// 0 is used for non-stream frames such as PING and SETTINGS.
65func (wr FrameWriteRequest) StreamID() uint32 {
66 if wr.stream == nil {
67 if se, ok := wr.write.(StreamError); ok {
68 // (*serverConn).resetStream doesn't set
69 // stream because it doesn't necessarily have
70 // one. So special case this type of write
71 // message.
72 return se.StreamID
73 }
74 return 0
75 }
76 return wr.stream.id
77}
78
79// DataSize returns the number of flow control bytes that must be consumed
80// to write this entire frame. This is 0 for non-DATA frames.
81func (wr FrameWriteRequest) DataSize() int {
82 if wd, ok := wr.write.(*writeData); ok {
83 return len(wd.p)
84 }
85 return 0
86}
87
88// Consume consumes min(n, available) bytes from this frame, where available
89// is the number of flow control bytes available on the stream. Consume returns
90// 0, 1, or 2 frames, where the integer return value gives the number of frames
91// returned.
92//
93// If flow control prevents consuming any bytes, this returns (_, _, 0). If
94// the entire frame was consumed, this returns (wr, _, 1). Otherwise, this
95// returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and
96// 'rest' contains the remaining bytes. The consumed bytes are deducted from the
97// underlying stream's flow control budget.
98func (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteRequest, int) {
99 var empty FrameWriteRequest
100
101 // Non-DATA frames are always consumed whole.
102 wd, ok := wr.write.(*writeData)
103 if !ok || len(wd.p) == 0 {
104 return wr, empty, 1
105 }
106
107 // Might need to split after applying limits.
108 allowed := wr.stream.flow.available()
109 if n < allowed {
110 allowed = n
111 }
112 if wr.stream.sc.maxFrameSize < allowed {
113 allowed = wr.stream.sc.maxFrameSize
114 }
115 if allowed <= 0 {
116 return empty, empty, 0
117 }
118 if len(wd.p) > int(allowed) {
119 wr.stream.flow.take(allowed)
120 consumed := FrameWriteRequest{
121 stream: wr.stream,
122 write: &writeData{
123 streamID: wd.streamID,
124 p: wd.p[:allowed],
125 // Even if the original had endStream set, there
126 // are bytes remaining because len(wd.p) > allowed,
127 // so we know endStream is false.
128 endStream: false,
129 },
130 // Our caller is blocking on the final DATA frame, not
131 // this intermediate frame, so no need to wait.
132 done: nil,
133 }
134 rest := FrameWriteRequest{
135 stream: wr.stream,
136 write: &writeData{
137 streamID: wd.streamID,
138 p: wd.p[allowed:],
139 endStream: wd.endStream,
140 },
141 done: wr.done,
142 }
143 return consumed, rest, 2
144 }
145
146 // The frame is consumed whole.
147 // NB: This cast cannot overflow because allowed is <= math.MaxInt32.
148 wr.stream.flow.take(int32(len(wd.p)))
149 return wr, empty, 1
150}
151
152// String is for debugging only.
153func (wr FrameWriteRequest) String() string {
154 var des string
155 if s, ok := wr.write.(fmt.Stringer); ok {
156 des = s.String()
157 } else {
158 des = fmt.Sprintf("%T", wr.write)
159 }
160 return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des)
161}
162
163// replyToWriter sends err to wr.done and panics if the send must block
164// This does nothing if wr.done is nil.
165func (wr *FrameWriteRequest) replyToWriter(err error) {
166 if wr.done == nil {
167 return
168 }
169 select {
170 case wr.done <- err:
171 default:
172 panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wr.write))
173 }
174 wr.write = nil // prevent use (assume it's tainted after wr.done send)
175}
176
177// writeQueue is used by implementations of WriteScheduler.
178type writeQueue struct {
179 s []FrameWriteRequest
180}
181
182func (q *writeQueue) empty() bool { return len(q.s) == 0 }
183
184func (q *writeQueue) push(wr FrameWriteRequest) {
185 q.s = append(q.s, wr)
186}
187
188func (q *writeQueue) shift() FrameWriteRequest {
189 if len(q.s) == 0 {
190 panic("invalid use of queue")
191 }
192 wr := q.s[0]
193 // TODO: less copy-happy queue.
194 copy(q.s, q.s[1:])
195 q.s[len(q.s)-1] = FrameWriteRequest{}
196 q.s = q.s[:len(q.s)-1]
197 return wr
198}
199
200// consume consumes up to n bytes from q.s[0]. If the frame is
201// entirely consumed, it is removed from the queue. If the frame
202// is partially consumed, the frame is kept with the consumed
203// bytes removed. Returns true iff any bytes were consumed.
204func (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) {
205 if len(q.s) == 0 {
206 return FrameWriteRequest{}, false
207 }
208 consumed, rest, numresult := q.s[0].Consume(n)
209 switch numresult {
210 case 0:
211 return FrameWriteRequest{}, false
212 case 1:
213 q.shift()
214 case 2:
215 q.s[0] = rest
216 }
217 return consumed, true
218}
219
220type writeQueuePool []*writeQueue
221
222// put inserts an unused writeQueue into the pool.
223func (p *writeQueuePool) put(q *writeQueue) {
224 for i := range q.s {
225 q.s[i] = FrameWriteRequest{}
226 }
227 q.s = q.s[:0]
228 *p = append(*p, q)
229}
230
231// get returns an empty writeQueue.
232func (p *writeQueuePool) get() *writeQueue {
233 ln := len(*p)
234 if ln == 0 {
235 return new(writeQueue)
236 }
237 x := ln - 1
238 q := (*p)[x]
239 (*p)[x] = nil
240 *p = (*p)[:x]
241 return q
242}
diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go
new file mode 100644
index 0000000..848fed6
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/writesched_priority.go
@@ -0,0 +1,452 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import (
8 "fmt"
9 "math"
10 "sort"
11)
12
13// RFC 7540, Section 5.3.5: the default weight is 16.
14const priorityDefaultWeight = 15 // 16 = 15 + 1
15
16// PriorityWriteSchedulerConfig configures a priorityWriteScheduler.
17type PriorityWriteSchedulerConfig struct {
18 // MaxClosedNodesInTree controls the maximum number of closed streams to
19 // retain in the priority tree. Setting this to zero saves a small amount
20 // of memory at the cost of performance.
21 //
22 // See RFC 7540, Section 5.3.4:
23 // "It is possible for a stream to become closed while prioritization
24 // information ... is in transit. ... This potentially creates suboptimal
25 // prioritization, since the stream could be given a priority that is
26 // different from what is intended. To avoid these problems, an endpoint
27 // SHOULD retain stream prioritization state for a period after streams
28 // become closed. The longer state is retained, the lower the chance that
29 // streams are assigned incorrect or default priority values."
30 MaxClosedNodesInTree int
31
32 // MaxIdleNodesInTree controls the maximum number of idle streams to
33 // retain in the priority tree. Setting this to zero saves a small amount
34 // of memory at the cost of performance.
35 //
36 // See RFC 7540, Section 5.3.4:
37 // Similarly, streams that are in the "idle" state can be assigned
38 // priority or become a parent of other streams. This allows for the
39 // creation of a grouping node in the dependency tree, which enables
40 // more flexible expressions of priority. Idle streams begin with a
41 // default priority (Section 5.3.5).
42 MaxIdleNodesInTree int
43
44 // ThrottleOutOfOrderWrites enables write throttling to help ensure that
45 // data is delivered in priority order. This works around a race where
46 // stream B depends on stream A and both streams are about to call Write
47 // to queue DATA frames. If B wins the race, a naive scheduler would eagerly
48 // write as much data from B as possible, but this is suboptimal because A
49 // is a higher-priority stream. With throttling enabled, we write a small
50 // amount of data from B to minimize the amount of bandwidth that B can
51 // steal from A.
52 ThrottleOutOfOrderWrites bool
53}
54
55// NewPriorityWriteScheduler constructs a WriteScheduler that schedules
56// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.
57// If cfg is nil, default options are used.
58func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
59 if cfg == nil {
60 // For justification of these defaults, see:
61 // https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
62 cfg = &PriorityWriteSchedulerConfig{
63 MaxClosedNodesInTree: 10,
64 MaxIdleNodesInTree: 10,
65 ThrottleOutOfOrderWrites: false,
66 }
67 }
68
69 ws := &priorityWriteScheduler{
70 nodes: make(map[uint32]*priorityNode),
71 maxClosedNodesInTree: cfg.MaxClosedNodesInTree,
72 maxIdleNodesInTree: cfg.MaxIdleNodesInTree,
73 enableWriteThrottle: cfg.ThrottleOutOfOrderWrites,
74 }
75 ws.nodes[0] = &ws.root
76 if cfg.ThrottleOutOfOrderWrites {
77 ws.writeThrottleLimit = 1024
78 } else {
79 ws.writeThrottleLimit = math.MaxInt32
80 }
81 return ws
82}
83
84type priorityNodeState int
85
86const (
87 priorityNodeOpen priorityNodeState = iota
88 priorityNodeClosed
89 priorityNodeIdle
90)
91
92// priorityNode is a node in an HTTP/2 priority tree.
93// Each node is associated with a single stream ID.
94// See RFC 7540, Section 5.3.
95type priorityNode struct {
96 q writeQueue // queue of pending frames to write
97 id uint32 // id of the stream, or 0 for the root of the tree
98 weight uint8 // the actual weight is weight+1, so the value is in [1,256]
99 state priorityNodeState // open | closed | idle
100 bytes int64 // number of bytes written by this node, or 0 if closed
101 subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree
102
103 // These links form the priority tree.
104 parent *priorityNode
105 kids *priorityNode // start of the kids list
106 prev, next *priorityNode // doubly-linked list of siblings
107}
108
109func (n *priorityNode) setParent(parent *priorityNode) {
110 if n == parent {
111 panic("setParent to self")
112 }
113 if n.parent == parent {
114 return
115 }
116 // Unlink from current parent.
117 if parent := n.parent; parent != nil {
118 if n.prev == nil {
119 parent.kids = n.next
120 } else {
121 n.prev.next = n.next
122 }
123 if n.next != nil {
124 n.next.prev = n.prev
125 }
126 }
127 // Link to new parent.
128 // If parent=nil, remove n from the tree.
129 // Always insert at the head of parent.kids (this is assumed by walkReadyInOrder).
130 n.parent = parent
131 if parent == nil {
132 n.next = nil
133 n.prev = nil
134 } else {
135 n.next = parent.kids
136 n.prev = nil
137 if n.next != nil {
138 n.next.prev = n
139 }
140 parent.kids = n
141 }
142}
143
144func (n *priorityNode) addBytes(b int64) {
145 n.bytes += b
146 for ; n != nil; n = n.parent {
147 n.subtreeBytes += b
148 }
149}
150
151// walkReadyInOrder iterates over the tree in priority order, calling f for each node
152// with a non-empty write queue. When f returns true, this funcion returns true and the
153// walk halts. tmp is used as scratch space for sorting.
154//
155// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
156// if any ancestor p of n is still open (ignoring the root node).
157func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool {
158 if !n.q.empty() && f(n, openParent) {
159 return true
160 }
161 if n.kids == nil {
162 return false
163 }
164
165 // Don't consider the root "open" when updating openParent since
166 // we can't send data frames on the root stream (only control frames).
167 if n.id != 0 {
168 openParent = openParent || (n.state == priorityNodeOpen)
169 }
170
171 // Common case: only one kid or all kids have the same weight.
172 // Some clients don't use weights; other clients (like web browsers)
173 // use mostly-linear priority trees.
174 w := n.kids.weight
175 needSort := false
176 for k := n.kids.next; k != nil; k = k.next {
177 if k.weight != w {
178 needSort = true
179 break
180 }
181 }
182 if !needSort {
183 for k := n.kids; k != nil; k = k.next {
184 if k.walkReadyInOrder(openParent, tmp, f) {
185 return true
186 }
187 }
188 return false
189 }
190
191 // Uncommon case: sort the child nodes. We remove the kids from the parent,
192 // then re-insert after sorting so we can reuse tmp for future sort calls.
193 *tmp = (*tmp)[:0]
194 for n.kids != nil {
195 *tmp = append(*tmp, n.kids)
196 n.kids.setParent(nil)
197 }
198 sort.Sort(sortPriorityNodeSiblings(*tmp))
199 for i := len(*tmp) - 1; i >= 0; i-- {
200 (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids
201 }
202 for k := n.kids; k != nil; k = k.next {
203 if k.walkReadyInOrder(openParent, tmp, f) {
204 return true
205 }
206 }
207 return false
208}
209
210type sortPriorityNodeSiblings []*priorityNode
211
212func (z sortPriorityNodeSiblings) Len() int { return len(z) }
213func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
214func (z sortPriorityNodeSiblings) Less(i, k int) bool {
215 // Prefer the subtree that has sent fewer bytes relative to its weight.
216 // See sections 5.3.2 and 5.3.4.
217 wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes)
218 wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes)
219 if bi == 0 && bk == 0 {
220 return wi >= wk
221 }
222 if bk == 0 {
223 return false
224 }
225 return bi/bk <= wi/wk
226}
227
228type priorityWriteScheduler struct {
229 // root is the root of the priority tree, where root.id = 0.
230 // The root queues control frames that are not associated with any stream.
231 root priorityNode
232
233 // nodes maps stream ids to priority tree nodes.
234 nodes map[uint32]*priorityNode
235
236 // maxID is the maximum stream id in nodes.
237 maxID uint32
238
239 // lists of nodes that have been closed or are idle, but are kept in
240 // the tree for improved prioritization. When the lengths exceed either
241 // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.
242 closedNodes, idleNodes []*priorityNode
243
244 // From the config.
245 maxClosedNodesInTree int
246 maxIdleNodesInTree int
247 writeThrottleLimit int32
248 enableWriteThrottle bool
249
250 // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.
251 tmp []*priorityNode
252
253 // pool of empty queues for reuse.
254 queuePool writeQueuePool
255}
256
257func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {
258 // The stream may be currently idle but cannot be opened or closed.
259 if curr := ws.nodes[streamID]; curr != nil {
260 if curr.state != priorityNodeIdle {
261 panic(fmt.Sprintf("stream %d already opened", streamID))
262 }
263 curr.state = priorityNodeOpen
264 return
265 }
266
267 // RFC 7540, Section 5.3.5:
268 // "All streams are initially assigned a non-exclusive dependency on stream 0x0.
269 // Pushed streams initially depend on their associated stream. In both cases,
270 // streams are assigned a default weight of 16."
271 parent := ws.nodes[options.PusherID]
272 if parent == nil {
273 parent = &ws.root
274 }
275 n := &priorityNode{
276 q: *ws.queuePool.get(),
277 id: streamID,
278 weight: priorityDefaultWeight,
279 state: priorityNodeOpen,
280 }
281 n.setParent(parent)
282 ws.nodes[streamID] = n
283 if streamID > ws.maxID {
284 ws.maxID = streamID
285 }
286}
287
288func (ws *priorityWriteScheduler) CloseStream(streamID uint32) {
289 if streamID == 0 {
290 panic("violation of WriteScheduler interface: cannot close stream 0")
291 }
292 if ws.nodes[streamID] == nil {
293 panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID))
294 }
295 if ws.nodes[streamID].state != priorityNodeOpen {
296 panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID))
297 }
298
299 n := ws.nodes[streamID]
300 n.state = priorityNodeClosed
301 n.addBytes(-n.bytes)
302
303 q := n.q
304 ws.queuePool.put(&q)
305 n.q.s = nil
306 if ws.maxClosedNodesInTree > 0 {
307 ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n)
308 } else {
309 ws.removeNode(n)
310 }
311}
312
313func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {
314 if streamID == 0 {
315 panic("adjustPriority on root")
316 }
317
318 // If streamID does not exist, there are two cases:
319 // - A closed stream that has been removed (this will have ID <= maxID)
320 // - An idle stream that is being used for "grouping" (this will have ID > maxID)
321 n := ws.nodes[streamID]
322 if n == nil {
323 if streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 {
324 return
325 }
326 ws.maxID = streamID
327 n = &priorityNode{
328 q: *ws.queuePool.get(),
329 id: streamID,
330 weight: priorityDefaultWeight,
331 state: priorityNodeIdle,
332 }
333 n.setParent(&ws.root)
334 ws.nodes[streamID] = n
335 ws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n)
336 }
337
338 // Section 5.3.1: A dependency on a stream that is not currently in the tree
339 // results in that stream being given a default priority (Section 5.3.5).
340 parent := ws.nodes[priority.StreamDep]
341 if parent == nil {
342 n.setParent(&ws.root)
343 n.weight = priorityDefaultWeight
344 return
345 }
346
347 // Ignore if the client tries to make a node its own parent.
348 if n == parent {
349 return
350 }
351
352 // Section 5.3.3:
353 // "If a stream is made dependent on one of its own dependencies, the
354 // formerly dependent stream is first moved to be dependent on the
355 // reprioritized stream's previous parent. The moved dependency retains
356 // its weight."
357 //
358 // That is: if parent depends on n, move parent to depend on n.parent.
359 for x := parent.parent; x != nil; x = x.parent {
360 if x == n {
361 parent.setParent(n.parent)
362 break
363 }
364 }
365
366 // Section 5.3.3: The exclusive flag causes the stream to become the sole
367 // dependency of its parent stream, causing other dependencies to become
368 // dependent on the exclusive stream.
369 if priority.Exclusive {
370 k := parent.kids
371 for k != nil {
372 next := k.next
373 if k != n {
374 k.setParent(n)
375 }
376 k = next
377 }
378 }
379
380 n.setParent(parent)
381 n.weight = priority.Weight
382}
383
384func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
385 var n *priorityNode
386 if id := wr.StreamID(); id == 0 {
387 n = &ws.root
388 } else {
389 n = ws.nodes[id]
390 if n == nil {
391 // id is an idle or closed stream. wr should not be a HEADERS or
392 // DATA frame. However, wr can be a RST_STREAM. In this case, we
393 // push wr onto the root, rather than creating a new priorityNode,
394 // since RST_STREAM is tiny and the stream's priority is unknown
395 // anyway. See issue #17919.
396 if wr.DataSize() > 0 {
397 panic("add DATA on non-open stream")
398 }
399 n = &ws.root
400 }
401 }
402 n.q.push(wr)
403}
404
405func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) {
406 ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool {
407 limit := int32(math.MaxInt32)
408 if openParent {
409 limit = ws.writeThrottleLimit
410 }
411 wr, ok = n.q.consume(limit)
412 if !ok {
413 return false
414 }
415 n.addBytes(int64(wr.DataSize()))
416 // If B depends on A and B continuously has data available but A
417 // does not, gradually increase the throttling limit to allow B to
418 // steal more and more bandwidth from A.
419 if openParent {
420 ws.writeThrottleLimit += 1024
421 if ws.writeThrottleLimit < 0 {
422 ws.writeThrottleLimit = math.MaxInt32
423 }
424 } else if ws.enableWriteThrottle {
425 ws.writeThrottleLimit = 1024
426 }
427 return true
428 })
429 return wr, ok
430}
431
432func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) {
433 if maxSize == 0 {
434 return
435 }
436 if len(*list) == maxSize {
437 // Remove the oldest node, then shift left.
438 ws.removeNode((*list)[0])
439 x := (*list)[1:]
440 copy(*list, x)
441 *list = (*list)[:len(x)]
442 }
443 *list = append(*list, n)
444}
445
446func (ws *priorityWriteScheduler) removeNode(n *priorityNode) {
447 for k := n.kids; k != nil; k = k.next {
448 k.setParent(n.parent)
449 }
450 n.setParent(nil)
451 delete(ws.nodes, n.id)
452}
diff --git a/vendor/golang.org/x/net/http2/writesched_random.go b/vendor/golang.org/x/net/http2/writesched_random.go
new file mode 100644
index 0000000..36d7919
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/writesched_random.go
@@ -0,0 +1,72 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package http2
6
7import "math"
8
9// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2
10// priorities. Control frames like SETTINGS and PING are written before DATA
11// frames, but if no control frames are queued and multiple streams have queued
12// HEADERS or DATA frames, Pop selects a ready stream arbitrarily.
13func NewRandomWriteScheduler() WriteScheduler {
14 return &randomWriteScheduler{sq: make(map[uint32]*writeQueue)}
15}
16
17type randomWriteScheduler struct {
18 // zero are frames not associated with a specific stream.
19 zero writeQueue
20
21 // sq contains the stream-specific queues, keyed by stream ID.
22 // When a stream is idle or closed, it's deleted from the map.
23 sq map[uint32]*writeQueue
24
25 // pool of empty queues for reuse.
26 queuePool writeQueuePool
27}
28
29func (ws *randomWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {
30 // no-op: idle streams are not tracked
31}
32
33func (ws *randomWriteScheduler) CloseStream(streamID uint32) {
34 q, ok := ws.sq[streamID]
35 if !ok {
36 return
37 }
38 delete(ws.sq, streamID)
39 ws.queuePool.put(q)
40}
41
42func (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {
43 // no-op: priorities are ignored
44}
45
46func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) {
47 id := wr.StreamID()
48 if id == 0 {
49 ws.zero.push(wr)
50 return
51 }
52 q, ok := ws.sq[id]
53 if !ok {
54 q = ws.queuePool.get()
55 ws.sq[id] = q
56 }
57 q.push(wr)
58}
59
60func (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) {
61 // Control frames first.
62 if !ws.zero.empty() {
63 return ws.zero.shift(), true
64 }
65 // Iterate over all non-idle streams until finding one that can be consumed.
66 for _, q := range ws.sq {
67 if wr, ok := q.consume(math.MaxInt32); ok {
68 return wr, true
69 }
70 }
71 return FrameWriteRequest{}, false
72}
diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go
new file mode 100644
index 0000000..ec8232b
--- /dev/null
+++ b/vendor/golang.org/x/net/idna/idna.go
@@ -0,0 +1,680 @@
1// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
2
3// Copyright 2016 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Package idna implements IDNA2008 using the compatibility processing
8// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
9// deal with the transition from IDNA2003.
10//
11// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC
12// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.
13// UTS #46 is defined in http://www.unicode.org/reports/tr46.
14// See http://unicode.org/cldr/utility/idna.jsp for a visualization of the
15// differences between these two standards.
16package idna // import "golang.org/x/net/idna"
17
18import (
19 "fmt"
20 "strings"
21 "unicode/utf8"
22
23 "golang.org/x/text/secure/bidirule"
24 "golang.org/x/text/unicode/norm"
25)
26
27// NOTE: Unlike common practice in Go APIs, the functions will return a
28// sanitized domain name in case of errors. Browsers sometimes use a partially
29// evaluated string as lookup.
30// TODO: the current error handling is, in my opinion, the least opinionated.
31// Other strategies are also viable, though:
32// Option 1) Return an empty string in case of error, but allow the user to
33// specify explicitly which errors to ignore.
34// Option 2) Return the partially evaluated string if it is itself a valid
35// string, otherwise return the empty string in case of error.
36// Option 3) Option 1 and 2.
37// Option 4) Always return an empty string for now and implement Option 1 as
38// needed, and document that the return string may not be empty in case of
39// error in the future.
40// I think Option 1 is best, but it is quite opinionated.
41
42// ToASCII is a wrapper for Punycode.ToASCII.
43func ToASCII(s string) (string, error) {
44 return Punycode.process(s, true)
45}
46
47// ToUnicode is a wrapper for Punycode.ToUnicode.
48func ToUnicode(s string) (string, error) {
49 return Punycode.process(s, false)
50}
51
52// An Option configures a Profile at creation time.
53type Option func(*options)
54
55// Transitional sets a Profile to use the Transitional mapping as defined in UTS
56// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
57// transitional mapping provides a compromise between IDNA2003 and IDNA2008
58// compatibility. It is used by most browsers when resolving domain names. This
59// option is only meaningful if combined with MapForLookup.
60func Transitional(transitional bool) Option {
61 return func(o *options) { o.transitional = true }
62}
63
64// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
65// are longer than allowed by the RFC.
66func VerifyDNSLength(verify bool) Option {
67 return func(o *options) { o.verifyDNSLength = verify }
68}
69
70// RemoveLeadingDots removes leading label separators. Leading runes that map to
71// dots, such as U+3002, are removed as well.
72//
73// This is the behavior suggested by the UTS #46 and is adopted by some
74// browsers.
75func RemoveLeadingDots(remove bool) Option {
76 return func(o *options) { o.removeLeadingDots = remove }
77}
78
79// ValidateLabels sets whether to check the mandatory label validation criteria
80// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
81// of hyphens ('-'), normalization, validity of runes, and the context rules.
82func ValidateLabels(enable bool) Option {
83 return func(o *options) {
84 // Don't override existing mappings, but set one that at least checks
85 // normalization if it is not set.
86 if o.mapping == nil && enable {
87 o.mapping = normalize
88 }
89 o.trie = trie
90 o.validateLabels = enable
91 o.fromPuny = validateFromPunycode
92 }
93}
94
95// StrictDomainName limits the set of permissable ASCII characters to those
96// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
97// hyphen). This is set by default for MapForLookup and ValidateForRegistration.
98//
99// This option is useful, for instance, for browsers that allow characters
100// outside this range, for example a '_' (U+005F LOW LINE). See
101// http://www.rfc-editor.org/std/std3.txt for more details This option
102// corresponds to the UseSTD3ASCIIRules option in UTS #46.
103func StrictDomainName(use bool) Option {
104 return func(o *options) {
105 o.trie = trie
106 o.useSTD3Rules = use
107 o.fromPuny = validateFromPunycode
108 }
109}
110
111// NOTE: the following options pull in tables. The tables should not be linked
112// in as long as the options are not used.
113
114// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
115// that relies on proper validation of labels should include this rule.
116func BidiRule() Option {
117 return func(o *options) { o.bidirule = bidirule.ValidString }
118}
119
120// ValidateForRegistration sets validation options to verify that a given IDN is
121// properly formatted for registration as defined by Section 4 of RFC 5891.
122func ValidateForRegistration() Option {
123 return func(o *options) {
124 o.mapping = validateRegistration
125 StrictDomainName(true)(o)
126 ValidateLabels(true)(o)
127 VerifyDNSLength(true)(o)
128 BidiRule()(o)
129 }
130}
131
132// MapForLookup sets validation and mapping options such that a given IDN is
133// transformed for domain name lookup according to the requirements set out in
134// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,
135// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option
136// to add this check.
137//
138// The mappings include normalization and mapping case, width and other
139// compatibility mappings.
140func MapForLookup() Option {
141 return func(o *options) {
142 o.mapping = validateAndMap
143 StrictDomainName(true)(o)
144 ValidateLabels(true)(o)
145 RemoveLeadingDots(true)(o)
146 }
147}
148
149type options struct {
150 transitional bool
151 useSTD3Rules bool
152 validateLabels bool
153 verifyDNSLength bool
154 removeLeadingDots bool
155
156 trie *idnaTrie
157
158 // fromPuny calls validation rules when converting A-labels to U-labels.
159 fromPuny func(p *Profile, s string) error
160
161 // mapping implements a validation and mapping step as defined in RFC 5895
162 // or UTS 46, tailored to, for example, domain registration or lookup.
163 mapping func(p *Profile, s string) (string, error)
164
165 // bidirule, if specified, checks whether s conforms to the Bidi Rule
166 // defined in RFC 5893.
167 bidirule func(s string) bool
168}
169
170// A Profile defines the configuration of an IDNA mapper.
171type Profile struct {
172 options
173}
174
175func apply(o *options, opts []Option) {
176 for _, f := range opts {
177 f(o)
178 }
179}
180
181// New creates a new Profile.
182//
183// With no options, the returned Profile is the most permissive and equals the
184// Punycode Profile. Options can be passed to further restrict the Profile. The
185// MapForLookup and ValidateForRegistration options set a collection of options,
186// for lookup and registration purposes respectively, which can be tailored by
187// adding more fine-grained options, where later options override earlier
188// options.
189func New(o ...Option) *Profile {
190 p := &Profile{}
191 apply(&p.options, o)
192 return p
193}
194
195// ToASCII converts a domain or domain label to its ASCII form. For example,
196// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
197// ToASCII("golang") is "golang". If an error is encountered it will return
198// an error and a (partially) processed result.
199func (p *Profile) ToASCII(s string) (string, error) {
200 return p.process(s, true)
201}
202
203// ToUnicode converts a domain or domain label to its Unicode form. For example,
204// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
205// ToUnicode("golang") is "golang". If an error is encountered it will return
206// an error and a (partially) processed result.
207func (p *Profile) ToUnicode(s string) (string, error) {
208 pp := *p
209 pp.transitional = false
210 return pp.process(s, false)
211}
212
213// String reports a string with a description of the profile for debugging
214// purposes. The string format may change with different versions.
215func (p *Profile) String() string {
216 s := ""
217 if p.transitional {
218 s = "Transitional"
219 } else {
220 s = "NonTransitional"
221 }
222 if p.useSTD3Rules {
223 s += ":UseSTD3Rules"
224 }
225 if p.validateLabels {
226 s += ":ValidateLabels"
227 }
228 if p.verifyDNSLength {
229 s += ":VerifyDNSLength"
230 }
231 return s
232}
233
234var (
235 // Punycode is a Profile that does raw punycode processing with a minimum
236 // of validation.
237 Punycode *Profile = punycode
238
239 // Lookup is the recommended profile for looking up domain names, according
240 // to Section 5 of RFC 5891. The exact configuration of this profile may
241 // change over time.
242 Lookup *Profile = lookup
243
244 // Display is the recommended profile for displaying domain names.
245 // The configuration of this profile may change over time.
246 Display *Profile = display
247
248 // Registration is the recommended profile for checking whether a given
249 // IDN is valid for registration, according to Section 4 of RFC 5891.
250 Registration *Profile = registration
251
252 punycode = &Profile{}
253 lookup = &Profile{options{
254 transitional: true,
255 useSTD3Rules: true,
256 validateLabels: true,
257 removeLeadingDots: true,
258 trie: trie,
259 fromPuny: validateFromPunycode,
260 mapping: validateAndMap,
261 bidirule: bidirule.ValidString,
262 }}
263 display = &Profile{options{
264 useSTD3Rules: true,
265 validateLabels: true,
266 removeLeadingDots: true,
267 trie: trie,
268 fromPuny: validateFromPunycode,
269 mapping: validateAndMap,
270 bidirule: bidirule.ValidString,
271 }}
272 registration = &Profile{options{
273 useSTD3Rules: true,
274 validateLabels: true,
275 verifyDNSLength: true,
276 trie: trie,
277 fromPuny: validateFromPunycode,
278 mapping: validateRegistration,
279 bidirule: bidirule.ValidString,
280 }}
281
282 // TODO: profiles
283 // Register: recommended for approving domain names: don't do any mappings
284 // but rather reject on invalid input. Bundle or block deviation characters.
285)
286
287type labelError struct{ label, code_ string }
288
289func (e labelError) code() string { return e.code_ }
290func (e labelError) Error() string {
291 return fmt.Sprintf("idna: invalid label %q", e.label)
292}
293
294type runeError rune
295
296func (e runeError) code() string { return "P1" }
297func (e runeError) Error() string {
298 return fmt.Sprintf("idna: disallowed rune %U", e)
299}
300
301// process implements the algorithm described in section 4 of UTS #46,
302// see http://www.unicode.org/reports/tr46.
303func (p *Profile) process(s string, toASCII bool) (string, error) {
304 var err error
305 if p.mapping != nil {
306 s, err = p.mapping(p, s)
307 }
308 // Remove leading empty labels.
309 if p.removeLeadingDots {
310 for ; len(s) > 0 && s[0] == '.'; s = s[1:] {
311 }
312 }
313 // It seems like we should only create this error on ToASCII, but the
314 // UTS 46 conformance tests suggests we should always check this.
315 if err == nil && p.verifyDNSLength && s == "" {
316 err = &labelError{s, "A4"}
317 }
318 labels := labelIter{orig: s}
319 for ; !labels.done(); labels.next() {
320 label := labels.label()
321 if label == "" {
322 // Empty labels are not okay. The label iterator skips the last
323 // label if it is empty.
324 if err == nil && p.verifyDNSLength {
325 err = &labelError{s, "A4"}
326 }
327 continue
328 }
329 if strings.HasPrefix(label, acePrefix) {
330 u, err2 := decode(label[len(acePrefix):])
331 if err2 != nil {
332 if err == nil {
333 err = err2
334 }
335 // Spec says keep the old label.
336 continue
337 }
338 labels.set(u)
339 if err == nil && p.validateLabels {
340 err = p.fromPuny(p, u)
341 }
342 if err == nil {
343 // This should be called on NonTransitional, according to the
344 // spec, but that currently does not have any effect. Use the
345 // original profile to preserve options.
346 err = p.validateLabel(u)
347 }
348 } else if err == nil {
349 err = p.validateLabel(label)
350 }
351 }
352 if toASCII {
353 for labels.reset(); !labels.done(); labels.next() {
354 label := labels.label()
355 if !ascii(label) {
356 a, err2 := encode(acePrefix, label)
357 if err == nil {
358 err = err2
359 }
360 label = a
361 labels.set(a)
362 }
363 n := len(label)
364 if p.verifyDNSLength && err == nil && (n == 0 || n > 63) {
365 err = &labelError{label, "A4"}
366 }
367 }
368 }
369 s = labels.result()
370 if toASCII && p.verifyDNSLength && err == nil {
371 // Compute the length of the domain name minus the root label and its dot.
372 n := len(s)
373 if n > 0 && s[n-1] == '.' {
374 n--
375 }
376 if len(s) < 1 || n > 253 {
377 err = &labelError{s, "A4"}
378 }
379 }
380 return s, err
381}
382
383func normalize(p *Profile, s string) (string, error) {
384 return norm.NFC.String(s), nil
385}
386
387func validateRegistration(p *Profile, s string) (string, error) {
388 if !norm.NFC.IsNormalString(s) {
389 return s, &labelError{s, "V1"}
390 }
391 for i := 0; i < len(s); {
392 v, sz := trie.lookupString(s[i:])
393 // Copy bytes not copied so far.
394 switch p.simplify(info(v).category()) {
395 // TODO: handle the NV8 defined in the Unicode idna data set to allow
396 // for strict conformance to IDNA2008.
397 case valid, deviation:
398 case disallowed, mapped, unknown, ignored:
399 r, _ := utf8.DecodeRuneInString(s[i:])
400 return s, runeError(r)
401 }
402 i += sz
403 }
404 return s, nil
405}
406
407func validateAndMap(p *Profile, s string) (string, error) {
408 var (
409 err error
410 b []byte
411 k int
412 )
413 for i := 0; i < len(s); {
414 v, sz := trie.lookupString(s[i:])
415 start := i
416 i += sz
417 // Copy bytes not copied so far.
418 switch p.simplify(info(v).category()) {
419 case valid:
420 continue
421 case disallowed:
422 if err == nil {
423 r, _ := utf8.DecodeRuneInString(s[start:])
424 err = runeError(r)
425 }
426 continue
427 case mapped, deviation:
428 b = append(b, s[k:start]...)
429 b = info(v).appendMapping(b, s[start:i])
430 case ignored:
431 b = append(b, s[k:start]...)
432 // drop the rune
433 case unknown:
434 b = append(b, s[k:start]...)
435 b = append(b, "\ufffd"...)
436 }
437 k = i
438 }
439 if k == 0 {
440 // No changes so far.
441 s = norm.NFC.String(s)
442 } else {
443 b = append(b, s[k:]...)
444 if norm.NFC.QuickSpan(b) != len(b) {
445 b = norm.NFC.Bytes(b)
446 }
447 // TODO: the punycode converters require strings as input.
448 s = string(b)
449 }
450 return s, err
451}
452
453// A labelIter allows iterating over domain name labels.
454type labelIter struct {
455 orig string
456 slice []string
457 curStart int
458 curEnd int
459 i int
460}
461
462func (l *labelIter) reset() {
463 l.curStart = 0
464 l.curEnd = 0
465 l.i = 0
466}
467
468func (l *labelIter) done() bool {
469 return l.curStart >= len(l.orig)
470}
471
472func (l *labelIter) result() string {
473 if l.slice != nil {
474 return strings.Join(l.slice, ".")
475 }
476 return l.orig
477}
478
479func (l *labelIter) label() string {
480 if l.slice != nil {
481 return l.slice[l.i]
482 }
483 p := strings.IndexByte(l.orig[l.curStart:], '.')
484 l.curEnd = l.curStart + p
485 if p == -1 {
486 l.curEnd = len(l.orig)
487 }
488 return l.orig[l.curStart:l.curEnd]
489}
490
491// next sets the value to the next label. It skips the last label if it is empty.
492func (l *labelIter) next() {
493 l.i++
494 if l.slice != nil {
495 if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" {
496 l.curStart = len(l.orig)
497 }
498 } else {
499 l.curStart = l.curEnd + 1
500 if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
501 l.curStart = len(l.orig)
502 }
503 }
504}
505
506func (l *labelIter) set(s string) {
507 if l.slice == nil {
508 l.slice = strings.Split(l.orig, ".")
509 }
510 l.slice[l.i] = s
511}
512
513// acePrefix is the ASCII Compatible Encoding prefix.
514const acePrefix = "xn--"
515
516func (p *Profile) simplify(cat category) category {
517 switch cat {
518 case disallowedSTD3Mapped:
519 if p.useSTD3Rules {
520 cat = disallowed
521 } else {
522 cat = mapped
523 }
524 case disallowedSTD3Valid:
525 if p.useSTD3Rules {
526 cat = disallowed
527 } else {
528 cat = valid
529 }
530 case deviation:
531 if !p.transitional {
532 cat = valid
533 }
534 case validNV8, validXV8:
535 // TODO: handle V2008
536 cat = valid
537 }
538 return cat
539}
540
541func validateFromPunycode(p *Profile, s string) error {
542 if !norm.NFC.IsNormalString(s) {
543 return &labelError{s, "V1"}
544 }
545 for i := 0; i < len(s); {
546 v, sz := trie.lookupString(s[i:])
547 if c := p.simplify(info(v).category()); c != valid && c != deviation {
548 return &labelError{s, "V6"}
549 }
550 i += sz
551 }
552 return nil
553}
554
555const (
556 zwnj = "\u200c"
557 zwj = "\u200d"
558)
559
560type joinState int8
561
562const (
563 stateStart joinState = iota
564 stateVirama
565 stateBefore
566 stateBeforeVirama
567 stateAfter
568 stateFAIL
569)
570
571var joinStates = [][numJoinTypes]joinState{
572 stateStart: {
573 joiningL: stateBefore,
574 joiningD: stateBefore,
575 joinZWNJ: stateFAIL,
576 joinZWJ: stateFAIL,
577 joinVirama: stateVirama,
578 },
579 stateVirama: {
580 joiningL: stateBefore,
581 joiningD: stateBefore,
582 },
583 stateBefore: {
584 joiningL: stateBefore,
585 joiningD: stateBefore,
586 joiningT: stateBefore,
587 joinZWNJ: stateAfter,
588 joinZWJ: stateFAIL,
589 joinVirama: stateBeforeVirama,
590 },
591 stateBeforeVirama: {
592 joiningL: stateBefore,
593 joiningD: stateBefore,
594 joiningT: stateBefore,
595 },
596 stateAfter: {
597 joiningL: stateFAIL,
598 joiningD: stateBefore,
599 joiningT: stateAfter,
600 joiningR: stateStart,
601 joinZWNJ: stateFAIL,
602 joinZWJ: stateFAIL,
603 joinVirama: stateAfter, // no-op as we can't accept joiners here
604 },
605 stateFAIL: {
606 0: stateFAIL,
607 joiningL: stateFAIL,
608 joiningD: stateFAIL,
609 joiningT: stateFAIL,
610 joiningR: stateFAIL,
611 joinZWNJ: stateFAIL,
612 joinZWJ: stateFAIL,
613 joinVirama: stateFAIL,
614 },
615}
616
617// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
618// already implicitly satisfied by the overall implementation.
619func (p *Profile) validateLabel(s string) error {
620 if s == "" {
621 if p.verifyDNSLength {
622 return &labelError{s, "A4"}
623 }
624 return nil
625 }
626 if p.bidirule != nil && !p.bidirule(s) {
627 return &labelError{s, "B"}
628 }
629 if !p.validateLabels {
630 return nil
631 }
632 trie := p.trie // p.validateLabels is only set if trie is set.
633 if len(s) > 4 && s[2] == '-' && s[3] == '-' {
634 return &labelError{s, "V2"}
635 }
636 if s[0] == '-' || s[len(s)-1] == '-' {
637 return &labelError{s, "V3"}
638 }
639 // TODO: merge the use of this in the trie.
640 v, sz := trie.lookupString(s)
641 x := info(v)
642 if x.isModifier() {
643 return &labelError{s, "V5"}
644 }
645 // Quickly return in the absence of zero-width (non) joiners.
646 if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 {
647 return nil
648 }
649 st := stateStart
650 for i := 0; ; {
651 jt := x.joinType()
652 if s[i:i+sz] == zwj {
653 jt = joinZWJ
654 } else if s[i:i+sz] == zwnj {
655 jt = joinZWNJ
656 }
657 st = joinStates[st][jt]
658 if x.isViramaModifier() {
659 st = joinStates[st][joinVirama]
660 }
661 if i += sz; i == len(s) {
662 break
663 }
664 v, sz = trie.lookupString(s[i:])
665 x = info(v)
666 }
667 if st == stateFAIL || st == stateAfter {
668 return &labelError{s, "C"}
669 }
670 return nil
671}
672
673func ascii(s string) bool {
674 for i := 0; i < len(s); i++ {
675 if s[i] >= utf8.RuneSelf {
676 return false
677 }
678 }
679 return true
680}
diff --git a/vendor/golang.org/x/net/idna/punycode.go b/vendor/golang.org/x/net/idna/punycode.go
new file mode 100644
index 0000000..02c7d59
--- /dev/null
+++ b/vendor/golang.org/x/net/idna/punycode.go
@@ -0,0 +1,203 @@
1// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
2
3// Copyright 2016 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7package idna
8
9// This file implements the Punycode algorithm from RFC 3492.
10
11import (
12 "math"
13 "strings"
14 "unicode/utf8"
15)
16
17// These parameter values are specified in section 5.
18//
19// All computation is done with int32s, so that overflow behavior is identical
20// regardless of whether int is 32-bit or 64-bit.
21const (
22 base int32 = 36
23 damp int32 = 700
24 initialBias int32 = 72
25 initialN int32 = 128
26 skew int32 = 38
27 tmax int32 = 26
28 tmin int32 = 1
29)
30
31func punyError(s string) error { return &labelError{s, "A3"} }
32
33// decode decodes a string as specified in section 6.2.
34func decode(encoded string) (string, error) {
35 if encoded == "" {
36 return "", nil
37 }
38 pos := 1 + strings.LastIndex(encoded, "-")
39 if pos == 1 {
40 return "", punyError(encoded)
41 }
42 if pos == len(encoded) {
43 return encoded[:len(encoded)-1], nil
44 }
45 output := make([]rune, 0, len(encoded))
46 if pos != 0 {
47 for _, r := range encoded[:pos-1] {
48 output = append(output, r)
49 }
50 }
51 i, n, bias := int32(0), initialN, initialBias
52 for pos < len(encoded) {
53 oldI, w := i, int32(1)
54 for k := base; ; k += base {
55 if pos == len(encoded) {
56 return "", punyError(encoded)
57 }
58 digit, ok := decodeDigit(encoded[pos])
59 if !ok {
60 return "", punyError(encoded)
61 }
62 pos++
63 i += digit * w
64 if i < 0 {
65 return "", punyError(encoded)
66 }
67 t := k - bias
68 if t < tmin {
69 t = tmin
70 } else if t > tmax {
71 t = tmax
72 }
73 if digit < t {
74 break
75 }
76 w *= base - t
77 if w >= math.MaxInt32/base {
78 return "", punyError(encoded)
79 }
80 }
81 x := int32(len(output) + 1)
82 bias = adapt(i-oldI, x, oldI == 0)
83 n += i / x
84 i %= x
85 if n > utf8.MaxRune || len(output) >= 1024 {
86 return "", punyError(encoded)
87 }
88 output = append(output, 0)
89 copy(output[i+1:], output[i:])
90 output[i] = n
91 i++
92 }
93 return string(output), nil
94}
95
96// encode encodes a string as specified in section 6.3 and prepends prefix to
97// the result.
98//
99// The "while h < length(input)" line in the specification becomes "for
100// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
101func encode(prefix, s string) (string, error) {
102 output := make([]byte, len(prefix), len(prefix)+1+2*len(s))
103 copy(output, prefix)
104 delta, n, bias := int32(0), initialN, initialBias
105 b, remaining := int32(0), int32(0)
106 for _, r := range s {
107 if r < 0x80 {
108 b++
109 output = append(output, byte(r))
110 } else {
111 remaining++
112 }
113 }
114 h := b
115 if b > 0 {
116 output = append(output, '-')
117 }
118 for remaining != 0 {
119 m := int32(0x7fffffff)
120 for _, r := range s {
121 if m > r && r >= n {
122 m = r
123 }
124 }
125 delta += (m - n) * (h + 1)
126 if delta < 0 {
127 return "", punyError(s)
128 }
129 n = m
130 for _, r := range s {
131 if r < n {
132 delta++
133 if delta < 0 {
134 return "", punyError(s)
135 }
136 continue
137 }
138 if r > n {
139 continue
140 }
141 q := delta
142 for k := base; ; k += base {
143 t := k - bias
144 if t < tmin {
145 t = tmin
146 } else if t > tmax {
147 t = tmax
148 }
149 if q < t {
150 break
151 }
152 output = append(output, encodeDigit(t+(q-t)%(base-t)))
153 q = (q - t) / (base - t)
154 }
155 output = append(output, encodeDigit(q))
156 bias = adapt(delta, h+1, h == b)
157 delta = 0
158 h++
159 remaining--
160 }
161 delta++
162 n++
163 }
164 return string(output), nil
165}
166
167func decodeDigit(x byte) (digit int32, ok bool) {
168 switch {
169 case '0' <= x && x <= '9':
170 return int32(x - ('0' - 26)), true
171 case 'A' <= x && x <= 'Z':
172 return int32(x - 'A'), true
173 case 'a' <= x && x <= 'z':
174 return int32(x - 'a'), true
175 }
176 return 0, false
177}
178
179func encodeDigit(digit int32) byte {
180 switch {
181 case 0 <= digit && digit < 26:
182 return byte(digit + 'a')
183 case 26 <= digit && digit < 36:
184 return byte(digit + ('0' - 26))
185 }
186 panic("idna: internal error in punycode encoding")
187}
188
189// adapt is the bias adaptation function specified in section 6.1.
190func adapt(delta, numPoints int32, firstTime bool) int32 {
191 if firstTime {
192 delta /= damp
193 } else {
194 delta /= 2
195 }
196 delta += delta / numPoints
197 k := int32(0)
198 for delta > ((base-tmin)*tmax)/2 {
199 delta /= base - tmin
200 k += base
201 }
202 return k + (base-tmin+1)*delta/(delta+skew)
203}
diff --git a/vendor/golang.org/x/net/idna/tables.go b/vendor/golang.org/x/net/idna/tables.go
new file mode 100644
index 0000000..d281934
--- /dev/null
+++ b/vendor/golang.org/x/net/idna/tables.go
@@ -0,0 +1,4477 @@
1// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
2
3package idna
4
5// UnicodeVersion is the Unicode version from which the tables in this package are derived.
6const UnicodeVersion = "9.0.0"
7
8var mappings string = "" + // Size: 8176 bytes
9 "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" +
10 "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" +
11 "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" +
12 "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" +
13 "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" +
14 "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" +
15 "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" +
16 "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" +
17 "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" +
18 "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" +
19 "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" +
20 "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" +
21 "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" +
22 "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" +
23 "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" +
24 "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" +
25 "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" +
26 "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" +
27 "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" +
28 "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" +
29 "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" +
30 "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" +
31 "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" +
32 "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" +
33 "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" +
34 "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" +
35 ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" +
36 "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" +
37 "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" +
38 "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" +
39 "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" +
40 "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" +
41 "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" +
42 "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" +
43 "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" +
44 "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" +
45 "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" +
46 "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" +
47 "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" +
48 "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" +
49 "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" +
50 "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" +
51 "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" +
52 "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" +
53 "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" +
54 "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" +
55 "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" +
56 "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" +
57 "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" +
58 "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" +
59 "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" +
60 "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" +
61 "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" +
62 "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" +
63 "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" +
64 "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" +
65 "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" +
66 "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" +
67 "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" +
68 "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" +
69 "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" +
70 "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" +
71 "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" +
72 "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" +
73 "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" +
74 "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" +
75 "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" +
76 "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" +
77 "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" +
78 "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" +
79 "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" +
80 "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" +
81 "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" +
82 " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" +
83 "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" +
84 "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" +
85 "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" +
86 "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" +
87 "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" +
88 "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" +
89 "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" +
90 "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" +
91 "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" +
92 "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" +
93 "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" +
94 "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" +
95 "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" +
96 "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" +
97 "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" +
98 "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" +
99 "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" +
100 "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" +
101 "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" +
102 "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" +
103 "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" +
104 "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" +
105 "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" +
106 "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" +
107 "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" +
108 "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" +
109 "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" +
110 "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" +
111 "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" +
112 "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" +
113 "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" +
114 "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" +
115 "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" +
116 "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" +
117 "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" +
118 "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" +
119 "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" +
120 "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" +
121 "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" +
122 "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" +
123 "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" +
124 "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" +
125 "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" +
126 "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" +
127 "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" +
128 "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" +
129 "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" +
130 "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" +
131 "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" +
132 "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" +
133 "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" +
134 "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" +
135 "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" +
136 "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" +
137 "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" +
138 "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" +
139 "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" +
140 "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" +
141 "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" +
142 "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" +
143 "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" +
144 "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" +
145 "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻"
146
147var xorData string = "" + // Size: 4855 bytes
148 "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" +
149 "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" +
150 "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" +
151 "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" +
152 "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" +
153 "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" +
154 "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" +
155 "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" +
156 "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" +
157 "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" +
158 "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" +
159 "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" +
160 "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" +
161 "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" +
162 "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" +
163 "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" +
164 "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" +
165 "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" +
166 "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" +
167 "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" +
168 "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" +
169 "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" +
170 "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" +
171 "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" +
172 "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" +
173 "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" +
174 "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" +
175 "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" +
176 "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" +
177 "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" +
178 "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" +
179 "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" +
180 "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" +
181 "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" +
182 "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" +
183 "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" +
184 "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " +
185 "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" +
186 "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" +
187 "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" +
188 "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" +
189 "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" +
190 ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" +
191 "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" +
192 "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" +
193 "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" +
194 "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" +
195 "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" +
196 "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" +
197 "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" +
198 "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" +
199 "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" +
200 "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" +
201 "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" +
202 "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" +
203 "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" +
204 "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" +
205 "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" +
206 "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" +
207 "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" +
208 "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" +
209 "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" +
210 "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" +
211 "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" +
212 "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" +
213 "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" +
214 "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" +
215 "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" +
216 "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" +
217 "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" +
218 "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" +
219 "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" +
220 "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" +
221 "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" +
222 "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" +
223 "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" +
224 "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" +
225 "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" +
226 "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" +
227 "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" +
228 "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" +
229 "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" +
230 "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" +
231 "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" +
232 "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" +
233 "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" +
234 "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" +
235 "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" +
236 "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," +
237 "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" +
238 "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" +
239 "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" +
240 "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" +
241 ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" +
242 "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" +
243 "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" +
244 "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" +
245 "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" +
246 "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" +
247 "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" +
248 "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" +
249 "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" +
250 "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" +
251 "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" +
252 "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" +
253 "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" +
254 "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" +
255 "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" +
256 "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" +
257 "\x08\x1a\x0a\x03\x07</\x03\x07:+\x03\x07\x07*\x03\x06&\x1c\x03\x09\x0c" +
258 "\x16\x03\x09\x10\x0e\x03\x08'\x0f\x03\x08+\x09\x03\x074%\x03\x06!3\x03" +
259 "\x06\x03+\x03\x0b\x1e\x19\x03\x0a))\x03\x09\x08\x19\x03\x08,\x05\x03\x07" +
260 "<2\x03\x06\x1c>\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" +
261 "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" +
262 "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" +
263 "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" +
264 "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" +
265 "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" +
266 "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" +
267 "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" +
268 "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" +
269 "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" +
270 "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" +
271 "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" +
272 "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" +
273 "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" +
274 "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" +
275 "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" +
276 "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" +
277 "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." +
278 "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" +
279 "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" +
280 "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " +
281 "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" +
282 "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" +
283 "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" +
284 "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" +
285 "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" +
286 "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" +
287 "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," +
288 "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" +
289 "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" +
290 "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" +
291 "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" +
292 "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" +
293 "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" +
294 "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" +
295 "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" +
296 "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" +
297 "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" +
298 "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" +
299 "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" +
300 "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" +
301 "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" +
302 "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" +
303 "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" +
304 "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" +
305 "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" +
306 "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" +
307 "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" +
308 "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" +
309 "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" +
310 "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" +
311 "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" +
312 "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" +
313 "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" +
314 "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" +
315 "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" +
316 "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" +
317 "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" +
318 "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" +
319 "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" +
320 "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" +
321 "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" +
322 "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" +
323 "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" +
324 "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" +
325 "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" +
326 "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," +
327 "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" +
328 "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" +
329 "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" +
330 "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" +
331 "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" +
332 "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" +
333 "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" +
334 "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" +
335 "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" +
336 "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" +
337 "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" +
338 "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" +
339 "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" +
340 "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" +
341 "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" +
342 "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" +
343 "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" +
344 "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" +
345 "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" +
346 "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" +
347 "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" +
348 "\x04\x03\x0c?\x05\x03\x0c<?\x03\x0c=\x00\x03\x0c=\x06\x03\x0c=\x05\x03" +
349 "\x0c=\x0c\x03\x0c=\x0f\x03\x0c=\x0d\x03\x0c=\x0b\x03\x0c=\x07\x03\x0c=" +
350 "\x19\x03\x0c=\x15\x03\x0c=\x11\x03\x0c=1\x03\x0c=3\x03\x0c=0\x03\x0c=>" +
351 "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" +
352 "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" +
353 "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" +
354 "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" +
355 "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" +
356 "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" +
357 "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" +
358 "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" +
359 "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" +
360 "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" +
361 "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" +
362 "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" +
363 "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" +
364 "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" +
365 "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" +
366 "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" +
367 "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" +
368 "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" +
369 "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" +
370 "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" +
371 "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" +
372 "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" +
373 "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" +
374 "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" +
375 "\x05\x22\x05\x03\x050\x1d"
376
377// lookup returns the trie value for the first UTF-8 encoding in s and
378// the width in bytes of this encoding. The size will be 0 if s does not
379// hold enough bytes to complete the encoding. len(s) must be greater than 0.
380func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {
381 c0 := s[0]
382 switch {
383 case c0 < 0x80: // is ASCII
384 return idnaValues[c0], 1
385 case c0 < 0xC2:
386 return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
387 case c0 < 0xE0: // 2-byte UTF-8
388 if len(s) < 2 {
389 return 0, 0
390 }
391 i := idnaIndex[c0]
392 c1 := s[1]
393 if c1 < 0x80 || 0xC0 <= c1 {
394 return 0, 1 // Illegal UTF-8: not a continuation byte.
395 }
396 return t.lookupValue(uint32(i), c1), 2
397 case c0 < 0xF0: // 3-byte UTF-8
398 if len(s) < 3 {
399 return 0, 0
400 }
401 i := idnaIndex[c0]
402 c1 := s[1]
403 if c1 < 0x80 || 0xC0 <= c1 {
404 return 0, 1 // Illegal UTF-8: not a continuation byte.
405 }
406 o := uint32(i)<<6 + uint32(c1)
407 i = idnaIndex[o]
408 c2 := s[2]
409 if c2 < 0x80 || 0xC0 <= c2 {
410 return 0, 2 // Illegal UTF-8: not a continuation byte.
411 }
412 return t.lookupValue(uint32(i), c2), 3
413 case c0 < 0xF8: // 4-byte UTF-8
414 if len(s) < 4 {
415 return 0, 0
416 }
417 i := idnaIndex[c0]
418 c1 := s[1]
419 if c1 < 0x80 || 0xC0 <= c1 {
420 return 0, 1 // Illegal UTF-8: not a continuation byte.
421 }
422 o := uint32(i)<<6 + uint32(c1)
423 i = idnaIndex[o]
424 c2 := s[2]
425 if c2 < 0x80 || 0xC0 <= c2 {
426 return 0, 2 // Illegal UTF-8: not a continuation byte.
427 }
428 o = uint32(i)<<6 + uint32(c2)
429 i = idnaIndex[o]
430 c3 := s[3]
431 if c3 < 0x80 || 0xC0 <= c3 {
432 return 0, 3 // Illegal UTF-8: not a continuation byte.
433 }
434 return t.lookupValue(uint32(i), c3), 4
435 }
436 // Illegal rune
437 return 0, 1
438}
439
440// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
441// s must start with a full and valid UTF-8 encoded rune.
442func (t *idnaTrie) lookupUnsafe(s []byte) uint16 {
443 c0 := s[0]
444 if c0 < 0x80 { // is ASCII
445 return idnaValues[c0]
446 }
447 i := idnaIndex[c0]
448 if c0 < 0xE0 { // 2-byte UTF-8
449 return t.lookupValue(uint32(i), s[1])
450 }
451 i = idnaIndex[uint32(i)<<6+uint32(s[1])]
452 if c0 < 0xF0 { // 3-byte UTF-8
453 return t.lookupValue(uint32(i), s[2])
454 }
455 i = idnaIndex[uint32(i)<<6+uint32(s[2])]
456 if c0 < 0xF8 { // 4-byte UTF-8
457 return t.lookupValue(uint32(i), s[3])
458 }
459 return 0
460}
461
462// lookupString returns the trie value for the first UTF-8 encoding in s and
463// the width in bytes of this encoding. The size will be 0 if s does not
464// hold enough bytes to complete the encoding. len(s) must be greater than 0.
465func (t *idnaTrie) lookupString(s string) (v uint16, sz int) {
466 c0 := s[0]
467 switch {
468 case c0 < 0x80: // is ASCII
469 return idnaValues[c0], 1
470 case c0 < 0xC2:
471 return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
472 case c0 < 0xE0: // 2-byte UTF-8
473 if len(s) < 2 {
474 return 0, 0
475 }
476 i := idnaIndex[c0]
477 c1 := s[1]
478 if c1 < 0x80 || 0xC0 <= c1 {
479 return 0, 1 // Illegal UTF-8: not a continuation byte.
480 }
481 return t.lookupValue(uint32(i), c1), 2
482 case c0 < 0xF0: // 3-byte UTF-8
483 if len(s) < 3 {
484 return 0, 0
485 }
486 i := idnaIndex[c0]
487 c1 := s[1]
488 if c1 < 0x80 || 0xC0 <= c1 {
489 return 0, 1 // Illegal UTF-8: not a continuation byte.
490 }
491 o := uint32(i)<<6 + uint32(c1)
492 i = idnaIndex[o]
493 c2 := s[2]
494 if c2 < 0x80 || 0xC0 <= c2 {
495 return 0, 2 // Illegal UTF-8: not a continuation byte.
496 }
497 return t.lookupValue(uint32(i), c2), 3
498 case c0 < 0xF8: // 4-byte UTF-8
499 if len(s) < 4 {
500 return 0, 0
501 }
502 i := idnaIndex[c0]
503 c1 := s[1]
504 if c1 < 0x80 || 0xC0 <= c1 {
505 return 0, 1 // Illegal UTF-8: not a continuation byte.
506 }
507 o := uint32(i)<<6 + uint32(c1)
508 i = idnaIndex[o]
509 c2 := s[2]
510 if c2 < 0x80 || 0xC0 <= c2 {
511 return 0, 2 // Illegal UTF-8: not a continuation byte.
512 }
513 o = uint32(i)<<6 + uint32(c2)
514 i = idnaIndex[o]
515 c3 := s[3]
516 if c3 < 0x80 || 0xC0 <= c3 {
517 return 0, 3 // Illegal UTF-8: not a continuation byte.
518 }
519 return t.lookupValue(uint32(i), c3), 4
520 }
521 // Illegal rune
522 return 0, 1
523}
524
525// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
526// s must start with a full and valid UTF-8 encoded rune.
527func (t *idnaTrie) lookupStringUnsafe(s string) uint16 {
528 c0 := s[0]
529 if c0 < 0x80 { // is ASCII
530 return idnaValues[c0]
531 }
532 i := idnaIndex[c0]
533 if c0 < 0xE0 { // 2-byte UTF-8
534 return t.lookupValue(uint32(i), s[1])
535 }
536 i = idnaIndex[uint32(i)<<6+uint32(s[1])]
537 if c0 < 0xF0 { // 3-byte UTF-8
538 return t.lookupValue(uint32(i), s[2])
539 }
540 i = idnaIndex[uint32(i)<<6+uint32(s[2])]
541 if c0 < 0xF8 { // 4-byte UTF-8
542 return t.lookupValue(uint32(i), s[3])
543 }
544 return 0
545}
546
547// idnaTrie. Total size: 28496 bytes (27.83 KiB). Checksum: 43288b883596640e.
548type idnaTrie struct{}
549
550func newIdnaTrie(i int) *idnaTrie {
551 return &idnaTrie{}
552}
553
554// lookupValue determines the type of block n and looks up the value for b.
555func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {
556 switch {
557 case n < 123:
558 return uint16(idnaValues[n<<6+uint32(b)])
559 default:
560 n -= 123
561 return uint16(idnaSparse.lookup(n, b))
562 }
563}
564
565// idnaValues: 125 blocks, 8000 entries, 16000 bytes
566// The third block is the zero block.
567var idnaValues = [8000]uint16{
568 // Block 0x0, offset 0x0
569 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,
570 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,
571 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,
572 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,
573 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,
574 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,
575 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,
576 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,
577 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,
578 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,
579 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,
580 // Block 0x1, offset 0x40
581 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,
582 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,
583 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,
584 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,
585 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,
586 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,
587 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,
588 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,
589 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,
590 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,
591 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,
592 // Block 0x2, offset 0x80
593 // Block 0x3, offset 0xc0
594 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,
595 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,
596 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,
597 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,
598 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,
599 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,
600 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,
601 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,
602 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,
603 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,
604 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,
605 // Block 0x4, offset 0x100
606 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,
607 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,
608 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,
609 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,
610 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,
611 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,
612 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,
613 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,
614 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,
615 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,
616 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,
617 // Block 0x5, offset 0x140
618 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,
619 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,
620 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,
621 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,
622 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,
623 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,
624 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,
625 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,
626 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,
627 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,
628 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,
629 // Block 0x6, offset 0x180
630 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,
631 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,
632 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,
633 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,
634 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,
635 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,
636 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,
637 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,
638 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,
639 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,
640 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,
641 // Block 0x7, offset 0x1c0
642 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,
643 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,
644 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,
645 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,
646 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,
647 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,
648 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,
649 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,
650 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,
651 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,
652 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,
653 // Block 0x8, offset 0x200
654 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,
655 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,
656 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,
657 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,
658 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,
659 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,
660 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,
661 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,
662 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,
663 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,
664 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,
665 // Block 0x9, offset 0x240
666 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,
667 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,
668 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,
669 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,
670 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,
671 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,
672 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,
673 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,
674 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,
675 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,
676 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,
677 // Block 0xa, offset 0x280
678 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x1308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,
679 0x286: 0x1308, 0x287: 0x1308, 0x288: 0x1308, 0x289: 0x1308, 0x28a: 0x1308, 0x28b: 0x1308,
680 0x28c: 0x1308, 0x28d: 0x1308, 0x28e: 0x1308, 0x28f: 0x13c0, 0x290: 0x1308, 0x291: 0x1308,
681 0x292: 0x1308, 0x293: 0x1308, 0x294: 0x1308, 0x295: 0x1308, 0x296: 0x1308, 0x297: 0x1308,
682 0x298: 0x1308, 0x299: 0x1308, 0x29a: 0x1308, 0x29b: 0x1308, 0x29c: 0x1308, 0x29d: 0x1308,
683 0x29e: 0x1308, 0x29f: 0x1308, 0x2a0: 0x1308, 0x2a1: 0x1308, 0x2a2: 0x1308, 0x2a3: 0x1308,
684 0x2a4: 0x1308, 0x2a5: 0x1308, 0x2a6: 0x1308, 0x2a7: 0x1308, 0x2a8: 0x1308, 0x2a9: 0x1308,
685 0x2aa: 0x1308, 0x2ab: 0x1308, 0x2ac: 0x1308, 0x2ad: 0x1308, 0x2ae: 0x1308, 0x2af: 0x1308,
686 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,
687 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,
688 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,
689 // Block 0xb, offset 0x2c0
690 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,
691 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,
692 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,
693 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,
694 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,
695 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,
696 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,
697 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,
698 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,
699 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,
700 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,
701 // Block 0xc, offset 0x300
702 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,
703 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,
704 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,
705 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,
706 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,
707 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,
708 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,
709 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,
710 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,
711 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,
712 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,
713 // Block 0xd, offset 0x340
714 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,
715 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,
716 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,
717 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,
718 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,
719 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,
720 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,
721 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,
722 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,
723 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,
724 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,
725 // Block 0xe, offset 0x380
726 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x1308, 0x384: 0x1308, 0x385: 0x1308,
727 0x386: 0x1308, 0x387: 0x1308, 0x388: 0x1318, 0x389: 0x1318, 0x38a: 0xe00d, 0x38b: 0x0008,
728 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,
729 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,
730 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,
731 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,
732 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,
733 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,
734 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,
735 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,
736 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,
737 // Block 0xf, offset 0x3c0
738 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,
739 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,
740 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,
741 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,
742 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,
743 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,
744 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,
745 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,
746 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,
747 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,
748 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,
749 // Block 0x10, offset 0x400
750 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,
751 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,
752 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,
753 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,
754 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,
755 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,
756 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,
757 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,
758 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,
759 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,
760 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,
761 // Block 0x11, offset 0x440
762 0x440: 0x0040, 0x441: 0x0040, 0x442: 0x0040, 0x443: 0x0040, 0x444: 0x0040, 0x445: 0x0040,
763 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0018, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0018,
764 0x44c: 0x0018, 0x44d: 0x0018, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x1308, 0x451: 0x1308,
765 0x452: 0x1308, 0x453: 0x1308, 0x454: 0x1308, 0x455: 0x1308, 0x456: 0x1308, 0x457: 0x1308,
766 0x458: 0x1308, 0x459: 0x1308, 0x45a: 0x1308, 0x45b: 0x0018, 0x45c: 0x0340, 0x45d: 0x0040,
767 0x45e: 0x0018, 0x45f: 0x0018, 0x460: 0x0208, 0x461: 0x0008, 0x462: 0x0408, 0x463: 0x0408,
768 0x464: 0x0408, 0x465: 0x0408, 0x466: 0x0208, 0x467: 0x0408, 0x468: 0x0208, 0x469: 0x0408,
769 0x46a: 0x0208, 0x46b: 0x0208, 0x46c: 0x0208, 0x46d: 0x0208, 0x46e: 0x0208, 0x46f: 0x0408,
770 0x470: 0x0408, 0x471: 0x0408, 0x472: 0x0408, 0x473: 0x0208, 0x474: 0x0208, 0x475: 0x0208,
771 0x476: 0x0208, 0x477: 0x0208, 0x478: 0x0208, 0x479: 0x0208, 0x47a: 0x0208, 0x47b: 0x0208,
772 0x47c: 0x0208, 0x47d: 0x0208, 0x47e: 0x0208, 0x47f: 0x0208,
773 // Block 0x12, offset 0x480
774 0x480: 0x0408, 0x481: 0x0208, 0x482: 0x0208, 0x483: 0x0408, 0x484: 0x0408, 0x485: 0x0408,
775 0x486: 0x0408, 0x487: 0x0408, 0x488: 0x0408, 0x489: 0x0408, 0x48a: 0x0408, 0x48b: 0x0408,
776 0x48c: 0x0208, 0x48d: 0x0408, 0x48e: 0x0208, 0x48f: 0x0408, 0x490: 0x0208, 0x491: 0x0208,
777 0x492: 0x0408, 0x493: 0x0408, 0x494: 0x0018, 0x495: 0x0408, 0x496: 0x1308, 0x497: 0x1308,
778 0x498: 0x1308, 0x499: 0x1308, 0x49a: 0x1308, 0x49b: 0x1308, 0x49c: 0x1308, 0x49d: 0x0040,
779 0x49e: 0x0018, 0x49f: 0x1308, 0x4a0: 0x1308, 0x4a1: 0x1308, 0x4a2: 0x1308, 0x4a3: 0x1308,
780 0x4a4: 0x1308, 0x4a5: 0x0008, 0x4a6: 0x0008, 0x4a7: 0x1308, 0x4a8: 0x1308, 0x4a9: 0x0018,
781 0x4aa: 0x1308, 0x4ab: 0x1308, 0x4ac: 0x1308, 0x4ad: 0x1308, 0x4ae: 0x0408, 0x4af: 0x0408,
782 0x4b0: 0x0008, 0x4b1: 0x0008, 0x4b2: 0x0008, 0x4b3: 0x0008, 0x4b4: 0x0008, 0x4b5: 0x0008,
783 0x4b6: 0x0008, 0x4b7: 0x0008, 0x4b8: 0x0008, 0x4b9: 0x0008, 0x4ba: 0x0208, 0x4bb: 0x0208,
784 0x4bc: 0x0208, 0x4bd: 0x0008, 0x4be: 0x0008, 0x4bf: 0x0208,
785 // Block 0x13, offset 0x4c0
786 0x4c0: 0x0018, 0x4c1: 0x0018, 0x4c2: 0x0018, 0x4c3: 0x0018, 0x4c4: 0x0018, 0x4c5: 0x0018,
787 0x4c6: 0x0018, 0x4c7: 0x0018, 0x4c8: 0x0018, 0x4c9: 0x0018, 0x4ca: 0x0018, 0x4cb: 0x0018,
788 0x4cc: 0x0018, 0x4cd: 0x0018, 0x4ce: 0x0040, 0x4cf: 0x0340, 0x4d0: 0x0408, 0x4d1: 0x1308,
789 0x4d2: 0x0208, 0x4d3: 0x0208, 0x4d4: 0x0208, 0x4d5: 0x0408, 0x4d6: 0x0408, 0x4d7: 0x0408,
790 0x4d8: 0x0408, 0x4d9: 0x0408, 0x4da: 0x0208, 0x4db: 0x0208, 0x4dc: 0x0208, 0x4dd: 0x0208,
791 0x4de: 0x0408, 0x4df: 0x0208, 0x4e0: 0x0208, 0x4e1: 0x0208, 0x4e2: 0x0208, 0x4e3: 0x0208,
792 0x4e4: 0x0208, 0x4e5: 0x0208, 0x4e6: 0x0208, 0x4e7: 0x0208, 0x4e8: 0x0408, 0x4e9: 0x0208,
793 0x4ea: 0x0408, 0x4eb: 0x0208, 0x4ec: 0x0408, 0x4ed: 0x0208, 0x4ee: 0x0208, 0x4ef: 0x0408,
794 0x4f0: 0x1308, 0x4f1: 0x1308, 0x4f2: 0x1308, 0x4f3: 0x1308, 0x4f4: 0x1308, 0x4f5: 0x1308,
795 0x4f6: 0x1308, 0x4f7: 0x1308, 0x4f8: 0x1308, 0x4f9: 0x1308, 0x4fa: 0x1308, 0x4fb: 0x1308,
796 0x4fc: 0x1308, 0x4fd: 0x1308, 0x4fe: 0x1308, 0x4ff: 0x1308,
797 // Block 0x14, offset 0x500
798 0x500: 0x1008, 0x501: 0x1308, 0x502: 0x1308, 0x503: 0x1308, 0x504: 0x1308, 0x505: 0x1308,
799 0x506: 0x1308, 0x507: 0x1308, 0x508: 0x1308, 0x509: 0x1008, 0x50a: 0x1008, 0x50b: 0x1008,
800 0x50c: 0x1008, 0x50d: 0x1b08, 0x50e: 0x1008, 0x50f: 0x1008, 0x510: 0x0008, 0x511: 0x1308,
801 0x512: 0x1308, 0x513: 0x1308, 0x514: 0x1308, 0x515: 0x1308, 0x516: 0x1308, 0x517: 0x1308,
802 0x518: 0x04c9, 0x519: 0x0501, 0x51a: 0x0539, 0x51b: 0x0571, 0x51c: 0x05a9, 0x51d: 0x05e1,
803 0x51e: 0x0619, 0x51f: 0x0651, 0x520: 0x0008, 0x521: 0x0008, 0x522: 0x1308, 0x523: 0x1308,
804 0x524: 0x0018, 0x525: 0x0018, 0x526: 0x0008, 0x527: 0x0008, 0x528: 0x0008, 0x529: 0x0008,
805 0x52a: 0x0008, 0x52b: 0x0008, 0x52c: 0x0008, 0x52d: 0x0008, 0x52e: 0x0008, 0x52f: 0x0008,
806 0x530: 0x0018, 0x531: 0x0008, 0x532: 0x0008, 0x533: 0x0008, 0x534: 0x0008, 0x535: 0x0008,
807 0x536: 0x0008, 0x537: 0x0008, 0x538: 0x0008, 0x539: 0x0008, 0x53a: 0x0008, 0x53b: 0x0008,
808 0x53c: 0x0008, 0x53d: 0x0008, 0x53e: 0x0008, 0x53f: 0x0008,
809 // Block 0x15, offset 0x540
810 0x540: 0x0008, 0x541: 0x1308, 0x542: 0x1008, 0x543: 0x1008, 0x544: 0x0040, 0x545: 0x0008,
811 0x546: 0x0008, 0x547: 0x0008, 0x548: 0x0008, 0x549: 0x0008, 0x54a: 0x0008, 0x54b: 0x0008,
812 0x54c: 0x0008, 0x54d: 0x0040, 0x54e: 0x0040, 0x54f: 0x0008, 0x550: 0x0008, 0x551: 0x0040,
813 0x552: 0x0040, 0x553: 0x0008, 0x554: 0x0008, 0x555: 0x0008, 0x556: 0x0008, 0x557: 0x0008,
814 0x558: 0x0008, 0x559: 0x0008, 0x55a: 0x0008, 0x55b: 0x0008, 0x55c: 0x0008, 0x55d: 0x0008,
815 0x55e: 0x0008, 0x55f: 0x0008, 0x560: 0x0008, 0x561: 0x0008, 0x562: 0x0008, 0x563: 0x0008,
816 0x564: 0x0008, 0x565: 0x0008, 0x566: 0x0008, 0x567: 0x0008, 0x568: 0x0008, 0x569: 0x0040,
817 0x56a: 0x0008, 0x56b: 0x0008, 0x56c: 0x0008, 0x56d: 0x0008, 0x56e: 0x0008, 0x56f: 0x0008,
818 0x570: 0x0008, 0x571: 0x0040, 0x572: 0x0008, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,
819 0x576: 0x0008, 0x577: 0x0008, 0x578: 0x0008, 0x579: 0x0008, 0x57a: 0x0040, 0x57b: 0x0040,
820 0x57c: 0x1308, 0x57d: 0x0008, 0x57e: 0x1008, 0x57f: 0x1008,
821 // Block 0x16, offset 0x580
822 0x580: 0x1008, 0x581: 0x1308, 0x582: 0x1308, 0x583: 0x1308, 0x584: 0x1308, 0x585: 0x0040,
823 0x586: 0x0040, 0x587: 0x1008, 0x588: 0x1008, 0x589: 0x0040, 0x58a: 0x0040, 0x58b: 0x1008,
824 0x58c: 0x1008, 0x58d: 0x1b08, 0x58e: 0x0008, 0x58f: 0x0040, 0x590: 0x0040, 0x591: 0x0040,
825 0x592: 0x0040, 0x593: 0x0040, 0x594: 0x0040, 0x595: 0x0040, 0x596: 0x0040, 0x597: 0x1008,
826 0x598: 0x0040, 0x599: 0x0040, 0x59a: 0x0040, 0x59b: 0x0040, 0x59c: 0x0689, 0x59d: 0x06c1,
827 0x59e: 0x0040, 0x59f: 0x06f9, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x1308, 0x5a3: 0x1308,
828 0x5a4: 0x0040, 0x5a5: 0x0040, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,
829 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,
830 0x5b0: 0x0008, 0x5b1: 0x0008, 0x5b2: 0x0018, 0x5b3: 0x0018, 0x5b4: 0x0018, 0x5b5: 0x0018,
831 0x5b6: 0x0018, 0x5b7: 0x0018, 0x5b8: 0x0018, 0x5b9: 0x0018, 0x5ba: 0x0018, 0x5bb: 0x0018,
832 0x5bc: 0x0040, 0x5bd: 0x0040, 0x5be: 0x0040, 0x5bf: 0x0040,
833 // Block 0x17, offset 0x5c0
834 0x5c0: 0x0040, 0x5c1: 0x1308, 0x5c2: 0x1308, 0x5c3: 0x1008, 0x5c4: 0x0040, 0x5c5: 0x0008,
835 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0040,
836 0x5cc: 0x0040, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,
837 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,
838 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,
839 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,
840 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,
841 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,
842 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0731, 0x5f4: 0x0040, 0x5f5: 0x0008,
843 0x5f6: 0x0769, 0x5f7: 0x0040, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,
844 0x5fc: 0x1308, 0x5fd: 0x0040, 0x5fe: 0x1008, 0x5ff: 0x1008,
845 // Block 0x18, offset 0x600
846 0x600: 0x1008, 0x601: 0x1308, 0x602: 0x1308, 0x603: 0x0040, 0x604: 0x0040, 0x605: 0x0040,
847 0x606: 0x0040, 0x607: 0x1308, 0x608: 0x1308, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x1308,
848 0x60c: 0x1308, 0x60d: 0x1b08, 0x60e: 0x0040, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x1308,
849 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x0040,
850 0x618: 0x0040, 0x619: 0x07a1, 0x61a: 0x07d9, 0x61b: 0x0811, 0x61c: 0x0008, 0x61d: 0x0040,
851 0x61e: 0x0849, 0x61f: 0x0040, 0x620: 0x0040, 0x621: 0x0040, 0x622: 0x0040, 0x623: 0x0040,
852 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,
853 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,
854 0x630: 0x1308, 0x631: 0x1308, 0x632: 0x0008, 0x633: 0x0008, 0x634: 0x0008, 0x635: 0x1308,
855 0x636: 0x0040, 0x637: 0x0040, 0x638: 0x0040, 0x639: 0x0040, 0x63a: 0x0040, 0x63b: 0x0040,
856 0x63c: 0x0040, 0x63d: 0x0040, 0x63e: 0x0040, 0x63f: 0x0040,
857 // Block 0x19, offset 0x640
858 0x640: 0x0040, 0x641: 0x1308, 0x642: 0x1308, 0x643: 0x1008, 0x644: 0x0040, 0x645: 0x0008,
859 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0008,
860 0x64c: 0x0008, 0x64d: 0x0008, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0008,
861 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,
862 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,
863 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,
864 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,
865 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,
866 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0008, 0x674: 0x0040, 0x675: 0x0008,
867 0x676: 0x0008, 0x677: 0x0008, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,
868 0x67c: 0x1308, 0x67d: 0x0008, 0x67e: 0x1008, 0x67f: 0x1008,
869 // Block 0x1a, offset 0x680
870 0x680: 0x1008, 0x681: 0x1308, 0x682: 0x1308, 0x683: 0x1308, 0x684: 0x1308, 0x685: 0x1308,
871 0x686: 0x0040, 0x687: 0x1308, 0x688: 0x1308, 0x689: 0x1008, 0x68a: 0x0040, 0x68b: 0x1008,
872 0x68c: 0x1008, 0x68d: 0x1b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0008, 0x691: 0x0040,
873 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,
874 0x698: 0x0040, 0x699: 0x0040, 0x69a: 0x0040, 0x69b: 0x0040, 0x69c: 0x0040, 0x69d: 0x0040,
875 0x69e: 0x0040, 0x69f: 0x0040, 0x6a0: 0x0008, 0x6a1: 0x0008, 0x6a2: 0x1308, 0x6a3: 0x1308,
876 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,
877 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,
878 0x6b0: 0x0018, 0x6b1: 0x0018, 0x6b2: 0x0040, 0x6b3: 0x0040, 0x6b4: 0x0040, 0x6b5: 0x0040,
879 0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0008, 0x6ba: 0x0040, 0x6bb: 0x0040,
880 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,
881 // Block 0x1b, offset 0x6c0
882 0x6c0: 0x0040, 0x6c1: 0x1308, 0x6c2: 0x1008, 0x6c3: 0x1008, 0x6c4: 0x0040, 0x6c5: 0x0008,
883 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,
884 0x6cc: 0x0008, 0x6cd: 0x0040, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0040,
885 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,
886 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,
887 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,
888 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,
889 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,
890 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,
891 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,
892 0x6fc: 0x1308, 0x6fd: 0x0008, 0x6fe: 0x1008, 0x6ff: 0x1308,
893 // Block 0x1c, offset 0x700
894 0x700: 0x1008, 0x701: 0x1308, 0x702: 0x1308, 0x703: 0x1308, 0x704: 0x1308, 0x705: 0x0040,
895 0x706: 0x0040, 0x707: 0x1008, 0x708: 0x1008, 0x709: 0x0040, 0x70a: 0x0040, 0x70b: 0x1008,
896 0x70c: 0x1008, 0x70d: 0x1b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0040, 0x711: 0x0040,
897 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x1308, 0x717: 0x1008,
898 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0881, 0x71d: 0x08b9,
899 0x71e: 0x0040, 0x71f: 0x0008, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x1308, 0x723: 0x1308,
900 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,
901 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,
902 0x730: 0x0018, 0x731: 0x0008, 0x732: 0x0018, 0x733: 0x0018, 0x734: 0x0018, 0x735: 0x0018,
903 0x736: 0x0018, 0x737: 0x0018, 0x738: 0x0040, 0x739: 0x0040, 0x73a: 0x0040, 0x73b: 0x0040,
904 0x73c: 0x0040, 0x73d: 0x0040, 0x73e: 0x0040, 0x73f: 0x0040,
905 // Block 0x1d, offset 0x740
906 0x740: 0x0040, 0x741: 0x0040, 0x742: 0x1308, 0x743: 0x0008, 0x744: 0x0040, 0x745: 0x0008,
907 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0040,
908 0x74c: 0x0040, 0x74d: 0x0040, 0x74e: 0x0008, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,
909 0x752: 0x0008, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0040, 0x757: 0x0040,
910 0x758: 0x0040, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0040, 0x75c: 0x0008, 0x75d: 0x0040,
911 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0040, 0x761: 0x0040, 0x762: 0x0040, 0x763: 0x0008,
912 0x764: 0x0008, 0x765: 0x0040, 0x766: 0x0040, 0x767: 0x0040, 0x768: 0x0008, 0x769: 0x0008,
913 0x76a: 0x0008, 0x76b: 0x0040, 0x76c: 0x0040, 0x76d: 0x0040, 0x76e: 0x0008, 0x76f: 0x0008,
914 0x770: 0x0008, 0x771: 0x0008, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0008, 0x775: 0x0008,
915 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,
916 0x77c: 0x0040, 0x77d: 0x0040, 0x77e: 0x1008, 0x77f: 0x1008,
917 // Block 0x1e, offset 0x780
918 0x780: 0x1308, 0x781: 0x1008, 0x782: 0x1008, 0x783: 0x1008, 0x784: 0x1008, 0x785: 0x0040,
919 0x786: 0x1308, 0x787: 0x1308, 0x788: 0x1308, 0x789: 0x0040, 0x78a: 0x1308, 0x78b: 0x1308,
920 0x78c: 0x1308, 0x78d: 0x1b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,
921 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x1308, 0x796: 0x1308, 0x797: 0x0040,
922 0x798: 0x0008, 0x799: 0x0008, 0x79a: 0x0008, 0x79b: 0x0040, 0x79c: 0x0040, 0x79d: 0x0040,
923 0x79e: 0x0040, 0x79f: 0x0040, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x1308, 0x7a3: 0x1308,
924 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,
925 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,
926 0x7b0: 0x0040, 0x7b1: 0x0040, 0x7b2: 0x0040, 0x7b3: 0x0040, 0x7b4: 0x0040, 0x7b5: 0x0040,
927 0x7b6: 0x0040, 0x7b7: 0x0040, 0x7b8: 0x0018, 0x7b9: 0x0018, 0x7ba: 0x0018, 0x7bb: 0x0018,
928 0x7bc: 0x0018, 0x7bd: 0x0018, 0x7be: 0x0018, 0x7bf: 0x0018,
929 // Block 0x1f, offset 0x7c0
930 0x7c0: 0x0008, 0x7c1: 0x1308, 0x7c2: 0x1008, 0x7c3: 0x1008, 0x7c4: 0x0040, 0x7c5: 0x0008,
931 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0008,
932 0x7cc: 0x0008, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,
933 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0008, 0x7d7: 0x0008,
934 0x7d8: 0x0008, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0008, 0x7dc: 0x0008, 0x7dd: 0x0008,
935 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0008, 0x7e1: 0x0008, 0x7e2: 0x0008, 0x7e3: 0x0008,
936 0x7e4: 0x0008, 0x7e5: 0x0008, 0x7e6: 0x0008, 0x7e7: 0x0008, 0x7e8: 0x0008, 0x7e9: 0x0040,
937 0x7ea: 0x0008, 0x7eb: 0x0008, 0x7ec: 0x0008, 0x7ed: 0x0008, 0x7ee: 0x0008, 0x7ef: 0x0008,
938 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0040, 0x7f5: 0x0008,
939 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,
940 0x7fc: 0x1308, 0x7fd: 0x0008, 0x7fe: 0x1008, 0x7ff: 0x1308,
941 // Block 0x20, offset 0x800
942 0x800: 0x1008, 0x801: 0x1008, 0x802: 0x1008, 0x803: 0x1008, 0x804: 0x1008, 0x805: 0x0040,
943 0x806: 0x1308, 0x807: 0x1008, 0x808: 0x1008, 0x809: 0x0040, 0x80a: 0x1008, 0x80b: 0x1008,
944 0x80c: 0x1308, 0x80d: 0x1b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,
945 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x1008, 0x816: 0x1008, 0x817: 0x0040,
946 0x818: 0x0040, 0x819: 0x0040, 0x81a: 0x0040, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,
947 0x81e: 0x0008, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x1308, 0x823: 0x1308,
948 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,
949 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,
950 0x830: 0x0040, 0x831: 0x0008, 0x832: 0x0008, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,
951 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0040, 0x839: 0x0040, 0x83a: 0x0040, 0x83b: 0x0040,
952 0x83c: 0x0040, 0x83d: 0x0040, 0x83e: 0x0040, 0x83f: 0x0040,
953 // Block 0x21, offset 0x840
954 0x840: 0x1008, 0x841: 0x1308, 0x842: 0x1308, 0x843: 0x1308, 0x844: 0x1308, 0x845: 0x0040,
955 0x846: 0x1008, 0x847: 0x1008, 0x848: 0x1008, 0x849: 0x0040, 0x84a: 0x1008, 0x84b: 0x1008,
956 0x84c: 0x1008, 0x84d: 0x1b08, 0x84e: 0x0008, 0x84f: 0x0018, 0x850: 0x0040, 0x851: 0x0040,
957 0x852: 0x0040, 0x853: 0x0040, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x1008,
958 0x858: 0x0018, 0x859: 0x0018, 0x85a: 0x0018, 0x85b: 0x0018, 0x85c: 0x0018, 0x85d: 0x0018,
959 0x85e: 0x0018, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x1308, 0x863: 0x1308,
960 0x864: 0x0040, 0x865: 0x0040, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0008,
961 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,
962 0x870: 0x0018, 0x871: 0x0018, 0x872: 0x0018, 0x873: 0x0018, 0x874: 0x0018, 0x875: 0x0018,
963 0x876: 0x0018, 0x877: 0x0018, 0x878: 0x0018, 0x879: 0x0018, 0x87a: 0x0008, 0x87b: 0x0008,
964 0x87c: 0x0008, 0x87d: 0x0008, 0x87e: 0x0008, 0x87f: 0x0008,
965 // Block 0x22, offset 0x880
966 0x880: 0x0040, 0x881: 0x0008, 0x882: 0x0008, 0x883: 0x0040, 0x884: 0x0008, 0x885: 0x0040,
967 0x886: 0x0040, 0x887: 0x0008, 0x888: 0x0008, 0x889: 0x0040, 0x88a: 0x0008, 0x88b: 0x0040,
968 0x88c: 0x0040, 0x88d: 0x0008, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,
969 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0008, 0x895: 0x0008, 0x896: 0x0008, 0x897: 0x0008,
970 0x898: 0x0040, 0x899: 0x0008, 0x89a: 0x0008, 0x89b: 0x0008, 0x89c: 0x0008, 0x89d: 0x0008,
971 0x89e: 0x0008, 0x89f: 0x0008, 0x8a0: 0x0040, 0x8a1: 0x0008, 0x8a2: 0x0008, 0x8a3: 0x0008,
972 0x8a4: 0x0040, 0x8a5: 0x0008, 0x8a6: 0x0040, 0x8a7: 0x0008, 0x8a8: 0x0040, 0x8a9: 0x0040,
973 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0040, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,
974 0x8b0: 0x0008, 0x8b1: 0x1308, 0x8b2: 0x0008, 0x8b3: 0x0929, 0x8b4: 0x1308, 0x8b5: 0x1308,
975 0x8b6: 0x1308, 0x8b7: 0x1308, 0x8b8: 0x1308, 0x8b9: 0x1308, 0x8ba: 0x0040, 0x8bb: 0x1308,
976 0x8bc: 0x1308, 0x8bd: 0x0008, 0x8be: 0x0040, 0x8bf: 0x0040,
977 // Block 0x23, offset 0x8c0
978 0x8c0: 0x0008, 0x8c1: 0x0008, 0x8c2: 0x0008, 0x8c3: 0x09d1, 0x8c4: 0x0008, 0x8c5: 0x0008,
979 0x8c6: 0x0008, 0x8c7: 0x0008, 0x8c8: 0x0040, 0x8c9: 0x0008, 0x8ca: 0x0008, 0x8cb: 0x0008,
980 0x8cc: 0x0008, 0x8cd: 0x0a09, 0x8ce: 0x0008, 0x8cf: 0x0008, 0x8d0: 0x0008, 0x8d1: 0x0008,
981 0x8d2: 0x0a41, 0x8d3: 0x0008, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x0a79,
982 0x8d8: 0x0008, 0x8d9: 0x0008, 0x8da: 0x0008, 0x8db: 0x0008, 0x8dc: 0x0ab1, 0x8dd: 0x0008,
983 0x8de: 0x0008, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x0008, 0x8e3: 0x0008,
984 0x8e4: 0x0008, 0x8e5: 0x0008, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0ae9,
985 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0040, 0x8ee: 0x0040, 0x8ef: 0x0040,
986 0x8f0: 0x0040, 0x8f1: 0x1308, 0x8f2: 0x1308, 0x8f3: 0x0b21, 0x8f4: 0x1308, 0x8f5: 0x0b59,
987 0x8f6: 0x0b91, 0x8f7: 0x0bc9, 0x8f8: 0x0c19, 0x8f9: 0x0c51, 0x8fa: 0x1308, 0x8fb: 0x1308,
988 0x8fc: 0x1308, 0x8fd: 0x1308, 0x8fe: 0x1308, 0x8ff: 0x1008,
989 // Block 0x24, offset 0x900
990 0x900: 0x1308, 0x901: 0x0ca1, 0x902: 0x1308, 0x903: 0x1308, 0x904: 0x1b08, 0x905: 0x0018,
991 0x906: 0x1308, 0x907: 0x1308, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0008,
992 0x90c: 0x0008, 0x90d: 0x1308, 0x90e: 0x1308, 0x90f: 0x1308, 0x910: 0x1308, 0x911: 0x1308,
993 0x912: 0x1308, 0x913: 0x0cd9, 0x914: 0x1308, 0x915: 0x1308, 0x916: 0x1308, 0x917: 0x1308,
994 0x918: 0x0040, 0x919: 0x1308, 0x91a: 0x1308, 0x91b: 0x1308, 0x91c: 0x1308, 0x91d: 0x0d11,
995 0x91e: 0x1308, 0x91f: 0x1308, 0x920: 0x1308, 0x921: 0x1308, 0x922: 0x0d49, 0x923: 0x1308,
996 0x924: 0x1308, 0x925: 0x1308, 0x926: 0x1308, 0x927: 0x0d81, 0x928: 0x1308, 0x929: 0x1308,
997 0x92a: 0x1308, 0x92b: 0x1308, 0x92c: 0x0db9, 0x92d: 0x1308, 0x92e: 0x1308, 0x92f: 0x1308,
998 0x930: 0x1308, 0x931: 0x1308, 0x932: 0x1308, 0x933: 0x1308, 0x934: 0x1308, 0x935: 0x1308,
999 0x936: 0x1308, 0x937: 0x1308, 0x938: 0x1308, 0x939: 0x0df1, 0x93a: 0x1308, 0x93b: 0x1308,
1000 0x93c: 0x1308, 0x93d: 0x0040, 0x93e: 0x0018, 0x93f: 0x0018,
1001 // Block 0x25, offset 0x940
1002 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x0008, 0x944: 0x0008, 0x945: 0x0008,
1003 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0008, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,
1004 0x94c: 0x0008, 0x94d: 0x0008, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,
1005 0x952: 0x0008, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0008,
1006 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0008, 0x95d: 0x0008,
1007 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,
1008 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0008,
1009 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0039, 0x96d: 0x0ed1, 0x96e: 0x0ee9, 0x96f: 0x0008,
1010 0x970: 0x0ef9, 0x971: 0x0f09, 0x972: 0x0f19, 0x973: 0x0f31, 0x974: 0x0249, 0x975: 0x0f41,
1011 0x976: 0x0259, 0x977: 0x0f51, 0x978: 0x0359, 0x979: 0x0f61, 0x97a: 0x0f71, 0x97b: 0x0008,
1012 0x97c: 0x00d9, 0x97d: 0x0f81, 0x97e: 0x0f99, 0x97f: 0x0269,
1013 // Block 0x26, offset 0x980
1014 0x980: 0x0fa9, 0x981: 0x0fb9, 0x982: 0x0279, 0x983: 0x0039, 0x984: 0x0fc9, 0x985: 0x0fe1,
1015 0x986: 0x059d, 0x987: 0x0ee9, 0x988: 0x0ef9, 0x989: 0x0f09, 0x98a: 0x0ff9, 0x98b: 0x1011,
1016 0x98c: 0x1029, 0x98d: 0x0f31, 0x98e: 0x0008, 0x98f: 0x0f51, 0x990: 0x0f61, 0x991: 0x1041,
1017 0x992: 0x00d9, 0x993: 0x1059, 0x994: 0x05b5, 0x995: 0x05b5, 0x996: 0x0f99, 0x997: 0x0fa9,
1018 0x998: 0x0fb9, 0x999: 0x059d, 0x99a: 0x1071, 0x99b: 0x1089, 0x99c: 0x05cd, 0x99d: 0x1099,
1019 0x99e: 0x10b1, 0x99f: 0x10c9, 0x9a0: 0x10e1, 0x9a1: 0x10f9, 0x9a2: 0x0f41, 0x9a3: 0x0269,
1020 0x9a4: 0x0fb9, 0x9a5: 0x1089, 0x9a6: 0x1099, 0x9a7: 0x10b1, 0x9a8: 0x1111, 0x9a9: 0x10e1,
1021 0x9aa: 0x10f9, 0x9ab: 0x0008, 0x9ac: 0x0008, 0x9ad: 0x0008, 0x9ae: 0x0008, 0x9af: 0x0008,
1022 0x9b0: 0x0008, 0x9b1: 0x0008, 0x9b2: 0x0008, 0x9b3: 0x0008, 0x9b4: 0x0008, 0x9b5: 0x0008,
1023 0x9b6: 0x0008, 0x9b7: 0x0008, 0x9b8: 0x1129, 0x9b9: 0x0008, 0x9ba: 0x0008, 0x9bb: 0x0008,
1024 0x9bc: 0x0008, 0x9bd: 0x0008, 0x9be: 0x0008, 0x9bf: 0x0008,
1025 // Block 0x27, offset 0x9c0
1026 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,
1027 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,
1028 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,
1029 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,
1030 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x1141, 0x9dc: 0x1159, 0x9dd: 0x1169,
1031 0x9de: 0x1181, 0x9df: 0x1029, 0x9e0: 0x1199, 0x9e1: 0x11a9, 0x9e2: 0x11c1, 0x9e3: 0x11d9,
1032 0x9e4: 0x11f1, 0x9e5: 0x1209, 0x9e6: 0x1221, 0x9e7: 0x05e5, 0x9e8: 0x1239, 0x9e9: 0x1251,
1033 0x9ea: 0xe17d, 0x9eb: 0x1269, 0x9ec: 0x1281, 0x9ed: 0x1299, 0x9ee: 0x12b1, 0x9ef: 0x12c9,
1034 0x9f0: 0x12e1, 0x9f1: 0x12f9, 0x9f2: 0x1311, 0x9f3: 0x1329, 0x9f4: 0x1341, 0x9f5: 0x1359,
1035 0x9f6: 0x1371, 0x9f7: 0x1389, 0x9f8: 0x05fd, 0x9f9: 0x13a1, 0x9fa: 0x13b9, 0x9fb: 0x13d1,
1036 0x9fc: 0x13e1, 0x9fd: 0x13f9, 0x9fe: 0x1411, 0x9ff: 0x1429,
1037 // Block 0x28, offset 0xa00
1038 0xa00: 0xe00d, 0xa01: 0x0008, 0xa02: 0xe00d, 0xa03: 0x0008, 0xa04: 0xe00d, 0xa05: 0x0008,
1039 0xa06: 0xe00d, 0xa07: 0x0008, 0xa08: 0xe00d, 0xa09: 0x0008, 0xa0a: 0xe00d, 0xa0b: 0x0008,
1040 0xa0c: 0xe00d, 0xa0d: 0x0008, 0xa0e: 0xe00d, 0xa0f: 0x0008, 0xa10: 0xe00d, 0xa11: 0x0008,
1041 0xa12: 0xe00d, 0xa13: 0x0008, 0xa14: 0xe00d, 0xa15: 0x0008, 0xa16: 0xe00d, 0xa17: 0x0008,
1042 0xa18: 0xe00d, 0xa19: 0x0008, 0xa1a: 0xe00d, 0xa1b: 0x0008, 0xa1c: 0xe00d, 0xa1d: 0x0008,
1043 0xa1e: 0xe00d, 0xa1f: 0x0008, 0xa20: 0xe00d, 0xa21: 0x0008, 0xa22: 0xe00d, 0xa23: 0x0008,
1044 0xa24: 0xe00d, 0xa25: 0x0008, 0xa26: 0xe00d, 0xa27: 0x0008, 0xa28: 0xe00d, 0xa29: 0x0008,
1045 0xa2a: 0xe00d, 0xa2b: 0x0008, 0xa2c: 0xe00d, 0xa2d: 0x0008, 0xa2e: 0xe00d, 0xa2f: 0x0008,
1046 0xa30: 0xe00d, 0xa31: 0x0008, 0xa32: 0xe00d, 0xa33: 0x0008, 0xa34: 0xe00d, 0xa35: 0x0008,
1047 0xa36: 0xe00d, 0xa37: 0x0008, 0xa38: 0xe00d, 0xa39: 0x0008, 0xa3a: 0xe00d, 0xa3b: 0x0008,
1048 0xa3c: 0xe00d, 0xa3d: 0x0008, 0xa3e: 0xe00d, 0xa3f: 0x0008,
1049 // Block 0x29, offset 0xa40
1050 0xa40: 0xe00d, 0xa41: 0x0008, 0xa42: 0xe00d, 0xa43: 0x0008, 0xa44: 0xe00d, 0xa45: 0x0008,
1051 0xa46: 0xe00d, 0xa47: 0x0008, 0xa48: 0xe00d, 0xa49: 0x0008, 0xa4a: 0xe00d, 0xa4b: 0x0008,
1052 0xa4c: 0xe00d, 0xa4d: 0x0008, 0xa4e: 0xe00d, 0xa4f: 0x0008, 0xa50: 0xe00d, 0xa51: 0x0008,
1053 0xa52: 0xe00d, 0xa53: 0x0008, 0xa54: 0xe00d, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,
1054 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0615, 0xa5b: 0x0635, 0xa5c: 0x0008, 0xa5d: 0x0008,
1055 0xa5e: 0x1441, 0xa5f: 0x0008, 0xa60: 0xe00d, 0xa61: 0x0008, 0xa62: 0xe00d, 0xa63: 0x0008,
1056 0xa64: 0xe00d, 0xa65: 0x0008, 0xa66: 0xe00d, 0xa67: 0x0008, 0xa68: 0xe00d, 0xa69: 0x0008,
1057 0xa6a: 0xe00d, 0xa6b: 0x0008, 0xa6c: 0xe00d, 0xa6d: 0x0008, 0xa6e: 0xe00d, 0xa6f: 0x0008,
1058 0xa70: 0xe00d, 0xa71: 0x0008, 0xa72: 0xe00d, 0xa73: 0x0008, 0xa74: 0xe00d, 0xa75: 0x0008,
1059 0xa76: 0xe00d, 0xa77: 0x0008, 0xa78: 0xe00d, 0xa79: 0x0008, 0xa7a: 0xe00d, 0xa7b: 0x0008,
1060 0xa7c: 0xe00d, 0xa7d: 0x0008, 0xa7e: 0xe00d, 0xa7f: 0x0008,
1061 // Block 0x2a, offset 0xa80
1062 0xa80: 0x0008, 0xa81: 0x0008, 0xa82: 0x0008, 0xa83: 0x0008, 0xa84: 0x0008, 0xa85: 0x0008,
1063 0xa86: 0x0040, 0xa87: 0x0040, 0xa88: 0xe045, 0xa89: 0xe045, 0xa8a: 0xe045, 0xa8b: 0xe045,
1064 0xa8c: 0xe045, 0xa8d: 0xe045, 0xa8e: 0x0040, 0xa8f: 0x0040, 0xa90: 0x0008, 0xa91: 0x0008,
1065 0xa92: 0x0008, 0xa93: 0x0008, 0xa94: 0x0008, 0xa95: 0x0008, 0xa96: 0x0008, 0xa97: 0x0008,
1066 0xa98: 0x0040, 0xa99: 0xe045, 0xa9a: 0x0040, 0xa9b: 0xe045, 0xa9c: 0x0040, 0xa9d: 0xe045,
1067 0xa9e: 0x0040, 0xa9f: 0xe045, 0xaa0: 0x0008, 0xaa1: 0x0008, 0xaa2: 0x0008, 0xaa3: 0x0008,
1068 0xaa4: 0x0008, 0xaa5: 0x0008, 0xaa6: 0x0008, 0xaa7: 0x0008, 0xaa8: 0xe045, 0xaa9: 0xe045,
1069 0xaaa: 0xe045, 0xaab: 0xe045, 0xaac: 0xe045, 0xaad: 0xe045, 0xaae: 0xe045, 0xaaf: 0xe045,
1070 0xab0: 0x0008, 0xab1: 0x1459, 0xab2: 0x0008, 0xab3: 0x1471, 0xab4: 0x0008, 0xab5: 0x1489,
1071 0xab6: 0x0008, 0xab7: 0x14a1, 0xab8: 0x0008, 0xab9: 0x14b9, 0xaba: 0x0008, 0xabb: 0x14d1,
1072 0xabc: 0x0008, 0xabd: 0x14e9, 0xabe: 0x0040, 0xabf: 0x0040,
1073 // Block 0x2b, offset 0xac0
1074 0xac0: 0x1501, 0xac1: 0x1531, 0xac2: 0x1561, 0xac3: 0x1591, 0xac4: 0x15c1, 0xac5: 0x15f1,
1075 0xac6: 0x1621, 0xac7: 0x1651, 0xac8: 0x1501, 0xac9: 0x1531, 0xaca: 0x1561, 0xacb: 0x1591,
1076 0xacc: 0x15c1, 0xacd: 0x15f1, 0xace: 0x1621, 0xacf: 0x1651, 0xad0: 0x1681, 0xad1: 0x16b1,
1077 0xad2: 0x16e1, 0xad3: 0x1711, 0xad4: 0x1741, 0xad5: 0x1771, 0xad6: 0x17a1, 0xad7: 0x17d1,
1078 0xad8: 0x1681, 0xad9: 0x16b1, 0xada: 0x16e1, 0xadb: 0x1711, 0xadc: 0x1741, 0xadd: 0x1771,
1079 0xade: 0x17a1, 0xadf: 0x17d1, 0xae0: 0x1801, 0xae1: 0x1831, 0xae2: 0x1861, 0xae3: 0x1891,
1080 0xae4: 0x18c1, 0xae5: 0x18f1, 0xae6: 0x1921, 0xae7: 0x1951, 0xae8: 0x1801, 0xae9: 0x1831,
1081 0xaea: 0x1861, 0xaeb: 0x1891, 0xaec: 0x18c1, 0xaed: 0x18f1, 0xaee: 0x1921, 0xaef: 0x1951,
1082 0xaf0: 0x0008, 0xaf1: 0x0008, 0xaf2: 0x1981, 0xaf3: 0x19b1, 0xaf4: 0x19d9, 0xaf5: 0x0040,
1083 0xaf6: 0x0008, 0xaf7: 0x1a01, 0xaf8: 0xe045, 0xaf9: 0xe045, 0xafa: 0x064d, 0xafb: 0x1459,
1084 0xafc: 0x19b1, 0xafd: 0x0666, 0xafe: 0x1a31, 0xaff: 0x0686,
1085 // Block 0x2c, offset 0xb00
1086 0xb00: 0x06a6, 0xb01: 0x1a4a, 0xb02: 0x1a79, 0xb03: 0x1aa9, 0xb04: 0x1ad1, 0xb05: 0x0040,
1087 0xb06: 0x0008, 0xb07: 0x1af9, 0xb08: 0x06c5, 0xb09: 0x1471, 0xb0a: 0x06dd, 0xb0b: 0x1489,
1088 0xb0c: 0x1aa9, 0xb0d: 0x1b2a, 0xb0e: 0x1b5a, 0xb0f: 0x1b8a, 0xb10: 0x0008, 0xb11: 0x0008,
1089 0xb12: 0x0008, 0xb13: 0x1bb9, 0xb14: 0x0040, 0xb15: 0x0040, 0xb16: 0x0008, 0xb17: 0x0008,
1090 0xb18: 0xe045, 0xb19: 0xe045, 0xb1a: 0x06f5, 0xb1b: 0x14a1, 0xb1c: 0x0040, 0xb1d: 0x1bd2,
1091 0xb1e: 0x1c02, 0xb1f: 0x1c32, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x1c61,
1092 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,
1093 0xb2a: 0x070d, 0xb2b: 0x14d1, 0xb2c: 0xe04d, 0xb2d: 0x1c7a, 0xb2e: 0x03d2, 0xb2f: 0x1caa,
1094 0xb30: 0x0040, 0xb31: 0x0040, 0xb32: 0x1cb9, 0xb33: 0x1ce9, 0xb34: 0x1d11, 0xb35: 0x0040,
1095 0xb36: 0x0008, 0xb37: 0x1d39, 0xb38: 0x0725, 0xb39: 0x14b9, 0xb3a: 0x0515, 0xb3b: 0x14e9,
1096 0xb3c: 0x1ce9, 0xb3d: 0x073e, 0xb3e: 0x075e, 0xb3f: 0x0040,
1097 // Block 0x2d, offset 0xb40
1098 0xb40: 0x000a, 0xb41: 0x000a, 0xb42: 0x000a, 0xb43: 0x000a, 0xb44: 0x000a, 0xb45: 0x000a,
1099 0xb46: 0x000a, 0xb47: 0x000a, 0xb48: 0x000a, 0xb49: 0x000a, 0xb4a: 0x000a, 0xb4b: 0x03c0,
1100 0xb4c: 0x0003, 0xb4d: 0x0003, 0xb4e: 0x0340, 0xb4f: 0x0340, 0xb50: 0x0018, 0xb51: 0xe00d,
1101 0xb52: 0x0018, 0xb53: 0x0018, 0xb54: 0x0018, 0xb55: 0x0018, 0xb56: 0x0018, 0xb57: 0x077e,
1102 0xb58: 0x0018, 0xb59: 0x0018, 0xb5a: 0x0018, 0xb5b: 0x0018, 0xb5c: 0x0018, 0xb5d: 0x0018,
1103 0xb5e: 0x0018, 0xb5f: 0x0018, 0xb60: 0x0018, 0xb61: 0x0018, 0xb62: 0x0018, 0xb63: 0x0018,
1104 0xb64: 0x0040, 0xb65: 0x0040, 0xb66: 0x0040, 0xb67: 0x0018, 0xb68: 0x0040, 0xb69: 0x0040,
1105 0xb6a: 0x0340, 0xb6b: 0x0340, 0xb6c: 0x0340, 0xb6d: 0x0340, 0xb6e: 0x0340, 0xb6f: 0x000a,
1106 0xb70: 0x0018, 0xb71: 0x0018, 0xb72: 0x0018, 0xb73: 0x1d69, 0xb74: 0x1da1, 0xb75: 0x0018,
1107 0xb76: 0x1df1, 0xb77: 0x1e29, 0xb78: 0x0018, 0xb79: 0x0018, 0xb7a: 0x0018, 0xb7b: 0x0018,
1108 0xb7c: 0x1e7a, 0xb7d: 0x0018, 0xb7e: 0x079e, 0xb7f: 0x0018,
1109 // Block 0x2e, offset 0xb80
1110 0xb80: 0x0018, 0xb81: 0x0018, 0xb82: 0x0018, 0xb83: 0x0018, 0xb84: 0x0018, 0xb85: 0x0018,
1111 0xb86: 0x0018, 0xb87: 0x1e92, 0xb88: 0x1eaa, 0xb89: 0x1ec2, 0xb8a: 0x0018, 0xb8b: 0x0018,
1112 0xb8c: 0x0018, 0xb8d: 0x0018, 0xb8e: 0x0018, 0xb8f: 0x0018, 0xb90: 0x0018, 0xb91: 0x0018,
1113 0xb92: 0x0018, 0xb93: 0x0018, 0xb94: 0x0018, 0xb95: 0x0018, 0xb96: 0x0018, 0xb97: 0x1ed9,
1114 0xb98: 0x0018, 0xb99: 0x0018, 0xb9a: 0x0018, 0xb9b: 0x0018, 0xb9c: 0x0018, 0xb9d: 0x0018,
1115 0xb9e: 0x0018, 0xb9f: 0x000a, 0xba0: 0x03c0, 0xba1: 0x0340, 0xba2: 0x0340, 0xba3: 0x0340,
1116 0xba4: 0x03c0, 0xba5: 0x0040, 0xba6: 0x0040, 0xba7: 0x0040, 0xba8: 0x0040, 0xba9: 0x0040,
1117 0xbaa: 0x0340, 0xbab: 0x0340, 0xbac: 0x0340, 0xbad: 0x0340, 0xbae: 0x0340, 0xbaf: 0x0340,
1118 0xbb0: 0x1f41, 0xbb1: 0x0f41, 0xbb2: 0x0040, 0xbb3: 0x0040, 0xbb4: 0x1f51, 0xbb5: 0x1f61,
1119 0xbb6: 0x1f71, 0xbb7: 0x1f81, 0xbb8: 0x1f91, 0xbb9: 0x1fa1, 0xbba: 0x1fb2, 0xbbb: 0x07bd,
1120 0xbbc: 0x1fc2, 0xbbd: 0x1fd2, 0xbbe: 0x1fe2, 0xbbf: 0x0f71,
1121 // Block 0x2f, offset 0xbc0
1122 0xbc0: 0x1f41, 0xbc1: 0x00c9, 0xbc2: 0x0069, 0xbc3: 0x0079, 0xbc4: 0x1f51, 0xbc5: 0x1f61,
1123 0xbc6: 0x1f71, 0xbc7: 0x1f81, 0xbc8: 0x1f91, 0xbc9: 0x1fa1, 0xbca: 0x1fb2, 0xbcb: 0x07d5,
1124 0xbcc: 0x1fc2, 0xbcd: 0x1fd2, 0xbce: 0x1fe2, 0xbcf: 0x0040, 0xbd0: 0x0039, 0xbd1: 0x0f09,
1125 0xbd2: 0x00d9, 0xbd3: 0x0369, 0xbd4: 0x0ff9, 0xbd5: 0x0249, 0xbd6: 0x0f51, 0xbd7: 0x0359,
1126 0xbd8: 0x0f61, 0xbd9: 0x0f71, 0xbda: 0x0f99, 0xbdb: 0x01d9, 0xbdc: 0x0fa9, 0xbdd: 0x0040,
1127 0xbde: 0x0040, 0xbdf: 0x0040, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,
1128 0xbe4: 0x0018, 0xbe5: 0x0018, 0xbe6: 0x0018, 0xbe7: 0x0018, 0xbe8: 0x1ff1, 0xbe9: 0x0018,
1129 0xbea: 0x0018, 0xbeb: 0x0018, 0xbec: 0x0018, 0xbed: 0x0018, 0xbee: 0x0018, 0xbef: 0x0018,
1130 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x0018, 0xbf4: 0x0018, 0xbf5: 0x0018,
1131 0xbf6: 0x0018, 0xbf7: 0x0018, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,
1132 0xbfc: 0x0018, 0xbfd: 0x0018, 0xbfe: 0x0018, 0xbff: 0x0040,
1133 // Block 0x30, offset 0xc00
1134 0xc00: 0x07ee, 0xc01: 0x080e, 0xc02: 0x1159, 0xc03: 0x082d, 0xc04: 0x0018, 0xc05: 0x084e,
1135 0xc06: 0x086e, 0xc07: 0x1011, 0xc08: 0x0018, 0xc09: 0x088d, 0xc0a: 0x0f31, 0xc0b: 0x0249,
1136 0xc0c: 0x0249, 0xc0d: 0x0249, 0xc0e: 0x0249, 0xc0f: 0x2009, 0xc10: 0x0f41, 0xc11: 0x0f41,
1137 0xc12: 0x0359, 0xc13: 0x0359, 0xc14: 0x0018, 0xc15: 0x0f71, 0xc16: 0x2021, 0xc17: 0x0018,
1138 0xc18: 0x0018, 0xc19: 0x0f99, 0xc1a: 0x2039, 0xc1b: 0x0269, 0xc1c: 0x0269, 0xc1d: 0x0269,
1139 0xc1e: 0x0018, 0xc1f: 0x0018, 0xc20: 0x2049, 0xc21: 0x08ad, 0xc22: 0x2061, 0xc23: 0x0018,
1140 0xc24: 0x13d1, 0xc25: 0x0018, 0xc26: 0x2079, 0xc27: 0x0018, 0xc28: 0x13d1, 0xc29: 0x0018,
1141 0xc2a: 0x0f51, 0xc2b: 0x2091, 0xc2c: 0x0ee9, 0xc2d: 0x1159, 0xc2e: 0x0018, 0xc2f: 0x0f09,
1142 0xc30: 0x0f09, 0xc31: 0x1199, 0xc32: 0x0040, 0xc33: 0x0f61, 0xc34: 0x00d9, 0xc35: 0x20a9,
1143 0xc36: 0x20c1, 0xc37: 0x20d9, 0xc38: 0x20f1, 0xc39: 0x0f41, 0xc3a: 0x0018, 0xc3b: 0x08cd,
1144 0xc3c: 0x2109, 0xc3d: 0x10b1, 0xc3e: 0x10b1, 0xc3f: 0x2109,
1145 // Block 0x31, offset 0xc40
1146 0xc40: 0x08ed, 0xc41: 0x0018, 0xc42: 0x0018, 0xc43: 0x0018, 0xc44: 0x0018, 0xc45: 0x0ef9,
1147 0xc46: 0x0ef9, 0xc47: 0x0f09, 0xc48: 0x0f41, 0xc49: 0x0259, 0xc4a: 0x0018, 0xc4b: 0x0018,
1148 0xc4c: 0x0018, 0xc4d: 0x0018, 0xc4e: 0x0008, 0xc4f: 0x0018, 0xc50: 0x2121, 0xc51: 0x2151,
1149 0xc52: 0x2181, 0xc53: 0x21b9, 0xc54: 0x21e9, 0xc55: 0x2219, 0xc56: 0x2249, 0xc57: 0x2279,
1150 0xc58: 0x22a9, 0xc59: 0x22d9, 0xc5a: 0x2309, 0xc5b: 0x2339, 0xc5c: 0x2369, 0xc5d: 0x2399,
1151 0xc5e: 0x23c9, 0xc5f: 0x23f9, 0xc60: 0x0f41, 0xc61: 0x2421, 0xc62: 0x0905, 0xc63: 0x2439,
1152 0xc64: 0x1089, 0xc65: 0x2451, 0xc66: 0x0925, 0xc67: 0x2469, 0xc68: 0x2491, 0xc69: 0x0369,
1153 0xc6a: 0x24a9, 0xc6b: 0x0945, 0xc6c: 0x0359, 0xc6d: 0x1159, 0xc6e: 0x0ef9, 0xc6f: 0x0f61,
1154 0xc70: 0x0f41, 0xc71: 0x2421, 0xc72: 0x0965, 0xc73: 0x2439, 0xc74: 0x1089, 0xc75: 0x2451,
1155 0xc76: 0x0985, 0xc77: 0x2469, 0xc78: 0x2491, 0xc79: 0x0369, 0xc7a: 0x24a9, 0xc7b: 0x09a5,
1156 0xc7c: 0x0359, 0xc7d: 0x1159, 0xc7e: 0x0ef9, 0xc7f: 0x0f61,
1157 // Block 0x32, offset 0xc80
1158 0xc80: 0x0018, 0xc81: 0x0018, 0xc82: 0x0018, 0xc83: 0x0018, 0xc84: 0x0018, 0xc85: 0x0018,
1159 0xc86: 0x0018, 0xc87: 0x0018, 0xc88: 0x0018, 0xc89: 0x0018, 0xc8a: 0x0018, 0xc8b: 0x0040,
1160 0xc8c: 0x0040, 0xc8d: 0x0040, 0xc8e: 0x0040, 0xc8f: 0x0040, 0xc90: 0x0040, 0xc91: 0x0040,
1161 0xc92: 0x0040, 0xc93: 0x0040, 0xc94: 0x0040, 0xc95: 0x0040, 0xc96: 0x0040, 0xc97: 0x0040,
1162 0xc98: 0x0040, 0xc99: 0x0040, 0xc9a: 0x0040, 0xc9b: 0x0040, 0xc9c: 0x0040, 0xc9d: 0x0040,
1163 0xc9e: 0x0040, 0xc9f: 0x0040, 0xca0: 0x00c9, 0xca1: 0x0069, 0xca2: 0x0079, 0xca3: 0x1f51,
1164 0xca4: 0x1f61, 0xca5: 0x1f71, 0xca6: 0x1f81, 0xca7: 0x1f91, 0xca8: 0x1fa1, 0xca9: 0x2601,
1165 0xcaa: 0x2619, 0xcab: 0x2631, 0xcac: 0x2649, 0xcad: 0x2661, 0xcae: 0x2679, 0xcaf: 0x2691,
1166 0xcb0: 0x26a9, 0xcb1: 0x26c1, 0xcb2: 0x26d9, 0xcb3: 0x26f1, 0xcb4: 0x0a06, 0xcb5: 0x0a26,
1167 0xcb6: 0x0a46, 0xcb7: 0x0a66, 0xcb8: 0x0a86, 0xcb9: 0x0aa6, 0xcba: 0x0ac6, 0xcbb: 0x0ae6,
1168 0xcbc: 0x0b06, 0xcbd: 0x270a, 0xcbe: 0x2732, 0xcbf: 0x275a,
1169 // Block 0x33, offset 0xcc0
1170 0xcc0: 0x2782, 0xcc1: 0x27aa, 0xcc2: 0x27d2, 0xcc3: 0x27fa, 0xcc4: 0x2822, 0xcc5: 0x284a,
1171 0xcc6: 0x2872, 0xcc7: 0x289a, 0xcc8: 0x0040, 0xcc9: 0x0040, 0xcca: 0x0040, 0xccb: 0x0040,
1172 0xccc: 0x0040, 0xccd: 0x0040, 0xcce: 0x0040, 0xccf: 0x0040, 0xcd0: 0x0040, 0xcd1: 0x0040,
1173 0xcd2: 0x0040, 0xcd3: 0x0040, 0xcd4: 0x0040, 0xcd5: 0x0040, 0xcd6: 0x0040, 0xcd7: 0x0040,
1174 0xcd8: 0x0040, 0xcd9: 0x0040, 0xcda: 0x0040, 0xcdb: 0x0040, 0xcdc: 0x0b26, 0xcdd: 0x0b46,
1175 0xcde: 0x0b66, 0xcdf: 0x0b86, 0xce0: 0x0ba6, 0xce1: 0x0bc6, 0xce2: 0x0be6, 0xce3: 0x0c06,
1176 0xce4: 0x0c26, 0xce5: 0x0c46, 0xce6: 0x0c66, 0xce7: 0x0c86, 0xce8: 0x0ca6, 0xce9: 0x0cc6,
1177 0xcea: 0x0ce6, 0xceb: 0x0d06, 0xcec: 0x0d26, 0xced: 0x0d46, 0xcee: 0x0d66, 0xcef: 0x0d86,
1178 0xcf0: 0x0da6, 0xcf1: 0x0dc6, 0xcf2: 0x0de6, 0xcf3: 0x0e06, 0xcf4: 0x0e26, 0xcf5: 0x0e46,
1179 0xcf6: 0x0039, 0xcf7: 0x0ee9, 0xcf8: 0x1159, 0xcf9: 0x0ef9, 0xcfa: 0x0f09, 0xcfb: 0x1199,
1180 0xcfc: 0x0f31, 0xcfd: 0x0249, 0xcfe: 0x0f41, 0xcff: 0x0259,
1181 // Block 0x34, offset 0xd00
1182 0xd00: 0x0f51, 0xd01: 0x0359, 0xd02: 0x0f61, 0xd03: 0x0f71, 0xd04: 0x00d9, 0xd05: 0x0f99,
1183 0xd06: 0x2039, 0xd07: 0x0269, 0xd08: 0x01d9, 0xd09: 0x0fa9, 0xd0a: 0x0fb9, 0xd0b: 0x1089,
1184 0xd0c: 0x0279, 0xd0d: 0x0369, 0xd0e: 0x0289, 0xd0f: 0x13d1, 0xd10: 0x0039, 0xd11: 0x0ee9,
1185 0xd12: 0x1159, 0xd13: 0x0ef9, 0xd14: 0x0f09, 0xd15: 0x1199, 0xd16: 0x0f31, 0xd17: 0x0249,
1186 0xd18: 0x0f41, 0xd19: 0x0259, 0xd1a: 0x0f51, 0xd1b: 0x0359, 0xd1c: 0x0f61, 0xd1d: 0x0f71,
1187 0xd1e: 0x00d9, 0xd1f: 0x0f99, 0xd20: 0x2039, 0xd21: 0x0269, 0xd22: 0x01d9, 0xd23: 0x0fa9,
1188 0xd24: 0x0fb9, 0xd25: 0x1089, 0xd26: 0x0279, 0xd27: 0x0369, 0xd28: 0x0289, 0xd29: 0x13d1,
1189 0xd2a: 0x1f41, 0xd2b: 0x0018, 0xd2c: 0x0018, 0xd2d: 0x0018, 0xd2e: 0x0018, 0xd2f: 0x0018,
1190 0xd30: 0x0018, 0xd31: 0x0018, 0xd32: 0x0018, 0xd33: 0x0018, 0xd34: 0x0018, 0xd35: 0x0018,
1191 0xd36: 0x0018, 0xd37: 0x0018, 0xd38: 0x0018, 0xd39: 0x0018, 0xd3a: 0x0018, 0xd3b: 0x0018,
1192 0xd3c: 0x0018, 0xd3d: 0x0018, 0xd3e: 0x0018, 0xd3f: 0x0018,
1193 // Block 0x35, offset 0xd40
1194 0xd40: 0x0008, 0xd41: 0x0008, 0xd42: 0x0008, 0xd43: 0x0008, 0xd44: 0x0008, 0xd45: 0x0008,
1195 0xd46: 0x0008, 0xd47: 0x0008, 0xd48: 0x0008, 0xd49: 0x0008, 0xd4a: 0x0008, 0xd4b: 0x0008,
1196 0xd4c: 0x0008, 0xd4d: 0x0008, 0xd4e: 0x0008, 0xd4f: 0x0008, 0xd50: 0x0008, 0xd51: 0x0008,
1197 0xd52: 0x0008, 0xd53: 0x0008, 0xd54: 0x0008, 0xd55: 0x0008, 0xd56: 0x0008, 0xd57: 0x0008,
1198 0xd58: 0x0008, 0xd59: 0x0008, 0xd5a: 0x0008, 0xd5b: 0x0008, 0xd5c: 0x0008, 0xd5d: 0x0008,
1199 0xd5e: 0x0008, 0xd5f: 0x0040, 0xd60: 0xe00d, 0xd61: 0x0008, 0xd62: 0x2971, 0xd63: 0x0ebd,
1200 0xd64: 0x2989, 0xd65: 0x0008, 0xd66: 0x0008, 0xd67: 0xe07d, 0xd68: 0x0008, 0xd69: 0xe01d,
1201 0xd6a: 0x0008, 0xd6b: 0xe03d, 0xd6c: 0x0008, 0xd6d: 0x0fe1, 0xd6e: 0x1281, 0xd6f: 0x0fc9,
1202 0xd70: 0x1141, 0xd71: 0x0008, 0xd72: 0xe00d, 0xd73: 0x0008, 0xd74: 0x0008, 0xd75: 0xe01d,
1203 0xd76: 0x0008, 0xd77: 0x0008, 0xd78: 0x0008, 0xd79: 0x0008, 0xd7a: 0x0008, 0xd7b: 0x0008,
1204 0xd7c: 0x0259, 0xd7d: 0x1089, 0xd7e: 0x29a1, 0xd7f: 0x29b9,
1205 // Block 0x36, offset 0xd80
1206 0xd80: 0xe00d, 0xd81: 0x0008, 0xd82: 0xe00d, 0xd83: 0x0008, 0xd84: 0xe00d, 0xd85: 0x0008,
1207 0xd86: 0xe00d, 0xd87: 0x0008, 0xd88: 0xe00d, 0xd89: 0x0008, 0xd8a: 0xe00d, 0xd8b: 0x0008,
1208 0xd8c: 0xe00d, 0xd8d: 0x0008, 0xd8e: 0xe00d, 0xd8f: 0x0008, 0xd90: 0xe00d, 0xd91: 0x0008,
1209 0xd92: 0xe00d, 0xd93: 0x0008, 0xd94: 0xe00d, 0xd95: 0x0008, 0xd96: 0xe00d, 0xd97: 0x0008,
1210 0xd98: 0xe00d, 0xd99: 0x0008, 0xd9a: 0xe00d, 0xd9b: 0x0008, 0xd9c: 0xe00d, 0xd9d: 0x0008,
1211 0xd9e: 0xe00d, 0xd9f: 0x0008, 0xda0: 0xe00d, 0xda1: 0x0008, 0xda2: 0xe00d, 0xda3: 0x0008,
1212 0xda4: 0x0008, 0xda5: 0x0018, 0xda6: 0x0018, 0xda7: 0x0018, 0xda8: 0x0018, 0xda9: 0x0018,
1213 0xdaa: 0x0018, 0xdab: 0xe03d, 0xdac: 0x0008, 0xdad: 0xe01d, 0xdae: 0x0008, 0xdaf: 0x1308,
1214 0xdb0: 0x1308, 0xdb1: 0x1308, 0xdb2: 0xe00d, 0xdb3: 0x0008, 0xdb4: 0x0040, 0xdb5: 0x0040,
1215 0xdb6: 0x0040, 0xdb7: 0x0040, 0xdb8: 0x0040, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,
1216 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,
1217 // Block 0x37, offset 0xdc0
1218 0xdc0: 0x26fd, 0xdc1: 0x271d, 0xdc2: 0x273d, 0xdc3: 0x275d, 0xdc4: 0x277d, 0xdc5: 0x279d,
1219 0xdc6: 0x27bd, 0xdc7: 0x27dd, 0xdc8: 0x27fd, 0xdc9: 0x281d, 0xdca: 0x283d, 0xdcb: 0x285d,
1220 0xdcc: 0x287d, 0xdcd: 0x289d, 0xdce: 0x28bd, 0xdcf: 0x28dd, 0xdd0: 0x28fd, 0xdd1: 0x291d,
1221 0xdd2: 0x293d, 0xdd3: 0x295d, 0xdd4: 0x297d, 0xdd5: 0x299d, 0xdd6: 0x0040, 0xdd7: 0x0040,
1222 0xdd8: 0x0040, 0xdd9: 0x0040, 0xdda: 0x0040, 0xddb: 0x0040, 0xddc: 0x0040, 0xddd: 0x0040,
1223 0xdde: 0x0040, 0xddf: 0x0040, 0xde0: 0x0040, 0xde1: 0x0040, 0xde2: 0x0040, 0xde3: 0x0040,
1224 0xde4: 0x0040, 0xde5: 0x0040, 0xde6: 0x0040, 0xde7: 0x0040, 0xde8: 0x0040, 0xde9: 0x0040,
1225 0xdea: 0x0040, 0xdeb: 0x0040, 0xdec: 0x0040, 0xded: 0x0040, 0xdee: 0x0040, 0xdef: 0x0040,
1226 0xdf0: 0x0040, 0xdf1: 0x0040, 0xdf2: 0x0040, 0xdf3: 0x0040, 0xdf4: 0x0040, 0xdf5: 0x0040,
1227 0xdf6: 0x0040, 0xdf7: 0x0040, 0xdf8: 0x0040, 0xdf9: 0x0040, 0xdfa: 0x0040, 0xdfb: 0x0040,
1228 0xdfc: 0x0040, 0xdfd: 0x0040, 0xdfe: 0x0040, 0xdff: 0x0040,
1229 // Block 0x38, offset 0xe00
1230 0xe00: 0x000a, 0xe01: 0x0018, 0xe02: 0x29d1, 0xe03: 0x0018, 0xe04: 0x0018, 0xe05: 0x0008,
1231 0xe06: 0x0008, 0xe07: 0x0008, 0xe08: 0x0018, 0xe09: 0x0018, 0xe0a: 0x0018, 0xe0b: 0x0018,
1232 0xe0c: 0x0018, 0xe0d: 0x0018, 0xe0e: 0x0018, 0xe0f: 0x0018, 0xe10: 0x0018, 0xe11: 0x0018,
1233 0xe12: 0x0018, 0xe13: 0x0018, 0xe14: 0x0018, 0xe15: 0x0018, 0xe16: 0x0018, 0xe17: 0x0018,
1234 0xe18: 0x0018, 0xe19: 0x0018, 0xe1a: 0x0018, 0xe1b: 0x0018, 0xe1c: 0x0018, 0xe1d: 0x0018,
1235 0xe1e: 0x0018, 0xe1f: 0x0018, 0xe20: 0x0018, 0xe21: 0x0018, 0xe22: 0x0018, 0xe23: 0x0018,
1236 0xe24: 0x0018, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,
1237 0xe2a: 0x1308, 0xe2b: 0x1308, 0xe2c: 0x1308, 0xe2d: 0x1308, 0xe2e: 0x1018, 0xe2f: 0x1018,
1238 0xe30: 0x0018, 0xe31: 0x0018, 0xe32: 0x0018, 0xe33: 0x0018, 0xe34: 0x0018, 0xe35: 0x0018,
1239 0xe36: 0xe125, 0xe37: 0x0018, 0xe38: 0x29bd, 0xe39: 0x29dd, 0xe3a: 0x29fd, 0xe3b: 0x0018,
1240 0xe3c: 0x0008, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,
1241 // Block 0x39, offset 0xe40
1242 0xe40: 0x2b3d, 0xe41: 0x2b5d, 0xe42: 0x2b7d, 0xe43: 0x2b9d, 0xe44: 0x2bbd, 0xe45: 0x2bdd,
1243 0xe46: 0x2bdd, 0xe47: 0x2bdd, 0xe48: 0x2bfd, 0xe49: 0x2bfd, 0xe4a: 0x2bfd, 0xe4b: 0x2bfd,
1244 0xe4c: 0x2c1d, 0xe4d: 0x2c1d, 0xe4e: 0x2c1d, 0xe4f: 0x2c3d, 0xe50: 0x2c5d, 0xe51: 0x2c5d,
1245 0xe52: 0x2a7d, 0xe53: 0x2a7d, 0xe54: 0x2c5d, 0xe55: 0x2c5d, 0xe56: 0x2c7d, 0xe57: 0x2c7d,
1246 0xe58: 0x2c5d, 0xe59: 0x2c5d, 0xe5a: 0x2a7d, 0xe5b: 0x2a7d, 0xe5c: 0x2c5d, 0xe5d: 0x2c5d,
1247 0xe5e: 0x2c3d, 0xe5f: 0x2c3d, 0xe60: 0x2c9d, 0xe61: 0x2c9d, 0xe62: 0x2cbd, 0xe63: 0x2cbd,
1248 0xe64: 0x0040, 0xe65: 0x2cdd, 0xe66: 0x2cfd, 0xe67: 0x2d1d, 0xe68: 0x2d1d, 0xe69: 0x2d3d,
1249 0xe6a: 0x2d5d, 0xe6b: 0x2d7d, 0xe6c: 0x2d9d, 0xe6d: 0x2dbd, 0xe6e: 0x2ddd, 0xe6f: 0x2dfd,
1250 0xe70: 0x2e1d, 0xe71: 0x2e3d, 0xe72: 0x2e3d, 0xe73: 0x2e5d, 0xe74: 0x2e7d, 0xe75: 0x2e7d,
1251 0xe76: 0x2e9d, 0xe77: 0x2ebd, 0xe78: 0x2e5d, 0xe79: 0x2edd, 0xe7a: 0x2efd, 0xe7b: 0x2edd,
1252 0xe7c: 0x2e5d, 0xe7d: 0x2f1d, 0xe7e: 0x2f3d, 0xe7f: 0x2f5d,
1253 // Block 0x3a, offset 0xe80
1254 0xe80: 0x2f7d, 0xe81: 0x2f9d, 0xe82: 0x2cfd, 0xe83: 0x2cdd, 0xe84: 0x2fbd, 0xe85: 0x2fdd,
1255 0xe86: 0x2ffd, 0xe87: 0x301d, 0xe88: 0x303d, 0xe89: 0x305d, 0xe8a: 0x307d, 0xe8b: 0x309d,
1256 0xe8c: 0x30bd, 0xe8d: 0x30dd, 0xe8e: 0x30fd, 0xe8f: 0x0040, 0xe90: 0x0018, 0xe91: 0x0018,
1257 0xe92: 0x311d, 0xe93: 0x313d, 0xe94: 0x315d, 0xe95: 0x317d, 0xe96: 0x319d, 0xe97: 0x31bd,
1258 0xe98: 0x31dd, 0xe99: 0x31fd, 0xe9a: 0x321d, 0xe9b: 0x323d, 0xe9c: 0x315d, 0xe9d: 0x325d,
1259 0xe9e: 0x327d, 0xe9f: 0x329d, 0xea0: 0x0008, 0xea1: 0x0008, 0xea2: 0x0008, 0xea3: 0x0008,
1260 0xea4: 0x0008, 0xea5: 0x0008, 0xea6: 0x0008, 0xea7: 0x0008, 0xea8: 0x0008, 0xea9: 0x0008,
1261 0xeaa: 0x0008, 0xeab: 0x0008, 0xeac: 0x0008, 0xead: 0x0008, 0xeae: 0x0008, 0xeaf: 0x0008,
1262 0xeb0: 0x0008, 0xeb1: 0x0008, 0xeb2: 0x0008, 0xeb3: 0x0008, 0xeb4: 0x0008, 0xeb5: 0x0008,
1263 0xeb6: 0x0008, 0xeb7: 0x0008, 0xeb8: 0x0008, 0xeb9: 0x0008, 0xeba: 0x0008, 0xebb: 0x0040,
1264 0xebc: 0x0040, 0xebd: 0x0040, 0xebe: 0x0040, 0xebf: 0x0040,
1265 // Block 0x3b, offset 0xec0
1266 0xec0: 0x36a2, 0xec1: 0x36d2, 0xec2: 0x3702, 0xec3: 0x3732, 0xec4: 0x32bd, 0xec5: 0x32dd,
1267 0xec6: 0x32fd, 0xec7: 0x331d, 0xec8: 0x0018, 0xec9: 0x0018, 0xeca: 0x0018, 0xecb: 0x0018,
1268 0xecc: 0x0018, 0xecd: 0x0018, 0xece: 0x0018, 0xecf: 0x0018, 0xed0: 0x333d, 0xed1: 0x3761,
1269 0xed2: 0x3779, 0xed3: 0x3791, 0xed4: 0x37a9, 0xed5: 0x37c1, 0xed6: 0x37d9, 0xed7: 0x37f1,
1270 0xed8: 0x3809, 0xed9: 0x3821, 0xeda: 0x3839, 0xedb: 0x3851, 0xedc: 0x3869, 0xedd: 0x3881,
1271 0xede: 0x3899, 0xedf: 0x38b1, 0xee0: 0x335d, 0xee1: 0x337d, 0xee2: 0x339d, 0xee3: 0x33bd,
1272 0xee4: 0x33dd, 0xee5: 0x33dd, 0xee6: 0x33fd, 0xee7: 0x341d, 0xee8: 0x343d, 0xee9: 0x345d,
1273 0xeea: 0x347d, 0xeeb: 0x349d, 0xeec: 0x34bd, 0xeed: 0x34dd, 0xeee: 0x34fd, 0xeef: 0x351d,
1274 0xef0: 0x353d, 0xef1: 0x355d, 0xef2: 0x357d, 0xef3: 0x359d, 0xef4: 0x35bd, 0xef5: 0x35dd,
1275 0xef6: 0x35fd, 0xef7: 0x361d, 0xef8: 0x363d, 0xef9: 0x365d, 0xefa: 0x367d, 0xefb: 0x369d,
1276 0xefc: 0x38c9, 0xefd: 0x3901, 0xefe: 0x36bd, 0xeff: 0x0018,
1277 // Block 0x3c, offset 0xf00
1278 0xf00: 0x36dd, 0xf01: 0x36fd, 0xf02: 0x371d, 0xf03: 0x373d, 0xf04: 0x375d, 0xf05: 0x377d,
1279 0xf06: 0x379d, 0xf07: 0x37bd, 0xf08: 0x37dd, 0xf09: 0x37fd, 0xf0a: 0x381d, 0xf0b: 0x383d,
1280 0xf0c: 0x385d, 0xf0d: 0x387d, 0xf0e: 0x389d, 0xf0f: 0x38bd, 0xf10: 0x38dd, 0xf11: 0x38fd,
1281 0xf12: 0x391d, 0xf13: 0x393d, 0xf14: 0x395d, 0xf15: 0x397d, 0xf16: 0x399d, 0xf17: 0x39bd,
1282 0xf18: 0x39dd, 0xf19: 0x39fd, 0xf1a: 0x3a1d, 0xf1b: 0x3a3d, 0xf1c: 0x3a5d, 0xf1d: 0x3a7d,
1283 0xf1e: 0x3a9d, 0xf1f: 0x3abd, 0xf20: 0x3add, 0xf21: 0x3afd, 0xf22: 0x3b1d, 0xf23: 0x3b3d,
1284 0xf24: 0x3b5d, 0xf25: 0x3b7d, 0xf26: 0x127d, 0xf27: 0x3b9d, 0xf28: 0x3bbd, 0xf29: 0x3bdd,
1285 0xf2a: 0x3bfd, 0xf2b: 0x3c1d, 0xf2c: 0x3c3d, 0xf2d: 0x3c5d, 0xf2e: 0x239d, 0xf2f: 0x3c7d,
1286 0xf30: 0x3c9d, 0xf31: 0x3939, 0xf32: 0x3951, 0xf33: 0x3969, 0xf34: 0x3981, 0xf35: 0x3999,
1287 0xf36: 0x39b1, 0xf37: 0x39c9, 0xf38: 0x39e1, 0xf39: 0x39f9, 0xf3a: 0x3a11, 0xf3b: 0x3a29,
1288 0xf3c: 0x3a41, 0xf3d: 0x3a59, 0xf3e: 0x3a71, 0xf3f: 0x3a89,
1289 // Block 0x3d, offset 0xf40
1290 0xf40: 0x3aa1, 0xf41: 0x3ac9, 0xf42: 0x3af1, 0xf43: 0x3b19, 0xf44: 0x3b41, 0xf45: 0x3b69,
1291 0xf46: 0x3b91, 0xf47: 0x3bb9, 0xf48: 0x3be1, 0xf49: 0x3c09, 0xf4a: 0x3c39, 0xf4b: 0x3c69,
1292 0xf4c: 0x3c99, 0xf4d: 0x3cbd, 0xf4e: 0x3cb1, 0xf4f: 0x3cdd, 0xf50: 0x3cfd, 0xf51: 0x3d15,
1293 0xf52: 0x3d2d, 0xf53: 0x3d45, 0xf54: 0x3d5d, 0xf55: 0x3d5d, 0xf56: 0x3d45, 0xf57: 0x3d75,
1294 0xf58: 0x07bd, 0xf59: 0x3d8d, 0xf5a: 0x3da5, 0xf5b: 0x3dbd, 0xf5c: 0x3dd5, 0xf5d: 0x3ded,
1295 0xf5e: 0x3e05, 0xf5f: 0x3e1d, 0xf60: 0x3e35, 0xf61: 0x3e4d, 0xf62: 0x3e65, 0xf63: 0x3e7d,
1296 0xf64: 0x3e95, 0xf65: 0x3e95, 0xf66: 0x3ead, 0xf67: 0x3ead, 0xf68: 0x3ec5, 0xf69: 0x3ec5,
1297 0xf6a: 0x3edd, 0xf6b: 0x3ef5, 0xf6c: 0x3f0d, 0xf6d: 0x3f25, 0xf6e: 0x3f3d, 0xf6f: 0x3f3d,
1298 0xf70: 0x3f55, 0xf71: 0x3f55, 0xf72: 0x3f55, 0xf73: 0x3f6d, 0xf74: 0x3f85, 0xf75: 0x3f9d,
1299 0xf76: 0x3fb5, 0xf77: 0x3f9d, 0xf78: 0x3fcd, 0xf79: 0x3fe5, 0xf7a: 0x3f6d, 0xf7b: 0x3ffd,
1300 0xf7c: 0x4015, 0xf7d: 0x4015, 0xf7e: 0x4015, 0xf7f: 0x0040,
1301 // Block 0x3e, offset 0xf80
1302 0xf80: 0x3cc9, 0xf81: 0x3d31, 0xf82: 0x3d99, 0xf83: 0x3e01, 0xf84: 0x3e51, 0xf85: 0x3eb9,
1303 0xf86: 0x3f09, 0xf87: 0x3f59, 0xf88: 0x3fd9, 0xf89: 0x4041, 0xf8a: 0x4091, 0xf8b: 0x40e1,
1304 0xf8c: 0x4131, 0xf8d: 0x4199, 0xf8e: 0x4201, 0xf8f: 0x4251, 0xf90: 0x42a1, 0xf91: 0x42d9,
1305 0xf92: 0x4329, 0xf93: 0x4391, 0xf94: 0x43f9, 0xf95: 0x4431, 0xf96: 0x44b1, 0xf97: 0x4549,
1306 0xf98: 0x45c9, 0xf99: 0x4619, 0xf9a: 0x4699, 0xf9b: 0x4719, 0xf9c: 0x4781, 0xf9d: 0x47d1,
1307 0xf9e: 0x4821, 0xf9f: 0x4871, 0xfa0: 0x48d9, 0xfa1: 0x4959, 0xfa2: 0x49c1, 0xfa3: 0x4a11,
1308 0xfa4: 0x4a61, 0xfa5: 0x4ab1, 0xfa6: 0x4ae9, 0xfa7: 0x4b21, 0xfa8: 0x4b59, 0xfa9: 0x4b91,
1309 0xfaa: 0x4be1, 0xfab: 0x4c31, 0xfac: 0x4cb1, 0xfad: 0x4d01, 0xfae: 0x4d69, 0xfaf: 0x4de9,
1310 0xfb0: 0x4e39, 0xfb1: 0x4e71, 0xfb2: 0x4ea9, 0xfb3: 0x4f29, 0xfb4: 0x4f91, 0xfb5: 0x5011,
1311 0xfb6: 0x5061, 0xfb7: 0x50e1, 0xfb8: 0x5119, 0xfb9: 0x5169, 0xfba: 0x51b9, 0xfbb: 0x5209,
1312 0xfbc: 0x5259, 0xfbd: 0x52a9, 0xfbe: 0x5311, 0xfbf: 0x5361,
1313 // Block 0x3f, offset 0xfc0
1314 0xfc0: 0x5399, 0xfc1: 0x53e9, 0xfc2: 0x5439, 0xfc3: 0x5489, 0xfc4: 0x54f1, 0xfc5: 0x5541,
1315 0xfc6: 0x5591, 0xfc7: 0x55e1, 0xfc8: 0x5661, 0xfc9: 0x56c9, 0xfca: 0x5701, 0xfcb: 0x5781,
1316 0xfcc: 0x57b9, 0xfcd: 0x5821, 0xfce: 0x5889, 0xfcf: 0x58d9, 0xfd0: 0x5929, 0xfd1: 0x5979,
1317 0xfd2: 0x59e1, 0xfd3: 0x5a19, 0xfd4: 0x5a69, 0xfd5: 0x5ad1, 0xfd6: 0x5b09, 0xfd7: 0x5b89,
1318 0xfd8: 0x5bd9, 0xfd9: 0x5c01, 0xfda: 0x5c29, 0xfdb: 0x5c51, 0xfdc: 0x5c79, 0xfdd: 0x5ca1,
1319 0xfde: 0x5cc9, 0xfdf: 0x5cf1, 0xfe0: 0x5d19, 0xfe1: 0x5d41, 0xfe2: 0x5d69, 0xfe3: 0x5d99,
1320 0xfe4: 0x5dc9, 0xfe5: 0x5df9, 0xfe6: 0x5e29, 0xfe7: 0x5e59, 0xfe8: 0x5e89, 0xfe9: 0x5eb9,
1321 0xfea: 0x5ee9, 0xfeb: 0x5f19, 0xfec: 0x5f49, 0xfed: 0x5f79, 0xfee: 0x5fa9, 0xfef: 0x5fd9,
1322 0xff0: 0x6009, 0xff1: 0x402d, 0xff2: 0x6039, 0xff3: 0x6051, 0xff4: 0x404d, 0xff5: 0x6069,
1323 0xff6: 0x6081, 0xff7: 0x6099, 0xff8: 0x406d, 0xff9: 0x406d, 0xffa: 0x60b1, 0xffb: 0x60c9,
1324 0xffc: 0x6101, 0xffd: 0x6139, 0xffe: 0x6171, 0xfff: 0x61a9,
1325 // Block 0x40, offset 0x1000
1326 0x1000: 0x6211, 0x1001: 0x6229, 0x1002: 0x408d, 0x1003: 0x6241, 0x1004: 0x6259, 0x1005: 0x6271,
1327 0x1006: 0x6289, 0x1007: 0x62a1, 0x1008: 0x40ad, 0x1009: 0x62b9, 0x100a: 0x62e1, 0x100b: 0x62f9,
1328 0x100c: 0x40cd, 0x100d: 0x40cd, 0x100e: 0x6311, 0x100f: 0x6329, 0x1010: 0x6341, 0x1011: 0x40ed,
1329 0x1012: 0x410d, 0x1013: 0x412d, 0x1014: 0x414d, 0x1015: 0x416d, 0x1016: 0x6359, 0x1017: 0x6371,
1330 0x1018: 0x6389, 0x1019: 0x63a1, 0x101a: 0x63b9, 0x101b: 0x418d, 0x101c: 0x63d1, 0x101d: 0x63e9,
1331 0x101e: 0x6401, 0x101f: 0x41ad, 0x1020: 0x41cd, 0x1021: 0x6419, 0x1022: 0x41ed, 0x1023: 0x420d,
1332 0x1024: 0x422d, 0x1025: 0x6431, 0x1026: 0x424d, 0x1027: 0x6449, 0x1028: 0x6479, 0x1029: 0x6211,
1333 0x102a: 0x426d, 0x102b: 0x428d, 0x102c: 0x42ad, 0x102d: 0x42cd, 0x102e: 0x64b1, 0x102f: 0x64f1,
1334 0x1030: 0x6539, 0x1031: 0x6551, 0x1032: 0x42ed, 0x1033: 0x6569, 0x1034: 0x6581, 0x1035: 0x6599,
1335 0x1036: 0x430d, 0x1037: 0x65b1, 0x1038: 0x65c9, 0x1039: 0x65b1, 0x103a: 0x65e1, 0x103b: 0x65f9,
1336 0x103c: 0x432d, 0x103d: 0x6611, 0x103e: 0x6629, 0x103f: 0x6611,
1337 // Block 0x41, offset 0x1040
1338 0x1040: 0x434d, 0x1041: 0x436d, 0x1042: 0x0040, 0x1043: 0x6641, 0x1044: 0x6659, 0x1045: 0x6671,
1339 0x1046: 0x6689, 0x1047: 0x0040, 0x1048: 0x66c1, 0x1049: 0x66d9, 0x104a: 0x66f1, 0x104b: 0x6709,
1340 0x104c: 0x6721, 0x104d: 0x6739, 0x104e: 0x6401, 0x104f: 0x6751, 0x1050: 0x6769, 0x1051: 0x6781,
1341 0x1052: 0x438d, 0x1053: 0x6799, 0x1054: 0x6289, 0x1055: 0x43ad, 0x1056: 0x43cd, 0x1057: 0x67b1,
1342 0x1058: 0x0040, 0x1059: 0x43ed, 0x105a: 0x67c9, 0x105b: 0x67e1, 0x105c: 0x67f9, 0x105d: 0x6811,
1343 0x105e: 0x6829, 0x105f: 0x6859, 0x1060: 0x6889, 0x1061: 0x68b1, 0x1062: 0x68d9, 0x1063: 0x6901,
1344 0x1064: 0x6929, 0x1065: 0x6951, 0x1066: 0x6979, 0x1067: 0x69a1, 0x1068: 0x69c9, 0x1069: 0x69f1,
1345 0x106a: 0x6a21, 0x106b: 0x6a51, 0x106c: 0x6a81, 0x106d: 0x6ab1, 0x106e: 0x6ae1, 0x106f: 0x6b11,
1346 0x1070: 0x6b41, 0x1071: 0x6b71, 0x1072: 0x6ba1, 0x1073: 0x6bd1, 0x1074: 0x6c01, 0x1075: 0x6c31,
1347 0x1076: 0x6c61, 0x1077: 0x6c91, 0x1078: 0x6cc1, 0x1079: 0x6cf1, 0x107a: 0x6d21, 0x107b: 0x6d51,
1348 0x107c: 0x6d81, 0x107d: 0x6db1, 0x107e: 0x6de1, 0x107f: 0x440d,
1349 // Block 0x42, offset 0x1080
1350 0x1080: 0xe00d, 0x1081: 0x0008, 0x1082: 0xe00d, 0x1083: 0x0008, 0x1084: 0xe00d, 0x1085: 0x0008,
1351 0x1086: 0xe00d, 0x1087: 0x0008, 0x1088: 0xe00d, 0x1089: 0x0008, 0x108a: 0xe00d, 0x108b: 0x0008,
1352 0x108c: 0xe00d, 0x108d: 0x0008, 0x108e: 0xe00d, 0x108f: 0x0008, 0x1090: 0xe00d, 0x1091: 0x0008,
1353 0x1092: 0xe00d, 0x1093: 0x0008, 0x1094: 0xe00d, 0x1095: 0x0008, 0x1096: 0xe00d, 0x1097: 0x0008,
1354 0x1098: 0xe00d, 0x1099: 0x0008, 0x109a: 0xe00d, 0x109b: 0x0008, 0x109c: 0xe00d, 0x109d: 0x0008,
1355 0x109e: 0xe00d, 0x109f: 0x0008, 0x10a0: 0xe00d, 0x10a1: 0x0008, 0x10a2: 0xe00d, 0x10a3: 0x0008,
1356 0x10a4: 0xe00d, 0x10a5: 0x0008, 0x10a6: 0xe00d, 0x10a7: 0x0008, 0x10a8: 0xe00d, 0x10a9: 0x0008,
1357 0x10aa: 0xe00d, 0x10ab: 0x0008, 0x10ac: 0xe00d, 0x10ad: 0x0008, 0x10ae: 0x0008, 0x10af: 0x1308,
1358 0x10b0: 0x1318, 0x10b1: 0x1318, 0x10b2: 0x1318, 0x10b3: 0x0018, 0x10b4: 0x1308, 0x10b5: 0x1308,
1359 0x10b6: 0x1308, 0x10b7: 0x1308, 0x10b8: 0x1308, 0x10b9: 0x1308, 0x10ba: 0x1308, 0x10bb: 0x1308,
1360 0x10bc: 0x1308, 0x10bd: 0x1308, 0x10be: 0x0018, 0x10bf: 0x0008,
1361 // Block 0x43, offset 0x10c0
1362 0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008,
1363 0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008,
1364 0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008,
1365 0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008,
1366 0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0x0ea1, 0x10dd: 0x6e11,
1367 0x10de: 0x1308, 0x10df: 0x1308, 0x10e0: 0x0008, 0x10e1: 0x0008, 0x10e2: 0x0008, 0x10e3: 0x0008,
1368 0x10e4: 0x0008, 0x10e5: 0x0008, 0x10e6: 0x0008, 0x10e7: 0x0008, 0x10e8: 0x0008, 0x10e9: 0x0008,
1369 0x10ea: 0x0008, 0x10eb: 0x0008, 0x10ec: 0x0008, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x0008,
1370 0x10f0: 0x0008, 0x10f1: 0x0008, 0x10f2: 0x0008, 0x10f3: 0x0008, 0x10f4: 0x0008, 0x10f5: 0x0008,
1371 0x10f6: 0x0008, 0x10f7: 0x0008, 0x10f8: 0x0008, 0x10f9: 0x0008, 0x10fa: 0x0008, 0x10fb: 0x0008,
1372 0x10fc: 0x0008, 0x10fd: 0x0008, 0x10fe: 0x0008, 0x10ff: 0x0008,
1373 // Block 0x44, offset 0x1100
1374 0x1100: 0x0018, 0x1101: 0x0018, 0x1102: 0x0018, 0x1103: 0x0018, 0x1104: 0x0018, 0x1105: 0x0018,
1375 0x1106: 0x0018, 0x1107: 0x0018, 0x1108: 0x0018, 0x1109: 0x0018, 0x110a: 0x0018, 0x110b: 0x0018,
1376 0x110c: 0x0018, 0x110d: 0x0018, 0x110e: 0x0018, 0x110f: 0x0018, 0x1110: 0x0018, 0x1111: 0x0018,
1377 0x1112: 0x0018, 0x1113: 0x0018, 0x1114: 0x0018, 0x1115: 0x0018, 0x1116: 0x0018, 0x1117: 0x0008,
1378 0x1118: 0x0008, 0x1119: 0x0008, 0x111a: 0x0008, 0x111b: 0x0008, 0x111c: 0x0008, 0x111d: 0x0008,
1379 0x111e: 0x0008, 0x111f: 0x0008, 0x1120: 0x0018, 0x1121: 0x0018, 0x1122: 0xe00d, 0x1123: 0x0008,
1380 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,
1381 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0xe00d, 0x112f: 0x0008,
1382 0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0xe00d, 0x1133: 0x0008, 0x1134: 0xe00d, 0x1135: 0x0008,
1383 0x1136: 0xe00d, 0x1137: 0x0008, 0x1138: 0xe00d, 0x1139: 0x0008, 0x113a: 0xe00d, 0x113b: 0x0008,
1384 0x113c: 0xe00d, 0x113d: 0x0008, 0x113e: 0xe00d, 0x113f: 0x0008,
1385 // Block 0x45, offset 0x1140
1386 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,
1387 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,
1388 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,
1389 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,
1390 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0xe00d, 0x115d: 0x0008,
1391 0x115e: 0xe00d, 0x115f: 0x0008, 0x1160: 0xe00d, 0x1161: 0x0008, 0x1162: 0xe00d, 0x1163: 0x0008,
1392 0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008,
1393 0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008,
1394 0x1170: 0xe0fd, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,
1395 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0xe01d, 0x117a: 0x0008, 0x117b: 0xe03d,
1396 0x117c: 0x0008, 0x117d: 0x442d, 0x117e: 0xe00d, 0x117f: 0x0008,
1397 // Block 0x46, offset 0x1180
1398 0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008,
1399 0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0x0008, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0xe03d,
1400 0x118c: 0x0008, 0x118d: 0x11d9, 0x118e: 0x0008, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008,
1401 0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0x0008, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008,
1402 0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008,
1403 0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008,
1404 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,
1405 0x11aa: 0x6e29, 0x11ab: 0x1029, 0x11ac: 0x11c1, 0x11ad: 0x6e41, 0x11ae: 0x1221, 0x11af: 0x0040,
1406 0x11b0: 0x6e59, 0x11b1: 0x6e71, 0x11b2: 0x1239, 0x11b3: 0x444d, 0x11b4: 0xe00d, 0x11b5: 0x0008,
1407 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0x0040, 0x11b9: 0x0040, 0x11ba: 0x0040, 0x11bb: 0x0040,
1408 0x11bc: 0x0040, 0x11bd: 0x0040, 0x11be: 0x0040, 0x11bf: 0x0040,
1409 // Block 0x47, offset 0x11c0
1410 0x11c0: 0x64d5, 0x11c1: 0x64f5, 0x11c2: 0x6515, 0x11c3: 0x6535, 0x11c4: 0x6555, 0x11c5: 0x6575,
1411 0x11c6: 0x6595, 0x11c7: 0x65b5, 0x11c8: 0x65d5, 0x11c9: 0x65f5, 0x11ca: 0x6615, 0x11cb: 0x6635,
1412 0x11cc: 0x6655, 0x11cd: 0x6675, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0x6695, 0x11d1: 0x0008,
1413 0x11d2: 0x66b5, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x66d5, 0x11d6: 0x66f5, 0x11d7: 0x6715,
1414 0x11d8: 0x6735, 0x11d9: 0x6755, 0x11da: 0x6775, 0x11db: 0x6795, 0x11dc: 0x67b5, 0x11dd: 0x67d5,
1415 0x11de: 0x67f5, 0x11df: 0x0008, 0x11e0: 0x6815, 0x11e1: 0x0008, 0x11e2: 0x6835, 0x11e3: 0x0008,
1416 0x11e4: 0x0008, 0x11e5: 0x6855, 0x11e6: 0x6875, 0x11e7: 0x0008, 0x11e8: 0x0008, 0x11e9: 0x0008,
1417 0x11ea: 0x6895, 0x11eb: 0x68b5, 0x11ec: 0x68d5, 0x11ed: 0x68f5, 0x11ee: 0x6915, 0x11ef: 0x6935,
1418 0x11f0: 0x6955, 0x11f1: 0x6975, 0x11f2: 0x6995, 0x11f3: 0x69b5, 0x11f4: 0x69d5, 0x11f5: 0x69f5,
1419 0x11f6: 0x6a15, 0x11f7: 0x6a35, 0x11f8: 0x6a55, 0x11f9: 0x6a75, 0x11fa: 0x6a95, 0x11fb: 0x6ab5,
1420 0x11fc: 0x6ad5, 0x11fd: 0x6af5, 0x11fe: 0x6b15, 0x11ff: 0x6b35,
1421 // Block 0x48, offset 0x1200
1422 0x1200: 0x7a95, 0x1201: 0x7ab5, 0x1202: 0x7ad5, 0x1203: 0x7af5, 0x1204: 0x7b15, 0x1205: 0x7b35,
1423 0x1206: 0x7b55, 0x1207: 0x7b75, 0x1208: 0x7b95, 0x1209: 0x7bb5, 0x120a: 0x7bd5, 0x120b: 0x7bf5,
1424 0x120c: 0x7c15, 0x120d: 0x7c35, 0x120e: 0x7c55, 0x120f: 0x6ec9, 0x1210: 0x6ef1, 0x1211: 0x6f19,
1425 0x1212: 0x7c75, 0x1213: 0x7c95, 0x1214: 0x7cb5, 0x1215: 0x6f41, 0x1216: 0x6f69, 0x1217: 0x6f91,
1426 0x1218: 0x7cd5, 0x1219: 0x7cf5, 0x121a: 0x0040, 0x121b: 0x0040, 0x121c: 0x0040, 0x121d: 0x0040,
1427 0x121e: 0x0040, 0x121f: 0x0040, 0x1220: 0x0040, 0x1221: 0x0040, 0x1222: 0x0040, 0x1223: 0x0040,
1428 0x1224: 0x0040, 0x1225: 0x0040, 0x1226: 0x0040, 0x1227: 0x0040, 0x1228: 0x0040, 0x1229: 0x0040,
1429 0x122a: 0x0040, 0x122b: 0x0040, 0x122c: 0x0040, 0x122d: 0x0040, 0x122e: 0x0040, 0x122f: 0x0040,
1430 0x1230: 0x0040, 0x1231: 0x0040, 0x1232: 0x0040, 0x1233: 0x0040, 0x1234: 0x0040, 0x1235: 0x0040,
1431 0x1236: 0x0040, 0x1237: 0x0040, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040,
1432 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040,
1433 // Block 0x49, offset 0x1240
1434 0x1240: 0x6fb9, 0x1241: 0x6fd1, 0x1242: 0x6fe9, 0x1243: 0x7d15, 0x1244: 0x7d35, 0x1245: 0x7001,
1435 0x1246: 0x7001, 0x1247: 0x0040, 0x1248: 0x0040, 0x1249: 0x0040, 0x124a: 0x0040, 0x124b: 0x0040,
1436 0x124c: 0x0040, 0x124d: 0x0040, 0x124e: 0x0040, 0x124f: 0x0040, 0x1250: 0x0040, 0x1251: 0x0040,
1437 0x1252: 0x0040, 0x1253: 0x7019, 0x1254: 0x7041, 0x1255: 0x7069, 0x1256: 0x7091, 0x1257: 0x70b9,
1438 0x1258: 0x0040, 0x1259: 0x0040, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x70e1,
1439 0x125e: 0x1308, 0x125f: 0x7109, 0x1260: 0x7131, 0x1261: 0x20a9, 0x1262: 0x20f1, 0x1263: 0x7149,
1440 0x1264: 0x7161, 0x1265: 0x7179, 0x1266: 0x7191, 0x1267: 0x71a9, 0x1268: 0x71c1, 0x1269: 0x1fb2,
1441 0x126a: 0x71d9, 0x126b: 0x7201, 0x126c: 0x7229, 0x126d: 0x7261, 0x126e: 0x7299, 0x126f: 0x72c1,
1442 0x1270: 0x72e9, 0x1271: 0x7311, 0x1272: 0x7339, 0x1273: 0x7361, 0x1274: 0x7389, 0x1275: 0x73b1,
1443 0x1276: 0x73d9, 0x1277: 0x0040, 0x1278: 0x7401, 0x1279: 0x7429, 0x127a: 0x7451, 0x127b: 0x7479,
1444 0x127c: 0x74a1, 0x127d: 0x0040, 0x127e: 0x74c9, 0x127f: 0x0040,
1445 // Block 0x4a, offset 0x1280
1446 0x1280: 0x74f1, 0x1281: 0x7519, 0x1282: 0x0040, 0x1283: 0x7541, 0x1284: 0x7569, 0x1285: 0x0040,
1447 0x1286: 0x7591, 0x1287: 0x75b9, 0x1288: 0x75e1, 0x1289: 0x7609, 0x128a: 0x7631, 0x128b: 0x7659,
1448 0x128c: 0x7681, 0x128d: 0x76a9, 0x128e: 0x76d1, 0x128f: 0x76f9, 0x1290: 0x7721, 0x1291: 0x7721,
1449 0x1292: 0x7739, 0x1293: 0x7739, 0x1294: 0x7739, 0x1295: 0x7739, 0x1296: 0x7751, 0x1297: 0x7751,
1450 0x1298: 0x7751, 0x1299: 0x7751, 0x129a: 0x7769, 0x129b: 0x7769, 0x129c: 0x7769, 0x129d: 0x7769,
1451 0x129e: 0x7781, 0x129f: 0x7781, 0x12a0: 0x7781, 0x12a1: 0x7781, 0x12a2: 0x7799, 0x12a3: 0x7799,
1452 0x12a4: 0x7799, 0x12a5: 0x7799, 0x12a6: 0x77b1, 0x12a7: 0x77b1, 0x12a8: 0x77b1, 0x12a9: 0x77b1,
1453 0x12aa: 0x77c9, 0x12ab: 0x77c9, 0x12ac: 0x77c9, 0x12ad: 0x77c9, 0x12ae: 0x77e1, 0x12af: 0x77e1,
1454 0x12b0: 0x77e1, 0x12b1: 0x77e1, 0x12b2: 0x77f9, 0x12b3: 0x77f9, 0x12b4: 0x77f9, 0x12b5: 0x77f9,
1455 0x12b6: 0x7811, 0x12b7: 0x7811, 0x12b8: 0x7811, 0x12b9: 0x7811, 0x12ba: 0x7829, 0x12bb: 0x7829,
1456 0x12bc: 0x7829, 0x12bd: 0x7829, 0x12be: 0x7841, 0x12bf: 0x7841,
1457 // Block 0x4b, offset 0x12c0
1458 0x12c0: 0x7841, 0x12c1: 0x7841, 0x12c2: 0x7859, 0x12c3: 0x7859, 0x12c4: 0x7871, 0x12c5: 0x7871,
1459 0x12c6: 0x7889, 0x12c7: 0x7889, 0x12c8: 0x78a1, 0x12c9: 0x78a1, 0x12ca: 0x78b9, 0x12cb: 0x78b9,
1460 0x12cc: 0x78d1, 0x12cd: 0x78d1, 0x12ce: 0x78e9, 0x12cf: 0x78e9, 0x12d0: 0x78e9, 0x12d1: 0x78e9,
1461 0x12d2: 0x7901, 0x12d3: 0x7901, 0x12d4: 0x7901, 0x12d5: 0x7901, 0x12d6: 0x7919, 0x12d7: 0x7919,
1462 0x12d8: 0x7919, 0x12d9: 0x7919, 0x12da: 0x7931, 0x12db: 0x7931, 0x12dc: 0x7931, 0x12dd: 0x7931,
1463 0x12de: 0x7949, 0x12df: 0x7949, 0x12e0: 0x7961, 0x12e1: 0x7961, 0x12e2: 0x7961, 0x12e3: 0x7961,
1464 0x12e4: 0x7979, 0x12e5: 0x7979, 0x12e6: 0x7991, 0x12e7: 0x7991, 0x12e8: 0x7991, 0x12e9: 0x7991,
1465 0x12ea: 0x79a9, 0x12eb: 0x79a9, 0x12ec: 0x79a9, 0x12ed: 0x79a9, 0x12ee: 0x79c1, 0x12ef: 0x79c1,
1466 0x12f0: 0x79d9, 0x12f1: 0x79d9, 0x12f2: 0x0018, 0x12f3: 0x0018, 0x12f4: 0x0018, 0x12f5: 0x0018,
1467 0x12f6: 0x0018, 0x12f7: 0x0018, 0x12f8: 0x0018, 0x12f9: 0x0018, 0x12fa: 0x0018, 0x12fb: 0x0018,
1468 0x12fc: 0x0018, 0x12fd: 0x0018, 0x12fe: 0x0018, 0x12ff: 0x0018,
1469 // Block 0x4c, offset 0x1300
1470 0x1300: 0x0018, 0x1301: 0x0018, 0x1302: 0x0040, 0x1303: 0x0040, 0x1304: 0x0040, 0x1305: 0x0040,
1471 0x1306: 0x0040, 0x1307: 0x0040, 0x1308: 0x0040, 0x1309: 0x0040, 0x130a: 0x0040, 0x130b: 0x0040,
1472 0x130c: 0x0040, 0x130d: 0x0040, 0x130e: 0x0040, 0x130f: 0x0040, 0x1310: 0x0040, 0x1311: 0x0040,
1473 0x1312: 0x0040, 0x1313: 0x79f1, 0x1314: 0x79f1, 0x1315: 0x79f1, 0x1316: 0x79f1, 0x1317: 0x7a09,
1474 0x1318: 0x7a09, 0x1319: 0x7a21, 0x131a: 0x7a21, 0x131b: 0x7a39, 0x131c: 0x7a39, 0x131d: 0x0479,
1475 0x131e: 0x7a51, 0x131f: 0x7a51, 0x1320: 0x7a69, 0x1321: 0x7a69, 0x1322: 0x7a81, 0x1323: 0x7a81,
1476 0x1324: 0x7a99, 0x1325: 0x7a99, 0x1326: 0x7a99, 0x1327: 0x7a99, 0x1328: 0x7ab1, 0x1329: 0x7ab1,
1477 0x132a: 0x7ac9, 0x132b: 0x7ac9, 0x132c: 0x7af1, 0x132d: 0x7af1, 0x132e: 0x7b19, 0x132f: 0x7b19,
1478 0x1330: 0x7b41, 0x1331: 0x7b41, 0x1332: 0x7b69, 0x1333: 0x7b69, 0x1334: 0x7b91, 0x1335: 0x7b91,
1479 0x1336: 0x7bb9, 0x1337: 0x7bb9, 0x1338: 0x7bb9, 0x1339: 0x7be1, 0x133a: 0x7be1, 0x133b: 0x7be1,
1480 0x133c: 0x7c09, 0x133d: 0x7c09, 0x133e: 0x7c09, 0x133f: 0x7c09,
1481 // Block 0x4d, offset 0x1340
1482 0x1340: 0x85f9, 0x1341: 0x8621, 0x1342: 0x8649, 0x1343: 0x8671, 0x1344: 0x8699, 0x1345: 0x86c1,
1483 0x1346: 0x86e9, 0x1347: 0x8711, 0x1348: 0x8739, 0x1349: 0x8761, 0x134a: 0x8789, 0x134b: 0x87b1,
1484 0x134c: 0x87d9, 0x134d: 0x8801, 0x134e: 0x8829, 0x134f: 0x8851, 0x1350: 0x8879, 0x1351: 0x88a1,
1485 0x1352: 0x88c9, 0x1353: 0x88f1, 0x1354: 0x8919, 0x1355: 0x8941, 0x1356: 0x8969, 0x1357: 0x8991,
1486 0x1358: 0x89b9, 0x1359: 0x89e1, 0x135a: 0x8a09, 0x135b: 0x8a31, 0x135c: 0x8a59, 0x135d: 0x8a81,
1487 0x135e: 0x8aaa, 0x135f: 0x8ada, 0x1360: 0x8b0a, 0x1361: 0x8b3a, 0x1362: 0x8b6a, 0x1363: 0x8b9a,
1488 0x1364: 0x8bc9, 0x1365: 0x8bf1, 0x1366: 0x7c71, 0x1367: 0x8c19, 0x1368: 0x7be1, 0x1369: 0x7c99,
1489 0x136a: 0x8c41, 0x136b: 0x8c69, 0x136c: 0x7d39, 0x136d: 0x8c91, 0x136e: 0x7d61, 0x136f: 0x7d89,
1490 0x1370: 0x8cb9, 0x1371: 0x8ce1, 0x1372: 0x7e29, 0x1373: 0x8d09, 0x1374: 0x7e51, 0x1375: 0x7e79,
1491 0x1376: 0x8d31, 0x1377: 0x8d59, 0x1378: 0x7ec9, 0x1379: 0x8d81, 0x137a: 0x7ef1, 0x137b: 0x7f19,
1492 0x137c: 0x83a1, 0x137d: 0x83c9, 0x137e: 0x8441, 0x137f: 0x8469,
1493 // Block 0x4e, offset 0x1380
1494 0x1380: 0x8491, 0x1381: 0x8531, 0x1382: 0x8559, 0x1383: 0x8581, 0x1384: 0x85a9, 0x1385: 0x8649,
1495 0x1386: 0x8671, 0x1387: 0x8699, 0x1388: 0x8da9, 0x1389: 0x8739, 0x138a: 0x8dd1, 0x138b: 0x8df9,
1496 0x138c: 0x8829, 0x138d: 0x8e21, 0x138e: 0x8851, 0x138f: 0x8879, 0x1390: 0x8a81, 0x1391: 0x8e49,
1497 0x1392: 0x8e71, 0x1393: 0x89b9, 0x1394: 0x8e99, 0x1395: 0x89e1, 0x1396: 0x8a09, 0x1397: 0x7c21,
1498 0x1398: 0x7c49, 0x1399: 0x8ec1, 0x139a: 0x7c71, 0x139b: 0x8ee9, 0x139c: 0x7cc1, 0x139d: 0x7ce9,
1499 0x139e: 0x7d11, 0x139f: 0x7d39, 0x13a0: 0x8f11, 0x13a1: 0x7db1, 0x13a2: 0x7dd9, 0x13a3: 0x7e01,
1500 0x13a4: 0x7e29, 0x13a5: 0x8f39, 0x13a6: 0x7ec9, 0x13a7: 0x7f41, 0x13a8: 0x7f69, 0x13a9: 0x7f91,
1501 0x13aa: 0x7fb9, 0x13ab: 0x7fe1, 0x13ac: 0x8031, 0x13ad: 0x8059, 0x13ae: 0x8081, 0x13af: 0x80a9,
1502 0x13b0: 0x80d1, 0x13b1: 0x80f9, 0x13b2: 0x8f61, 0x13b3: 0x8121, 0x13b4: 0x8149, 0x13b5: 0x8171,
1503 0x13b6: 0x8199, 0x13b7: 0x81c1, 0x13b8: 0x81e9, 0x13b9: 0x8239, 0x13ba: 0x8261, 0x13bb: 0x8289,
1504 0x13bc: 0x82b1, 0x13bd: 0x82d9, 0x13be: 0x8301, 0x13bf: 0x8329,
1505 // Block 0x4f, offset 0x13c0
1506 0x13c0: 0x8351, 0x13c1: 0x8379, 0x13c2: 0x83f1, 0x13c3: 0x8419, 0x13c4: 0x84b9, 0x13c5: 0x84e1,
1507 0x13c6: 0x8509, 0x13c7: 0x8531, 0x13c8: 0x8559, 0x13c9: 0x85d1, 0x13ca: 0x85f9, 0x13cb: 0x8621,
1508 0x13cc: 0x8649, 0x13cd: 0x8f89, 0x13ce: 0x86c1, 0x13cf: 0x86e9, 0x13d0: 0x8711, 0x13d1: 0x8739,
1509 0x13d2: 0x87b1, 0x13d3: 0x87d9, 0x13d4: 0x8801, 0x13d5: 0x8829, 0x13d6: 0x8fb1, 0x13d7: 0x88a1,
1510 0x13d8: 0x88c9, 0x13d9: 0x8fd9, 0x13da: 0x8941, 0x13db: 0x8969, 0x13dc: 0x8991, 0x13dd: 0x89b9,
1511 0x13de: 0x9001, 0x13df: 0x7c71, 0x13e0: 0x8ee9, 0x13e1: 0x7d39, 0x13e2: 0x8f11, 0x13e3: 0x7e29,
1512 0x13e4: 0x8f39, 0x13e5: 0x7ec9, 0x13e6: 0x9029, 0x13e7: 0x80d1, 0x13e8: 0x9051, 0x13e9: 0x9079,
1513 0x13ea: 0x90a1, 0x13eb: 0x8531, 0x13ec: 0x8559, 0x13ed: 0x8649, 0x13ee: 0x8829, 0x13ef: 0x8fb1,
1514 0x13f0: 0x89b9, 0x13f1: 0x9001, 0x13f2: 0x90c9, 0x13f3: 0x9101, 0x13f4: 0x9139, 0x13f5: 0x9171,
1515 0x13f6: 0x9199, 0x13f7: 0x91c1, 0x13f8: 0x91e9, 0x13f9: 0x9211, 0x13fa: 0x9239, 0x13fb: 0x9261,
1516 0x13fc: 0x9289, 0x13fd: 0x92b1, 0x13fe: 0x92d9, 0x13ff: 0x9301,
1517 // Block 0x50, offset 0x1400
1518 0x1400: 0x9329, 0x1401: 0x9351, 0x1402: 0x9379, 0x1403: 0x93a1, 0x1404: 0x93c9, 0x1405: 0x93f1,
1519 0x1406: 0x9419, 0x1407: 0x9441, 0x1408: 0x9469, 0x1409: 0x9491, 0x140a: 0x94b9, 0x140b: 0x94e1,
1520 0x140c: 0x9079, 0x140d: 0x9509, 0x140e: 0x9531, 0x140f: 0x9559, 0x1410: 0x9581, 0x1411: 0x9171,
1521 0x1412: 0x9199, 0x1413: 0x91c1, 0x1414: 0x91e9, 0x1415: 0x9211, 0x1416: 0x9239, 0x1417: 0x9261,
1522 0x1418: 0x9289, 0x1419: 0x92b1, 0x141a: 0x92d9, 0x141b: 0x9301, 0x141c: 0x9329, 0x141d: 0x9351,
1523 0x141e: 0x9379, 0x141f: 0x93a1, 0x1420: 0x93c9, 0x1421: 0x93f1, 0x1422: 0x9419, 0x1423: 0x9441,
1524 0x1424: 0x9469, 0x1425: 0x9491, 0x1426: 0x94b9, 0x1427: 0x94e1, 0x1428: 0x9079, 0x1429: 0x9509,
1525 0x142a: 0x9531, 0x142b: 0x9559, 0x142c: 0x9581, 0x142d: 0x9491, 0x142e: 0x94b9, 0x142f: 0x94e1,
1526 0x1430: 0x9079, 0x1431: 0x9051, 0x1432: 0x90a1, 0x1433: 0x8211, 0x1434: 0x8059, 0x1435: 0x8081,
1527 0x1436: 0x80a9, 0x1437: 0x9491, 0x1438: 0x94b9, 0x1439: 0x94e1, 0x143a: 0x8211, 0x143b: 0x8239,
1528 0x143c: 0x95a9, 0x143d: 0x95a9, 0x143e: 0x0018, 0x143f: 0x0018,
1529 // Block 0x51, offset 0x1440
1530 0x1440: 0x0040, 0x1441: 0x0040, 0x1442: 0x0040, 0x1443: 0x0040, 0x1444: 0x0040, 0x1445: 0x0040,
1531 0x1446: 0x0040, 0x1447: 0x0040, 0x1448: 0x0040, 0x1449: 0x0040, 0x144a: 0x0040, 0x144b: 0x0040,
1532 0x144c: 0x0040, 0x144d: 0x0040, 0x144e: 0x0040, 0x144f: 0x0040, 0x1450: 0x95d1, 0x1451: 0x9609,
1533 0x1452: 0x9609, 0x1453: 0x9641, 0x1454: 0x9679, 0x1455: 0x96b1, 0x1456: 0x96e9, 0x1457: 0x9721,
1534 0x1458: 0x9759, 0x1459: 0x9759, 0x145a: 0x9791, 0x145b: 0x97c9, 0x145c: 0x9801, 0x145d: 0x9839,
1535 0x145e: 0x9871, 0x145f: 0x98a9, 0x1460: 0x98a9, 0x1461: 0x98e1, 0x1462: 0x9919, 0x1463: 0x9919,
1536 0x1464: 0x9951, 0x1465: 0x9951, 0x1466: 0x9989, 0x1467: 0x99c1, 0x1468: 0x99c1, 0x1469: 0x99f9,
1537 0x146a: 0x9a31, 0x146b: 0x9a31, 0x146c: 0x9a69, 0x146d: 0x9a69, 0x146e: 0x9aa1, 0x146f: 0x9ad9,
1538 0x1470: 0x9ad9, 0x1471: 0x9b11, 0x1472: 0x9b11, 0x1473: 0x9b49, 0x1474: 0x9b81, 0x1475: 0x9bb9,
1539 0x1476: 0x9bf1, 0x1477: 0x9bf1, 0x1478: 0x9c29, 0x1479: 0x9c61, 0x147a: 0x9c99, 0x147b: 0x9cd1,
1540 0x147c: 0x9d09, 0x147d: 0x9d09, 0x147e: 0x9d41, 0x147f: 0x9d79,
1541 // Block 0x52, offset 0x1480
1542 0x1480: 0xa949, 0x1481: 0xa981, 0x1482: 0xa9b9, 0x1483: 0xa8a1, 0x1484: 0x9bb9, 0x1485: 0x9989,
1543 0x1486: 0xa9f1, 0x1487: 0xaa29, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040,
1544 0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x0040, 0x1491: 0x0040,
1545 0x1492: 0x0040, 0x1493: 0x0040, 0x1494: 0x0040, 0x1495: 0x0040, 0x1496: 0x0040, 0x1497: 0x0040,
1546 0x1498: 0x0040, 0x1499: 0x0040, 0x149a: 0x0040, 0x149b: 0x0040, 0x149c: 0x0040, 0x149d: 0x0040,
1547 0x149e: 0x0040, 0x149f: 0x0040, 0x14a0: 0x0040, 0x14a1: 0x0040, 0x14a2: 0x0040, 0x14a3: 0x0040,
1548 0x14a4: 0x0040, 0x14a5: 0x0040, 0x14a6: 0x0040, 0x14a7: 0x0040, 0x14a8: 0x0040, 0x14a9: 0x0040,
1549 0x14aa: 0x0040, 0x14ab: 0x0040, 0x14ac: 0x0040, 0x14ad: 0x0040, 0x14ae: 0x0040, 0x14af: 0x0040,
1550 0x14b0: 0xaa61, 0x14b1: 0xaa99, 0x14b2: 0xaad1, 0x14b3: 0xab19, 0x14b4: 0xab61, 0x14b5: 0xaba9,
1551 0x14b6: 0xabf1, 0x14b7: 0xac39, 0x14b8: 0xac81, 0x14b9: 0xacc9, 0x14ba: 0xad02, 0x14bb: 0xae12,
1552 0x14bc: 0xae91, 0x14bd: 0x0018, 0x14be: 0x0040, 0x14bf: 0x0040,
1553 // Block 0x53, offset 0x14c0
1554 0x14c0: 0x13c0, 0x14c1: 0x13c0, 0x14c2: 0x13c0, 0x14c3: 0x13c0, 0x14c4: 0x13c0, 0x14c5: 0x13c0,
1555 0x14c6: 0x13c0, 0x14c7: 0x13c0, 0x14c8: 0x13c0, 0x14c9: 0x13c0, 0x14ca: 0x13c0, 0x14cb: 0x13c0,
1556 0x14cc: 0x13c0, 0x14cd: 0x13c0, 0x14ce: 0x13c0, 0x14cf: 0x13c0, 0x14d0: 0xaeda, 0x14d1: 0x7d55,
1557 0x14d2: 0x0040, 0x14d3: 0xaeea, 0x14d4: 0x03c2, 0x14d5: 0xaefa, 0x14d6: 0xaf0a, 0x14d7: 0x7d75,
1558 0x14d8: 0x7d95, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040,
1559 0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x1308, 0x14e1: 0x1308, 0x14e2: 0x1308, 0x14e3: 0x1308,
1560 0x14e4: 0x1308, 0x14e5: 0x1308, 0x14e6: 0x1308, 0x14e7: 0x1308, 0x14e8: 0x1308, 0x14e9: 0x1308,
1561 0x14ea: 0x1308, 0x14eb: 0x1308, 0x14ec: 0x1308, 0x14ed: 0x1308, 0x14ee: 0x1308, 0x14ef: 0x1308,
1562 0x14f0: 0x0040, 0x14f1: 0x7db5, 0x14f2: 0x7dd5, 0x14f3: 0xaf1a, 0x14f4: 0xaf1a, 0x14f5: 0x1fd2,
1563 0x14f6: 0x1fe2, 0x14f7: 0xaf2a, 0x14f8: 0xaf3a, 0x14f9: 0x7df5, 0x14fa: 0x7e15, 0x14fb: 0x7e35,
1564 0x14fc: 0x7df5, 0x14fd: 0x7e55, 0x14fe: 0x7e75, 0x14ff: 0x7e55,
1565 // Block 0x54, offset 0x1500
1566 0x1500: 0x7e95, 0x1501: 0x7eb5, 0x1502: 0x7ed5, 0x1503: 0x7eb5, 0x1504: 0x7ef5, 0x1505: 0x0018,
1567 0x1506: 0x0018, 0x1507: 0xaf4a, 0x1508: 0xaf5a, 0x1509: 0x7f16, 0x150a: 0x7f36, 0x150b: 0x7f56,
1568 0x150c: 0x7f76, 0x150d: 0xaf1a, 0x150e: 0xaf1a, 0x150f: 0xaf1a, 0x1510: 0xaeda, 0x1511: 0x7f95,
1569 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x03c2, 0x1515: 0xaeea, 0x1516: 0xaf0a, 0x1517: 0xaefa,
1570 0x1518: 0x7fb5, 0x1519: 0x1fd2, 0x151a: 0x1fe2, 0x151b: 0xaf2a, 0x151c: 0xaf3a, 0x151d: 0x7e95,
1571 0x151e: 0x7ef5, 0x151f: 0xaf6a, 0x1520: 0xaf7a, 0x1521: 0xaf8a, 0x1522: 0x1fb2, 0x1523: 0xaf99,
1572 0x1524: 0xafaa, 0x1525: 0xafba, 0x1526: 0x1fc2, 0x1527: 0x0040, 0x1528: 0xafca, 0x1529: 0xafda,
1573 0x152a: 0xafea, 0x152b: 0xaffa, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,
1574 0x1530: 0x7fd6, 0x1531: 0xb009, 0x1532: 0x7ff6, 0x1533: 0x0008, 0x1534: 0x8016, 0x1535: 0x0040,
1575 0x1536: 0x8036, 0x1537: 0xb031, 0x1538: 0x8056, 0x1539: 0xb059, 0x153a: 0x8076, 0x153b: 0xb081,
1576 0x153c: 0x8096, 0x153d: 0xb0a9, 0x153e: 0x80b6, 0x153f: 0xb0d1,
1577 // Block 0x55, offset 0x1540
1578 0x1540: 0xb0f9, 0x1541: 0xb111, 0x1542: 0xb111, 0x1543: 0xb129, 0x1544: 0xb129, 0x1545: 0xb141,
1579 0x1546: 0xb141, 0x1547: 0xb159, 0x1548: 0xb159, 0x1549: 0xb171, 0x154a: 0xb171, 0x154b: 0xb171,
1580 0x154c: 0xb171, 0x154d: 0xb189, 0x154e: 0xb189, 0x154f: 0xb1a1, 0x1550: 0xb1a1, 0x1551: 0xb1a1,
1581 0x1552: 0xb1a1, 0x1553: 0xb1b9, 0x1554: 0xb1b9, 0x1555: 0xb1d1, 0x1556: 0xb1d1, 0x1557: 0xb1d1,
1582 0x1558: 0xb1d1, 0x1559: 0xb1e9, 0x155a: 0xb1e9, 0x155b: 0xb1e9, 0x155c: 0xb1e9, 0x155d: 0xb201,
1583 0x155e: 0xb201, 0x155f: 0xb201, 0x1560: 0xb201, 0x1561: 0xb219, 0x1562: 0xb219, 0x1563: 0xb219,
1584 0x1564: 0xb219, 0x1565: 0xb231, 0x1566: 0xb231, 0x1567: 0xb231, 0x1568: 0xb231, 0x1569: 0xb249,
1585 0x156a: 0xb249, 0x156b: 0xb261, 0x156c: 0xb261, 0x156d: 0xb279, 0x156e: 0xb279, 0x156f: 0xb291,
1586 0x1570: 0xb291, 0x1571: 0xb2a9, 0x1572: 0xb2a9, 0x1573: 0xb2a9, 0x1574: 0xb2a9, 0x1575: 0xb2c1,
1587 0x1576: 0xb2c1, 0x1577: 0xb2c1, 0x1578: 0xb2c1, 0x1579: 0xb2d9, 0x157a: 0xb2d9, 0x157b: 0xb2d9,
1588 0x157c: 0xb2d9, 0x157d: 0xb2f1, 0x157e: 0xb2f1, 0x157f: 0xb2f1,
1589 // Block 0x56, offset 0x1580
1590 0x1580: 0xb2f1, 0x1581: 0xb309, 0x1582: 0xb309, 0x1583: 0xb309, 0x1584: 0xb309, 0x1585: 0xb321,
1591 0x1586: 0xb321, 0x1587: 0xb321, 0x1588: 0xb321, 0x1589: 0xb339, 0x158a: 0xb339, 0x158b: 0xb339,
1592 0x158c: 0xb339, 0x158d: 0xb351, 0x158e: 0xb351, 0x158f: 0xb351, 0x1590: 0xb351, 0x1591: 0xb369,
1593 0x1592: 0xb369, 0x1593: 0xb369, 0x1594: 0xb369, 0x1595: 0xb381, 0x1596: 0xb381, 0x1597: 0xb381,
1594 0x1598: 0xb381, 0x1599: 0xb399, 0x159a: 0xb399, 0x159b: 0xb399, 0x159c: 0xb399, 0x159d: 0xb3b1,
1595 0x159e: 0xb3b1, 0x159f: 0xb3b1, 0x15a0: 0xb3b1, 0x15a1: 0xb3c9, 0x15a2: 0xb3c9, 0x15a3: 0xb3c9,
1596 0x15a4: 0xb3c9, 0x15a5: 0xb3e1, 0x15a6: 0xb3e1, 0x15a7: 0xb3e1, 0x15a8: 0xb3e1, 0x15a9: 0xb3f9,
1597 0x15aa: 0xb3f9, 0x15ab: 0xb3f9, 0x15ac: 0xb3f9, 0x15ad: 0xb411, 0x15ae: 0xb411, 0x15af: 0x7ab1,
1598 0x15b0: 0x7ab1, 0x15b1: 0xb429, 0x15b2: 0xb429, 0x15b3: 0xb429, 0x15b4: 0xb429, 0x15b5: 0xb441,
1599 0x15b6: 0xb441, 0x15b7: 0xb469, 0x15b8: 0xb469, 0x15b9: 0xb491, 0x15ba: 0xb491, 0x15bb: 0xb4b9,
1600 0x15bc: 0xb4b9, 0x15bd: 0x0040, 0x15be: 0x0040, 0x15bf: 0x03c0,
1601 // Block 0x57, offset 0x15c0
1602 0x15c0: 0x0040, 0x15c1: 0xaefa, 0x15c2: 0xb4e2, 0x15c3: 0xaf6a, 0x15c4: 0xafda, 0x15c5: 0xafea,
1603 0x15c6: 0xaf7a, 0x15c7: 0xb4f2, 0x15c8: 0x1fd2, 0x15c9: 0x1fe2, 0x15ca: 0xaf8a, 0x15cb: 0x1fb2,
1604 0x15cc: 0xaeda, 0x15cd: 0xaf99, 0x15ce: 0x29d1, 0x15cf: 0xb502, 0x15d0: 0x1f41, 0x15d1: 0x00c9,
1605 0x15d2: 0x0069, 0x15d3: 0x0079, 0x15d4: 0x1f51, 0x15d5: 0x1f61, 0x15d6: 0x1f71, 0x15d7: 0x1f81,
1606 0x15d8: 0x1f91, 0x15d9: 0x1fa1, 0x15da: 0xaeea, 0x15db: 0x03c2, 0x15dc: 0xafaa, 0x15dd: 0x1fc2,
1607 0x15de: 0xafba, 0x15df: 0xaf0a, 0x15e0: 0xaffa, 0x15e1: 0x0039, 0x15e2: 0x0ee9, 0x15e3: 0x1159,
1608 0x15e4: 0x0ef9, 0x15e5: 0x0f09, 0x15e6: 0x1199, 0x15e7: 0x0f31, 0x15e8: 0x0249, 0x15e9: 0x0f41,
1609 0x15ea: 0x0259, 0x15eb: 0x0f51, 0x15ec: 0x0359, 0x15ed: 0x0f61, 0x15ee: 0x0f71, 0x15ef: 0x00d9,
1610 0x15f0: 0x0f99, 0x15f1: 0x2039, 0x15f2: 0x0269, 0x15f3: 0x01d9, 0x15f4: 0x0fa9, 0x15f5: 0x0fb9,
1611 0x15f6: 0x1089, 0x15f7: 0x0279, 0x15f8: 0x0369, 0x15f9: 0x0289, 0x15fa: 0x13d1, 0x15fb: 0xaf4a,
1612 0x15fc: 0xafca, 0x15fd: 0xaf5a, 0x15fe: 0xb512, 0x15ff: 0xaf1a,
1613 // Block 0x58, offset 0x1600
1614 0x1600: 0x1caa, 0x1601: 0x0039, 0x1602: 0x0ee9, 0x1603: 0x1159, 0x1604: 0x0ef9, 0x1605: 0x0f09,
1615 0x1606: 0x1199, 0x1607: 0x0f31, 0x1608: 0x0249, 0x1609: 0x0f41, 0x160a: 0x0259, 0x160b: 0x0f51,
1616 0x160c: 0x0359, 0x160d: 0x0f61, 0x160e: 0x0f71, 0x160f: 0x00d9, 0x1610: 0x0f99, 0x1611: 0x2039,
1617 0x1612: 0x0269, 0x1613: 0x01d9, 0x1614: 0x0fa9, 0x1615: 0x0fb9, 0x1616: 0x1089, 0x1617: 0x0279,
1618 0x1618: 0x0369, 0x1619: 0x0289, 0x161a: 0x13d1, 0x161b: 0xaf2a, 0x161c: 0xb522, 0x161d: 0xaf3a,
1619 0x161e: 0xb532, 0x161f: 0x80d5, 0x1620: 0x80f5, 0x1621: 0x29d1, 0x1622: 0x8115, 0x1623: 0x8115,
1620 0x1624: 0x8135, 0x1625: 0x8155, 0x1626: 0x8175, 0x1627: 0x8195, 0x1628: 0x81b5, 0x1629: 0x81d5,
1621 0x162a: 0x81f5, 0x162b: 0x8215, 0x162c: 0x8235, 0x162d: 0x8255, 0x162e: 0x8275, 0x162f: 0x8295,
1622 0x1630: 0x82b5, 0x1631: 0x82d5, 0x1632: 0x82f5, 0x1633: 0x8315, 0x1634: 0x8335, 0x1635: 0x8355,
1623 0x1636: 0x8375, 0x1637: 0x8395, 0x1638: 0x83b5, 0x1639: 0x83d5, 0x163a: 0x83f5, 0x163b: 0x8415,
1624 0x163c: 0x81b5, 0x163d: 0x8435, 0x163e: 0x8455, 0x163f: 0x8215,
1625 // Block 0x59, offset 0x1640
1626 0x1640: 0x8475, 0x1641: 0x8495, 0x1642: 0x84b5, 0x1643: 0x84d5, 0x1644: 0x84f5, 0x1645: 0x8515,
1627 0x1646: 0x8535, 0x1647: 0x8555, 0x1648: 0x84d5, 0x1649: 0x8575, 0x164a: 0x84d5, 0x164b: 0x8595,
1628 0x164c: 0x8595, 0x164d: 0x85b5, 0x164e: 0x85b5, 0x164f: 0x85d5, 0x1650: 0x8515, 0x1651: 0x85f5,
1629 0x1652: 0x8615, 0x1653: 0x85f5, 0x1654: 0x8635, 0x1655: 0x8615, 0x1656: 0x8655, 0x1657: 0x8655,
1630 0x1658: 0x8675, 0x1659: 0x8675, 0x165a: 0x8695, 0x165b: 0x8695, 0x165c: 0x8615, 0x165d: 0x8115,
1631 0x165e: 0x86b5, 0x165f: 0x86d5, 0x1660: 0x0040, 0x1661: 0x86f5, 0x1662: 0x8715, 0x1663: 0x8735,
1632 0x1664: 0x8755, 0x1665: 0x8735, 0x1666: 0x8775, 0x1667: 0x8795, 0x1668: 0x87b5, 0x1669: 0x87b5,
1633 0x166a: 0x87d5, 0x166b: 0x87d5, 0x166c: 0x87f5, 0x166d: 0x87f5, 0x166e: 0x87d5, 0x166f: 0x87d5,
1634 0x1670: 0x8815, 0x1671: 0x8835, 0x1672: 0x8855, 0x1673: 0x8875, 0x1674: 0x8895, 0x1675: 0x88b5,
1635 0x1676: 0x88b5, 0x1677: 0x88b5, 0x1678: 0x88d5, 0x1679: 0x88d5, 0x167a: 0x88d5, 0x167b: 0x88d5,
1636 0x167c: 0x87b5, 0x167d: 0x87b5, 0x167e: 0x87b5, 0x167f: 0x0040,
1637 // Block 0x5a, offset 0x1680
1638 0x1680: 0x0040, 0x1681: 0x0040, 0x1682: 0x8715, 0x1683: 0x86f5, 0x1684: 0x88f5, 0x1685: 0x86f5,
1639 0x1686: 0x8715, 0x1687: 0x86f5, 0x1688: 0x0040, 0x1689: 0x0040, 0x168a: 0x8915, 0x168b: 0x8715,
1640 0x168c: 0x8935, 0x168d: 0x88f5, 0x168e: 0x8935, 0x168f: 0x8715, 0x1690: 0x0040, 0x1691: 0x0040,
1641 0x1692: 0x8955, 0x1693: 0x8975, 0x1694: 0x8875, 0x1695: 0x8935, 0x1696: 0x88f5, 0x1697: 0x8935,
1642 0x1698: 0x0040, 0x1699: 0x0040, 0x169a: 0x8995, 0x169b: 0x89b5, 0x169c: 0x8995, 0x169d: 0x0040,
1643 0x169e: 0x0040, 0x169f: 0x0040, 0x16a0: 0xb541, 0x16a1: 0xb559, 0x16a2: 0xb571, 0x16a3: 0x89d6,
1644 0x16a4: 0xb589, 0x16a5: 0xb5a1, 0x16a6: 0x89f5, 0x16a7: 0x0040, 0x16a8: 0x8a15, 0x16a9: 0x8a35,
1645 0x16aa: 0x8a55, 0x16ab: 0x8a35, 0x16ac: 0x8a75, 0x16ad: 0x8a95, 0x16ae: 0x8ab5, 0x16af: 0x0040,
1646 0x16b0: 0x0040, 0x16b1: 0x0040, 0x16b2: 0x0040, 0x16b3: 0x0040, 0x16b4: 0x0040, 0x16b5: 0x0040,
1647 0x16b6: 0x0040, 0x16b7: 0x0040, 0x16b8: 0x0040, 0x16b9: 0x0340, 0x16ba: 0x0340, 0x16bb: 0x0340,
1648 0x16bc: 0x0040, 0x16bd: 0x0040, 0x16be: 0x0040, 0x16bf: 0x0040,
1649 // Block 0x5b, offset 0x16c0
1650 0x16c0: 0x0208, 0x16c1: 0x0208, 0x16c2: 0x0208, 0x16c3: 0x0208, 0x16c4: 0x0208, 0x16c5: 0x0408,
1651 0x16c6: 0x0008, 0x16c7: 0x0408, 0x16c8: 0x0018, 0x16c9: 0x0408, 0x16ca: 0x0408, 0x16cb: 0x0008,
1652 0x16cc: 0x0008, 0x16cd: 0x0108, 0x16ce: 0x0408, 0x16cf: 0x0408, 0x16d0: 0x0408, 0x16d1: 0x0408,
1653 0x16d2: 0x0408, 0x16d3: 0x0208, 0x16d4: 0x0208, 0x16d5: 0x0208, 0x16d6: 0x0208, 0x16d7: 0x0108,
1654 0x16d8: 0x0208, 0x16d9: 0x0208, 0x16da: 0x0208, 0x16db: 0x0208, 0x16dc: 0x0208, 0x16dd: 0x0408,
1655 0x16de: 0x0208, 0x16df: 0x0208, 0x16e0: 0x0208, 0x16e1: 0x0408, 0x16e2: 0x0008, 0x16e3: 0x0008,
1656 0x16e4: 0x0408, 0x16e5: 0x1308, 0x16e6: 0x1308, 0x16e7: 0x0040, 0x16e8: 0x0040, 0x16e9: 0x0040,
1657 0x16ea: 0x0040, 0x16eb: 0x0218, 0x16ec: 0x0218, 0x16ed: 0x0218, 0x16ee: 0x0218, 0x16ef: 0x0418,
1658 0x16f0: 0x0018, 0x16f1: 0x0018, 0x16f2: 0x0018, 0x16f3: 0x0018, 0x16f4: 0x0018, 0x16f5: 0x0018,
1659 0x16f6: 0x0018, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0040, 0x16fa: 0x0040, 0x16fb: 0x0040,
1660 0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040,
1661 // Block 0x5c, offset 0x1700
1662 0x1700: 0x0208, 0x1701: 0x0408, 0x1702: 0x0208, 0x1703: 0x0408, 0x1704: 0x0408, 0x1705: 0x0408,
1663 0x1706: 0x0208, 0x1707: 0x0208, 0x1708: 0x0208, 0x1709: 0x0408, 0x170a: 0x0208, 0x170b: 0x0208,
1664 0x170c: 0x0408, 0x170d: 0x0208, 0x170e: 0x0408, 0x170f: 0x0408, 0x1710: 0x0208, 0x1711: 0x0408,
1665 0x1712: 0x0040, 0x1713: 0x0040, 0x1714: 0x0040, 0x1715: 0x0040, 0x1716: 0x0040, 0x1717: 0x0040,
1666 0x1718: 0x0040, 0x1719: 0x0018, 0x171a: 0x0018, 0x171b: 0x0018, 0x171c: 0x0018, 0x171d: 0x0040,
1667 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0x0040, 0x1721: 0x0040, 0x1722: 0x0040, 0x1723: 0x0040,
1668 0x1724: 0x0040, 0x1725: 0x0040, 0x1726: 0x0040, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0418,
1669 0x172a: 0x0418, 0x172b: 0x0418, 0x172c: 0x0418, 0x172d: 0x0218, 0x172e: 0x0218, 0x172f: 0x0018,
1670 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,
1671 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040,
1672 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,
1673 // Block 0x5d, offset 0x1740
1674 0x1740: 0x1308, 0x1741: 0x1308, 0x1742: 0x1008, 0x1743: 0x1008, 0x1744: 0x0040, 0x1745: 0x0008,
1675 0x1746: 0x0008, 0x1747: 0x0008, 0x1748: 0x0008, 0x1749: 0x0008, 0x174a: 0x0008, 0x174b: 0x0008,
1676 0x174c: 0x0008, 0x174d: 0x0040, 0x174e: 0x0040, 0x174f: 0x0008, 0x1750: 0x0008, 0x1751: 0x0040,
1677 0x1752: 0x0040, 0x1753: 0x0008, 0x1754: 0x0008, 0x1755: 0x0008, 0x1756: 0x0008, 0x1757: 0x0008,
1678 0x1758: 0x0008, 0x1759: 0x0008, 0x175a: 0x0008, 0x175b: 0x0008, 0x175c: 0x0008, 0x175d: 0x0008,
1679 0x175e: 0x0008, 0x175f: 0x0008, 0x1760: 0x0008, 0x1761: 0x0008, 0x1762: 0x0008, 0x1763: 0x0008,
1680 0x1764: 0x0008, 0x1765: 0x0008, 0x1766: 0x0008, 0x1767: 0x0008, 0x1768: 0x0008, 0x1769: 0x0040,
1681 0x176a: 0x0008, 0x176b: 0x0008, 0x176c: 0x0008, 0x176d: 0x0008, 0x176e: 0x0008, 0x176f: 0x0008,
1682 0x1770: 0x0008, 0x1771: 0x0040, 0x1772: 0x0008, 0x1773: 0x0008, 0x1774: 0x0040, 0x1775: 0x0008,
1683 0x1776: 0x0008, 0x1777: 0x0008, 0x1778: 0x0008, 0x1779: 0x0008, 0x177a: 0x0040, 0x177b: 0x0040,
1684 0x177c: 0x1308, 0x177d: 0x0008, 0x177e: 0x1008, 0x177f: 0x1008,
1685 // Block 0x5e, offset 0x1780
1686 0x1780: 0x1308, 0x1781: 0x1008, 0x1782: 0x1008, 0x1783: 0x1008, 0x1784: 0x1008, 0x1785: 0x0040,
1687 0x1786: 0x0040, 0x1787: 0x1008, 0x1788: 0x1008, 0x1789: 0x0040, 0x178a: 0x0040, 0x178b: 0x1008,
1688 0x178c: 0x1008, 0x178d: 0x1808, 0x178e: 0x0040, 0x178f: 0x0040, 0x1790: 0x0008, 0x1791: 0x0040,
1689 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x1008,
1690 0x1798: 0x0040, 0x1799: 0x0040, 0x179a: 0x0040, 0x179b: 0x0040, 0x179c: 0x0040, 0x179d: 0x0008,
1691 0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x1008, 0x17a3: 0x1008,
1692 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x1308, 0x17a7: 0x1308, 0x17a8: 0x1308, 0x17a9: 0x1308,
1693 0x17aa: 0x1308, 0x17ab: 0x1308, 0x17ac: 0x1308, 0x17ad: 0x0040, 0x17ae: 0x0040, 0x17af: 0x0040,
1694 0x17b0: 0x1308, 0x17b1: 0x1308, 0x17b2: 0x1308, 0x17b3: 0x1308, 0x17b4: 0x1308, 0x17b5: 0x0040,
1695 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,
1696 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,
1697 // Block 0x5f, offset 0x17c0
1698 0x17c0: 0x0039, 0x17c1: 0x0ee9, 0x17c2: 0x1159, 0x17c3: 0x0ef9, 0x17c4: 0x0f09, 0x17c5: 0x1199,
1699 0x17c6: 0x0f31, 0x17c7: 0x0249, 0x17c8: 0x0f41, 0x17c9: 0x0259, 0x17ca: 0x0f51, 0x17cb: 0x0359,
1700 0x17cc: 0x0f61, 0x17cd: 0x0f71, 0x17ce: 0x00d9, 0x17cf: 0x0f99, 0x17d0: 0x2039, 0x17d1: 0x0269,
1701 0x17d2: 0x01d9, 0x17d3: 0x0fa9, 0x17d4: 0x0fb9, 0x17d5: 0x1089, 0x17d6: 0x0279, 0x17d7: 0x0369,
1702 0x17d8: 0x0289, 0x17d9: 0x13d1, 0x17da: 0x0039, 0x17db: 0x0ee9, 0x17dc: 0x1159, 0x17dd: 0x0ef9,
1703 0x17de: 0x0f09, 0x17df: 0x1199, 0x17e0: 0x0f31, 0x17e1: 0x0249, 0x17e2: 0x0f41, 0x17e3: 0x0259,
1704 0x17e4: 0x0f51, 0x17e5: 0x0359, 0x17e6: 0x0f61, 0x17e7: 0x0f71, 0x17e8: 0x00d9, 0x17e9: 0x0f99,
1705 0x17ea: 0x2039, 0x17eb: 0x0269, 0x17ec: 0x01d9, 0x17ed: 0x0fa9, 0x17ee: 0x0fb9, 0x17ef: 0x1089,
1706 0x17f0: 0x0279, 0x17f1: 0x0369, 0x17f2: 0x0289, 0x17f3: 0x13d1, 0x17f4: 0x0039, 0x17f5: 0x0ee9,
1707 0x17f6: 0x1159, 0x17f7: 0x0ef9, 0x17f8: 0x0f09, 0x17f9: 0x1199, 0x17fa: 0x0f31, 0x17fb: 0x0249,
1708 0x17fc: 0x0f41, 0x17fd: 0x0259, 0x17fe: 0x0f51, 0x17ff: 0x0359,
1709 // Block 0x60, offset 0x1800
1710 0x1800: 0x0f61, 0x1801: 0x0f71, 0x1802: 0x00d9, 0x1803: 0x0f99, 0x1804: 0x2039, 0x1805: 0x0269,
1711 0x1806: 0x01d9, 0x1807: 0x0fa9, 0x1808: 0x0fb9, 0x1809: 0x1089, 0x180a: 0x0279, 0x180b: 0x0369,
1712 0x180c: 0x0289, 0x180d: 0x13d1, 0x180e: 0x0039, 0x180f: 0x0ee9, 0x1810: 0x1159, 0x1811: 0x0ef9,
1713 0x1812: 0x0f09, 0x1813: 0x1199, 0x1814: 0x0f31, 0x1815: 0x0040, 0x1816: 0x0f41, 0x1817: 0x0259,
1714 0x1818: 0x0f51, 0x1819: 0x0359, 0x181a: 0x0f61, 0x181b: 0x0f71, 0x181c: 0x00d9, 0x181d: 0x0f99,
1715 0x181e: 0x2039, 0x181f: 0x0269, 0x1820: 0x01d9, 0x1821: 0x0fa9, 0x1822: 0x0fb9, 0x1823: 0x1089,
1716 0x1824: 0x0279, 0x1825: 0x0369, 0x1826: 0x0289, 0x1827: 0x13d1, 0x1828: 0x0039, 0x1829: 0x0ee9,
1717 0x182a: 0x1159, 0x182b: 0x0ef9, 0x182c: 0x0f09, 0x182d: 0x1199, 0x182e: 0x0f31, 0x182f: 0x0249,
1718 0x1830: 0x0f41, 0x1831: 0x0259, 0x1832: 0x0f51, 0x1833: 0x0359, 0x1834: 0x0f61, 0x1835: 0x0f71,
1719 0x1836: 0x00d9, 0x1837: 0x0f99, 0x1838: 0x2039, 0x1839: 0x0269, 0x183a: 0x01d9, 0x183b: 0x0fa9,
1720 0x183c: 0x0fb9, 0x183d: 0x1089, 0x183e: 0x0279, 0x183f: 0x0369,
1721 // Block 0x61, offset 0x1840
1722 0x1840: 0x0289, 0x1841: 0x13d1, 0x1842: 0x0039, 0x1843: 0x0ee9, 0x1844: 0x1159, 0x1845: 0x0ef9,
1723 0x1846: 0x0f09, 0x1847: 0x1199, 0x1848: 0x0f31, 0x1849: 0x0249, 0x184a: 0x0f41, 0x184b: 0x0259,
1724 0x184c: 0x0f51, 0x184d: 0x0359, 0x184e: 0x0f61, 0x184f: 0x0f71, 0x1850: 0x00d9, 0x1851: 0x0f99,
1725 0x1852: 0x2039, 0x1853: 0x0269, 0x1854: 0x01d9, 0x1855: 0x0fa9, 0x1856: 0x0fb9, 0x1857: 0x1089,
1726 0x1858: 0x0279, 0x1859: 0x0369, 0x185a: 0x0289, 0x185b: 0x13d1, 0x185c: 0x0039, 0x185d: 0x0040,
1727 0x185e: 0x1159, 0x185f: 0x0ef9, 0x1860: 0x0040, 0x1861: 0x0040, 0x1862: 0x0f31, 0x1863: 0x0040,
1728 0x1864: 0x0040, 0x1865: 0x0259, 0x1866: 0x0f51, 0x1867: 0x0040, 0x1868: 0x0040, 0x1869: 0x0f71,
1729 0x186a: 0x00d9, 0x186b: 0x0f99, 0x186c: 0x2039, 0x186d: 0x0040, 0x186e: 0x01d9, 0x186f: 0x0fa9,
1730 0x1870: 0x0fb9, 0x1871: 0x1089, 0x1872: 0x0279, 0x1873: 0x0369, 0x1874: 0x0289, 0x1875: 0x13d1,
1731 0x1876: 0x0039, 0x1877: 0x0ee9, 0x1878: 0x1159, 0x1879: 0x0ef9, 0x187a: 0x0040, 0x187b: 0x1199,
1732 0x187c: 0x0040, 0x187d: 0x0249, 0x187e: 0x0f41, 0x187f: 0x0259,
1733 // Block 0x62, offset 0x1880
1734 0x1880: 0x0f51, 0x1881: 0x0359, 0x1882: 0x0f61, 0x1883: 0x0f71, 0x1884: 0x0040, 0x1885: 0x0f99,
1735 0x1886: 0x2039, 0x1887: 0x0269, 0x1888: 0x01d9, 0x1889: 0x0fa9, 0x188a: 0x0fb9, 0x188b: 0x1089,
1736 0x188c: 0x0279, 0x188d: 0x0369, 0x188e: 0x0289, 0x188f: 0x13d1, 0x1890: 0x0039, 0x1891: 0x0ee9,
1737 0x1892: 0x1159, 0x1893: 0x0ef9, 0x1894: 0x0f09, 0x1895: 0x1199, 0x1896: 0x0f31, 0x1897: 0x0249,
1738 0x1898: 0x0f41, 0x1899: 0x0259, 0x189a: 0x0f51, 0x189b: 0x0359, 0x189c: 0x0f61, 0x189d: 0x0f71,
1739 0x189e: 0x00d9, 0x189f: 0x0f99, 0x18a0: 0x2039, 0x18a1: 0x0269, 0x18a2: 0x01d9, 0x18a3: 0x0fa9,
1740 0x18a4: 0x0fb9, 0x18a5: 0x1089, 0x18a6: 0x0279, 0x18a7: 0x0369, 0x18a8: 0x0289, 0x18a9: 0x13d1,
1741 0x18aa: 0x0039, 0x18ab: 0x0ee9, 0x18ac: 0x1159, 0x18ad: 0x0ef9, 0x18ae: 0x0f09, 0x18af: 0x1199,
1742 0x18b0: 0x0f31, 0x18b1: 0x0249, 0x18b2: 0x0f41, 0x18b3: 0x0259, 0x18b4: 0x0f51, 0x18b5: 0x0359,
1743 0x18b6: 0x0f61, 0x18b7: 0x0f71, 0x18b8: 0x00d9, 0x18b9: 0x0f99, 0x18ba: 0x2039, 0x18bb: 0x0269,
1744 0x18bc: 0x01d9, 0x18bd: 0x0fa9, 0x18be: 0x0fb9, 0x18bf: 0x1089,
1745 // Block 0x63, offset 0x18c0
1746 0x18c0: 0x0279, 0x18c1: 0x0369, 0x18c2: 0x0289, 0x18c3: 0x13d1, 0x18c4: 0x0039, 0x18c5: 0x0ee9,
1747 0x18c6: 0x0040, 0x18c7: 0x0ef9, 0x18c8: 0x0f09, 0x18c9: 0x1199, 0x18ca: 0x0f31, 0x18cb: 0x0040,
1748 0x18cc: 0x0040, 0x18cd: 0x0259, 0x18ce: 0x0f51, 0x18cf: 0x0359, 0x18d0: 0x0f61, 0x18d1: 0x0f71,
1749 0x18d2: 0x00d9, 0x18d3: 0x0f99, 0x18d4: 0x2039, 0x18d5: 0x0040, 0x18d6: 0x01d9, 0x18d7: 0x0fa9,
1750 0x18d8: 0x0fb9, 0x18d9: 0x1089, 0x18da: 0x0279, 0x18db: 0x0369, 0x18dc: 0x0289, 0x18dd: 0x0040,
1751 0x18de: 0x0039, 0x18df: 0x0ee9, 0x18e0: 0x1159, 0x18e1: 0x0ef9, 0x18e2: 0x0f09, 0x18e3: 0x1199,
1752 0x18e4: 0x0f31, 0x18e5: 0x0249, 0x18e6: 0x0f41, 0x18e7: 0x0259, 0x18e8: 0x0f51, 0x18e9: 0x0359,
1753 0x18ea: 0x0f61, 0x18eb: 0x0f71, 0x18ec: 0x00d9, 0x18ed: 0x0f99, 0x18ee: 0x2039, 0x18ef: 0x0269,
1754 0x18f0: 0x01d9, 0x18f1: 0x0fa9, 0x18f2: 0x0fb9, 0x18f3: 0x1089, 0x18f4: 0x0279, 0x18f5: 0x0369,
1755 0x18f6: 0x0289, 0x18f7: 0x13d1, 0x18f8: 0x0039, 0x18f9: 0x0ee9, 0x18fa: 0x0040, 0x18fb: 0x0ef9,
1756 0x18fc: 0x0f09, 0x18fd: 0x1199, 0x18fe: 0x0f31, 0x18ff: 0x0040,
1757 // Block 0x64, offset 0x1900
1758 0x1900: 0x0f41, 0x1901: 0x0259, 0x1902: 0x0f51, 0x1903: 0x0359, 0x1904: 0x0f61, 0x1905: 0x0040,
1759 0x1906: 0x00d9, 0x1907: 0x0040, 0x1908: 0x0040, 0x1909: 0x0040, 0x190a: 0x01d9, 0x190b: 0x0fa9,
1760 0x190c: 0x0fb9, 0x190d: 0x1089, 0x190e: 0x0279, 0x190f: 0x0369, 0x1910: 0x0289, 0x1911: 0x0040,
1761 0x1912: 0x0039, 0x1913: 0x0ee9, 0x1914: 0x1159, 0x1915: 0x0ef9, 0x1916: 0x0f09, 0x1917: 0x1199,
1762 0x1918: 0x0f31, 0x1919: 0x0249, 0x191a: 0x0f41, 0x191b: 0x0259, 0x191c: 0x0f51, 0x191d: 0x0359,
1763 0x191e: 0x0f61, 0x191f: 0x0f71, 0x1920: 0x00d9, 0x1921: 0x0f99, 0x1922: 0x2039, 0x1923: 0x0269,
1764 0x1924: 0x01d9, 0x1925: 0x0fa9, 0x1926: 0x0fb9, 0x1927: 0x1089, 0x1928: 0x0279, 0x1929: 0x0369,
1765 0x192a: 0x0289, 0x192b: 0x13d1, 0x192c: 0x0039, 0x192d: 0x0ee9, 0x192e: 0x1159, 0x192f: 0x0ef9,
1766 0x1930: 0x0f09, 0x1931: 0x1199, 0x1932: 0x0f31, 0x1933: 0x0249, 0x1934: 0x0f41, 0x1935: 0x0259,
1767 0x1936: 0x0f51, 0x1937: 0x0359, 0x1938: 0x0f61, 0x1939: 0x0f71, 0x193a: 0x00d9, 0x193b: 0x0f99,
1768 0x193c: 0x2039, 0x193d: 0x0269, 0x193e: 0x01d9, 0x193f: 0x0fa9,
1769 // Block 0x65, offset 0x1940
1770 0x1940: 0x0fb9, 0x1941: 0x1089, 0x1942: 0x0279, 0x1943: 0x0369, 0x1944: 0x0289, 0x1945: 0x13d1,
1771 0x1946: 0x0039, 0x1947: 0x0ee9, 0x1948: 0x1159, 0x1949: 0x0ef9, 0x194a: 0x0f09, 0x194b: 0x1199,
1772 0x194c: 0x0f31, 0x194d: 0x0249, 0x194e: 0x0f41, 0x194f: 0x0259, 0x1950: 0x0f51, 0x1951: 0x0359,
1773 0x1952: 0x0f61, 0x1953: 0x0f71, 0x1954: 0x00d9, 0x1955: 0x0f99, 0x1956: 0x2039, 0x1957: 0x0269,
1774 0x1958: 0x01d9, 0x1959: 0x0fa9, 0x195a: 0x0fb9, 0x195b: 0x1089, 0x195c: 0x0279, 0x195d: 0x0369,
1775 0x195e: 0x0289, 0x195f: 0x13d1, 0x1960: 0x0039, 0x1961: 0x0ee9, 0x1962: 0x1159, 0x1963: 0x0ef9,
1776 0x1964: 0x0f09, 0x1965: 0x1199, 0x1966: 0x0f31, 0x1967: 0x0249, 0x1968: 0x0f41, 0x1969: 0x0259,
1777 0x196a: 0x0f51, 0x196b: 0x0359, 0x196c: 0x0f61, 0x196d: 0x0f71, 0x196e: 0x00d9, 0x196f: 0x0f99,
1778 0x1970: 0x2039, 0x1971: 0x0269, 0x1972: 0x01d9, 0x1973: 0x0fa9, 0x1974: 0x0fb9, 0x1975: 0x1089,
1779 0x1976: 0x0279, 0x1977: 0x0369, 0x1978: 0x0289, 0x1979: 0x13d1, 0x197a: 0x0039, 0x197b: 0x0ee9,
1780 0x197c: 0x1159, 0x197d: 0x0ef9, 0x197e: 0x0f09, 0x197f: 0x1199,
1781 // Block 0x66, offset 0x1980
1782 0x1980: 0x0f31, 0x1981: 0x0249, 0x1982: 0x0f41, 0x1983: 0x0259, 0x1984: 0x0f51, 0x1985: 0x0359,
1783 0x1986: 0x0f61, 0x1987: 0x0f71, 0x1988: 0x00d9, 0x1989: 0x0f99, 0x198a: 0x2039, 0x198b: 0x0269,
1784 0x198c: 0x01d9, 0x198d: 0x0fa9, 0x198e: 0x0fb9, 0x198f: 0x1089, 0x1990: 0x0279, 0x1991: 0x0369,
1785 0x1992: 0x0289, 0x1993: 0x13d1, 0x1994: 0x0039, 0x1995: 0x0ee9, 0x1996: 0x1159, 0x1997: 0x0ef9,
1786 0x1998: 0x0f09, 0x1999: 0x1199, 0x199a: 0x0f31, 0x199b: 0x0249, 0x199c: 0x0f41, 0x199d: 0x0259,
1787 0x199e: 0x0f51, 0x199f: 0x0359, 0x19a0: 0x0f61, 0x19a1: 0x0f71, 0x19a2: 0x00d9, 0x19a3: 0x0f99,
1788 0x19a4: 0x2039, 0x19a5: 0x0269, 0x19a6: 0x01d9, 0x19a7: 0x0fa9, 0x19a8: 0x0fb9, 0x19a9: 0x1089,
1789 0x19aa: 0x0279, 0x19ab: 0x0369, 0x19ac: 0x0289, 0x19ad: 0x13d1, 0x19ae: 0x0039, 0x19af: 0x0ee9,
1790 0x19b0: 0x1159, 0x19b1: 0x0ef9, 0x19b2: 0x0f09, 0x19b3: 0x1199, 0x19b4: 0x0f31, 0x19b5: 0x0249,
1791 0x19b6: 0x0f41, 0x19b7: 0x0259, 0x19b8: 0x0f51, 0x19b9: 0x0359, 0x19ba: 0x0f61, 0x19bb: 0x0f71,
1792 0x19bc: 0x00d9, 0x19bd: 0x0f99, 0x19be: 0x2039, 0x19bf: 0x0269,
1793 // Block 0x67, offset 0x19c0
1794 0x19c0: 0x01d9, 0x19c1: 0x0fa9, 0x19c2: 0x0fb9, 0x19c3: 0x1089, 0x19c4: 0x0279, 0x19c5: 0x0369,
1795 0x19c6: 0x0289, 0x19c7: 0x13d1, 0x19c8: 0x0039, 0x19c9: 0x0ee9, 0x19ca: 0x1159, 0x19cb: 0x0ef9,
1796 0x19cc: 0x0f09, 0x19cd: 0x1199, 0x19ce: 0x0f31, 0x19cf: 0x0249, 0x19d0: 0x0f41, 0x19d1: 0x0259,
1797 0x19d2: 0x0f51, 0x19d3: 0x0359, 0x19d4: 0x0f61, 0x19d5: 0x0f71, 0x19d6: 0x00d9, 0x19d7: 0x0f99,
1798 0x19d8: 0x2039, 0x19d9: 0x0269, 0x19da: 0x01d9, 0x19db: 0x0fa9, 0x19dc: 0x0fb9, 0x19dd: 0x1089,
1799 0x19de: 0x0279, 0x19df: 0x0369, 0x19e0: 0x0289, 0x19e1: 0x13d1, 0x19e2: 0x0039, 0x19e3: 0x0ee9,
1800 0x19e4: 0x1159, 0x19e5: 0x0ef9, 0x19e6: 0x0f09, 0x19e7: 0x1199, 0x19e8: 0x0f31, 0x19e9: 0x0249,
1801 0x19ea: 0x0f41, 0x19eb: 0x0259, 0x19ec: 0x0f51, 0x19ed: 0x0359, 0x19ee: 0x0f61, 0x19ef: 0x0f71,
1802 0x19f0: 0x00d9, 0x19f1: 0x0f99, 0x19f2: 0x2039, 0x19f3: 0x0269, 0x19f4: 0x01d9, 0x19f5: 0x0fa9,
1803 0x19f6: 0x0fb9, 0x19f7: 0x1089, 0x19f8: 0x0279, 0x19f9: 0x0369, 0x19fa: 0x0289, 0x19fb: 0x13d1,
1804 0x19fc: 0x0039, 0x19fd: 0x0ee9, 0x19fe: 0x1159, 0x19ff: 0x0ef9,
1805 // Block 0x68, offset 0x1a00
1806 0x1a00: 0x0f09, 0x1a01: 0x1199, 0x1a02: 0x0f31, 0x1a03: 0x0249, 0x1a04: 0x0f41, 0x1a05: 0x0259,
1807 0x1a06: 0x0f51, 0x1a07: 0x0359, 0x1a08: 0x0f61, 0x1a09: 0x0f71, 0x1a0a: 0x00d9, 0x1a0b: 0x0f99,
1808 0x1a0c: 0x2039, 0x1a0d: 0x0269, 0x1a0e: 0x01d9, 0x1a0f: 0x0fa9, 0x1a10: 0x0fb9, 0x1a11: 0x1089,
1809 0x1a12: 0x0279, 0x1a13: 0x0369, 0x1a14: 0x0289, 0x1a15: 0x13d1, 0x1a16: 0x0039, 0x1a17: 0x0ee9,
1810 0x1a18: 0x1159, 0x1a19: 0x0ef9, 0x1a1a: 0x0f09, 0x1a1b: 0x1199, 0x1a1c: 0x0f31, 0x1a1d: 0x0249,
1811 0x1a1e: 0x0f41, 0x1a1f: 0x0259, 0x1a20: 0x0f51, 0x1a21: 0x0359, 0x1a22: 0x0f61, 0x1a23: 0x0f71,
1812 0x1a24: 0x00d9, 0x1a25: 0x0f99, 0x1a26: 0x2039, 0x1a27: 0x0269, 0x1a28: 0x01d9, 0x1a29: 0x0fa9,
1813 0x1a2a: 0x0fb9, 0x1a2b: 0x1089, 0x1a2c: 0x0279, 0x1a2d: 0x0369, 0x1a2e: 0x0289, 0x1a2f: 0x13d1,
1814 0x1a30: 0x0039, 0x1a31: 0x0ee9, 0x1a32: 0x1159, 0x1a33: 0x0ef9, 0x1a34: 0x0f09, 0x1a35: 0x1199,
1815 0x1a36: 0x0f31, 0x1a37: 0x0249, 0x1a38: 0x0f41, 0x1a39: 0x0259, 0x1a3a: 0x0f51, 0x1a3b: 0x0359,
1816 0x1a3c: 0x0f61, 0x1a3d: 0x0f71, 0x1a3e: 0x00d9, 0x1a3f: 0x0f99,
1817 // Block 0x69, offset 0x1a40
1818 0x1a40: 0x2039, 0x1a41: 0x0269, 0x1a42: 0x01d9, 0x1a43: 0x0fa9, 0x1a44: 0x0fb9, 0x1a45: 0x1089,
1819 0x1a46: 0x0279, 0x1a47: 0x0369, 0x1a48: 0x0289, 0x1a49: 0x13d1, 0x1a4a: 0x0039, 0x1a4b: 0x0ee9,
1820 0x1a4c: 0x1159, 0x1a4d: 0x0ef9, 0x1a4e: 0x0f09, 0x1a4f: 0x1199, 0x1a50: 0x0f31, 0x1a51: 0x0249,
1821 0x1a52: 0x0f41, 0x1a53: 0x0259, 0x1a54: 0x0f51, 0x1a55: 0x0359, 0x1a56: 0x0f61, 0x1a57: 0x0f71,
1822 0x1a58: 0x00d9, 0x1a59: 0x0f99, 0x1a5a: 0x2039, 0x1a5b: 0x0269, 0x1a5c: 0x01d9, 0x1a5d: 0x0fa9,
1823 0x1a5e: 0x0fb9, 0x1a5f: 0x1089, 0x1a60: 0x0279, 0x1a61: 0x0369, 0x1a62: 0x0289, 0x1a63: 0x13d1,
1824 0x1a64: 0xba81, 0x1a65: 0xba99, 0x1a66: 0x0040, 0x1a67: 0x0040, 0x1a68: 0xbab1, 0x1a69: 0x1099,
1825 0x1a6a: 0x10b1, 0x1a6b: 0x10c9, 0x1a6c: 0xbac9, 0x1a6d: 0xbae1, 0x1a6e: 0xbaf9, 0x1a6f: 0x1429,
1826 0x1a70: 0x1a31, 0x1a71: 0xbb11, 0x1a72: 0xbb29, 0x1a73: 0xbb41, 0x1a74: 0xbb59, 0x1a75: 0xbb71,
1827 0x1a76: 0xbb89, 0x1a77: 0x2109, 0x1a78: 0x1111, 0x1a79: 0x1429, 0x1a7a: 0xbba1, 0x1a7b: 0xbbb9,
1828 0x1a7c: 0xbbd1, 0x1a7d: 0x10e1, 0x1a7e: 0x10f9, 0x1a7f: 0xbbe9,
1829 // Block 0x6a, offset 0x1a80
1830 0x1a80: 0x2079, 0x1a81: 0xbc01, 0x1a82: 0xbab1, 0x1a83: 0x1099, 0x1a84: 0x10b1, 0x1a85: 0x10c9,
1831 0x1a86: 0xbac9, 0x1a87: 0xbae1, 0x1a88: 0xbaf9, 0x1a89: 0x1429, 0x1a8a: 0x1a31, 0x1a8b: 0xbb11,
1832 0x1a8c: 0xbb29, 0x1a8d: 0xbb41, 0x1a8e: 0xbb59, 0x1a8f: 0xbb71, 0x1a90: 0xbb89, 0x1a91: 0x2109,
1833 0x1a92: 0x1111, 0x1a93: 0xbba1, 0x1a94: 0xbba1, 0x1a95: 0xbbb9, 0x1a96: 0xbbd1, 0x1a97: 0x10e1,
1834 0x1a98: 0x10f9, 0x1a99: 0xbbe9, 0x1a9a: 0x2079, 0x1a9b: 0xbc21, 0x1a9c: 0xbac9, 0x1a9d: 0x1429,
1835 0x1a9e: 0xbb11, 0x1a9f: 0x10e1, 0x1aa0: 0x1111, 0x1aa1: 0x2109, 0x1aa2: 0xbab1, 0x1aa3: 0x1099,
1836 0x1aa4: 0x10b1, 0x1aa5: 0x10c9, 0x1aa6: 0xbac9, 0x1aa7: 0xbae1, 0x1aa8: 0xbaf9, 0x1aa9: 0x1429,
1837 0x1aaa: 0x1a31, 0x1aab: 0xbb11, 0x1aac: 0xbb29, 0x1aad: 0xbb41, 0x1aae: 0xbb59, 0x1aaf: 0xbb71,
1838 0x1ab0: 0xbb89, 0x1ab1: 0x2109, 0x1ab2: 0x1111, 0x1ab3: 0x1429, 0x1ab4: 0xbba1, 0x1ab5: 0xbbb9,
1839 0x1ab6: 0xbbd1, 0x1ab7: 0x10e1, 0x1ab8: 0x10f9, 0x1ab9: 0xbbe9, 0x1aba: 0x2079, 0x1abb: 0xbc01,
1840 0x1abc: 0xbab1, 0x1abd: 0x1099, 0x1abe: 0x10b1, 0x1abf: 0x10c9,
1841 // Block 0x6b, offset 0x1ac0
1842 0x1ac0: 0xbac9, 0x1ac1: 0xbae1, 0x1ac2: 0xbaf9, 0x1ac3: 0x1429, 0x1ac4: 0x1a31, 0x1ac5: 0xbb11,
1843 0x1ac6: 0xbb29, 0x1ac7: 0xbb41, 0x1ac8: 0xbb59, 0x1ac9: 0xbb71, 0x1aca: 0xbb89, 0x1acb: 0x2109,
1844 0x1acc: 0x1111, 0x1acd: 0xbba1, 0x1ace: 0xbba1, 0x1acf: 0xbbb9, 0x1ad0: 0xbbd1, 0x1ad1: 0x10e1,
1845 0x1ad2: 0x10f9, 0x1ad3: 0xbbe9, 0x1ad4: 0x2079, 0x1ad5: 0xbc21, 0x1ad6: 0xbac9, 0x1ad7: 0x1429,
1846 0x1ad8: 0xbb11, 0x1ad9: 0x10e1, 0x1ada: 0x1111, 0x1adb: 0x2109, 0x1adc: 0xbab1, 0x1add: 0x1099,
1847 0x1ade: 0x10b1, 0x1adf: 0x10c9, 0x1ae0: 0xbac9, 0x1ae1: 0xbae1, 0x1ae2: 0xbaf9, 0x1ae3: 0x1429,
1848 0x1ae4: 0x1a31, 0x1ae5: 0xbb11, 0x1ae6: 0xbb29, 0x1ae7: 0xbb41, 0x1ae8: 0xbb59, 0x1ae9: 0xbb71,
1849 0x1aea: 0xbb89, 0x1aeb: 0x2109, 0x1aec: 0x1111, 0x1aed: 0x1429, 0x1aee: 0xbba1, 0x1aef: 0xbbb9,
1850 0x1af0: 0xbbd1, 0x1af1: 0x10e1, 0x1af2: 0x10f9, 0x1af3: 0xbbe9, 0x1af4: 0x2079, 0x1af5: 0xbc01,
1851 0x1af6: 0xbab1, 0x1af7: 0x1099, 0x1af8: 0x10b1, 0x1af9: 0x10c9, 0x1afa: 0xbac9, 0x1afb: 0xbae1,
1852 0x1afc: 0xbaf9, 0x1afd: 0x1429, 0x1afe: 0x1a31, 0x1aff: 0xbb11,
1853 // Block 0x6c, offset 0x1b00
1854 0x1b00: 0xbb29, 0x1b01: 0xbb41, 0x1b02: 0xbb59, 0x1b03: 0xbb71, 0x1b04: 0xbb89, 0x1b05: 0x2109,
1855 0x1b06: 0x1111, 0x1b07: 0xbba1, 0x1b08: 0xbba1, 0x1b09: 0xbbb9, 0x1b0a: 0xbbd1, 0x1b0b: 0x10e1,
1856 0x1b0c: 0x10f9, 0x1b0d: 0xbbe9, 0x1b0e: 0x2079, 0x1b0f: 0xbc21, 0x1b10: 0xbac9, 0x1b11: 0x1429,
1857 0x1b12: 0xbb11, 0x1b13: 0x10e1, 0x1b14: 0x1111, 0x1b15: 0x2109, 0x1b16: 0xbab1, 0x1b17: 0x1099,
1858 0x1b18: 0x10b1, 0x1b19: 0x10c9, 0x1b1a: 0xbac9, 0x1b1b: 0xbae1, 0x1b1c: 0xbaf9, 0x1b1d: 0x1429,
1859 0x1b1e: 0x1a31, 0x1b1f: 0xbb11, 0x1b20: 0xbb29, 0x1b21: 0xbb41, 0x1b22: 0xbb59, 0x1b23: 0xbb71,
1860 0x1b24: 0xbb89, 0x1b25: 0x2109, 0x1b26: 0x1111, 0x1b27: 0x1429, 0x1b28: 0xbba1, 0x1b29: 0xbbb9,
1861 0x1b2a: 0xbbd1, 0x1b2b: 0x10e1, 0x1b2c: 0x10f9, 0x1b2d: 0xbbe9, 0x1b2e: 0x2079, 0x1b2f: 0xbc01,
1862 0x1b30: 0xbab1, 0x1b31: 0x1099, 0x1b32: 0x10b1, 0x1b33: 0x10c9, 0x1b34: 0xbac9, 0x1b35: 0xbae1,
1863 0x1b36: 0xbaf9, 0x1b37: 0x1429, 0x1b38: 0x1a31, 0x1b39: 0xbb11, 0x1b3a: 0xbb29, 0x1b3b: 0xbb41,
1864 0x1b3c: 0xbb59, 0x1b3d: 0xbb71, 0x1b3e: 0xbb89, 0x1b3f: 0x2109,
1865 // Block 0x6d, offset 0x1b40
1866 0x1b40: 0x1111, 0x1b41: 0xbba1, 0x1b42: 0xbba1, 0x1b43: 0xbbb9, 0x1b44: 0xbbd1, 0x1b45: 0x10e1,
1867 0x1b46: 0x10f9, 0x1b47: 0xbbe9, 0x1b48: 0x2079, 0x1b49: 0xbc21, 0x1b4a: 0xbac9, 0x1b4b: 0x1429,
1868 0x1b4c: 0xbb11, 0x1b4d: 0x10e1, 0x1b4e: 0x1111, 0x1b4f: 0x2109, 0x1b50: 0xbab1, 0x1b51: 0x1099,
1869 0x1b52: 0x10b1, 0x1b53: 0x10c9, 0x1b54: 0xbac9, 0x1b55: 0xbae1, 0x1b56: 0xbaf9, 0x1b57: 0x1429,
1870 0x1b58: 0x1a31, 0x1b59: 0xbb11, 0x1b5a: 0xbb29, 0x1b5b: 0xbb41, 0x1b5c: 0xbb59, 0x1b5d: 0xbb71,
1871 0x1b5e: 0xbb89, 0x1b5f: 0x2109, 0x1b60: 0x1111, 0x1b61: 0x1429, 0x1b62: 0xbba1, 0x1b63: 0xbbb9,
1872 0x1b64: 0xbbd1, 0x1b65: 0x10e1, 0x1b66: 0x10f9, 0x1b67: 0xbbe9, 0x1b68: 0x2079, 0x1b69: 0xbc01,
1873 0x1b6a: 0xbab1, 0x1b6b: 0x1099, 0x1b6c: 0x10b1, 0x1b6d: 0x10c9, 0x1b6e: 0xbac9, 0x1b6f: 0xbae1,
1874 0x1b70: 0xbaf9, 0x1b71: 0x1429, 0x1b72: 0x1a31, 0x1b73: 0xbb11, 0x1b74: 0xbb29, 0x1b75: 0xbb41,
1875 0x1b76: 0xbb59, 0x1b77: 0xbb71, 0x1b78: 0xbb89, 0x1b79: 0x2109, 0x1b7a: 0x1111, 0x1b7b: 0xbba1,
1876 0x1b7c: 0xbba1, 0x1b7d: 0xbbb9, 0x1b7e: 0xbbd1, 0x1b7f: 0x10e1,
1877 // Block 0x6e, offset 0x1b80
1878 0x1b80: 0x10f9, 0x1b81: 0xbbe9, 0x1b82: 0x2079, 0x1b83: 0xbc21, 0x1b84: 0xbac9, 0x1b85: 0x1429,
1879 0x1b86: 0xbb11, 0x1b87: 0x10e1, 0x1b88: 0x1111, 0x1b89: 0x2109, 0x1b8a: 0xbc41, 0x1b8b: 0xbc41,
1880 0x1b8c: 0x0040, 0x1b8d: 0x0040, 0x1b8e: 0x1f41, 0x1b8f: 0x00c9, 0x1b90: 0x0069, 0x1b91: 0x0079,
1881 0x1b92: 0x1f51, 0x1b93: 0x1f61, 0x1b94: 0x1f71, 0x1b95: 0x1f81, 0x1b96: 0x1f91, 0x1b97: 0x1fa1,
1882 0x1b98: 0x1f41, 0x1b99: 0x00c9, 0x1b9a: 0x0069, 0x1b9b: 0x0079, 0x1b9c: 0x1f51, 0x1b9d: 0x1f61,
1883 0x1b9e: 0x1f71, 0x1b9f: 0x1f81, 0x1ba0: 0x1f91, 0x1ba1: 0x1fa1, 0x1ba2: 0x1f41, 0x1ba3: 0x00c9,
1884 0x1ba4: 0x0069, 0x1ba5: 0x0079, 0x1ba6: 0x1f51, 0x1ba7: 0x1f61, 0x1ba8: 0x1f71, 0x1ba9: 0x1f81,
1885 0x1baa: 0x1f91, 0x1bab: 0x1fa1, 0x1bac: 0x1f41, 0x1bad: 0x00c9, 0x1bae: 0x0069, 0x1baf: 0x0079,
1886 0x1bb0: 0x1f51, 0x1bb1: 0x1f61, 0x1bb2: 0x1f71, 0x1bb3: 0x1f81, 0x1bb4: 0x1f91, 0x1bb5: 0x1fa1,
1887 0x1bb6: 0x1f41, 0x1bb7: 0x00c9, 0x1bb8: 0x0069, 0x1bb9: 0x0079, 0x1bba: 0x1f51, 0x1bbb: 0x1f61,
1888 0x1bbc: 0x1f71, 0x1bbd: 0x1f81, 0x1bbe: 0x1f91, 0x1bbf: 0x1fa1,
1889 // Block 0x6f, offset 0x1bc0
1890 0x1bc0: 0xe115, 0x1bc1: 0xe115, 0x1bc2: 0xe135, 0x1bc3: 0xe135, 0x1bc4: 0xe115, 0x1bc5: 0xe115,
1891 0x1bc6: 0xe175, 0x1bc7: 0xe175, 0x1bc8: 0xe115, 0x1bc9: 0xe115, 0x1bca: 0xe135, 0x1bcb: 0xe135,
1892 0x1bcc: 0xe115, 0x1bcd: 0xe115, 0x1bce: 0xe1f5, 0x1bcf: 0xe1f5, 0x1bd0: 0xe115, 0x1bd1: 0xe115,
1893 0x1bd2: 0xe135, 0x1bd3: 0xe135, 0x1bd4: 0xe115, 0x1bd5: 0xe115, 0x1bd6: 0xe175, 0x1bd7: 0xe175,
1894 0x1bd8: 0xe115, 0x1bd9: 0xe115, 0x1bda: 0xe135, 0x1bdb: 0xe135, 0x1bdc: 0xe115, 0x1bdd: 0xe115,
1895 0x1bde: 0x8b05, 0x1bdf: 0x8b05, 0x1be0: 0x04b5, 0x1be1: 0x04b5, 0x1be2: 0x0208, 0x1be3: 0x0208,
1896 0x1be4: 0x0208, 0x1be5: 0x0208, 0x1be6: 0x0208, 0x1be7: 0x0208, 0x1be8: 0x0208, 0x1be9: 0x0208,
1897 0x1bea: 0x0208, 0x1beb: 0x0208, 0x1bec: 0x0208, 0x1bed: 0x0208, 0x1bee: 0x0208, 0x1bef: 0x0208,
1898 0x1bf0: 0x0208, 0x1bf1: 0x0208, 0x1bf2: 0x0208, 0x1bf3: 0x0208, 0x1bf4: 0x0208, 0x1bf5: 0x0208,
1899 0x1bf6: 0x0208, 0x1bf7: 0x0208, 0x1bf8: 0x0208, 0x1bf9: 0x0208, 0x1bfa: 0x0208, 0x1bfb: 0x0208,
1900 0x1bfc: 0x0208, 0x1bfd: 0x0208, 0x1bfe: 0x0208, 0x1bff: 0x0208,
1901 // Block 0x70, offset 0x1c00
1902 0x1c00: 0xb189, 0x1c01: 0xb1a1, 0x1c02: 0xb201, 0x1c03: 0xb249, 0x1c04: 0x0040, 0x1c05: 0xb411,
1903 0x1c06: 0xb291, 0x1c07: 0xb219, 0x1c08: 0xb309, 0x1c09: 0xb429, 0x1c0a: 0xb399, 0x1c0b: 0xb3b1,
1904 0x1c0c: 0xb3c9, 0x1c0d: 0xb3e1, 0x1c0e: 0xb2a9, 0x1c0f: 0xb339, 0x1c10: 0xb369, 0x1c11: 0xb2d9,
1905 0x1c12: 0xb381, 0x1c13: 0xb279, 0x1c14: 0xb2c1, 0x1c15: 0xb1d1, 0x1c16: 0xb1e9, 0x1c17: 0xb231,
1906 0x1c18: 0xb261, 0x1c19: 0xb2f1, 0x1c1a: 0xb321, 0x1c1b: 0xb351, 0x1c1c: 0xbc59, 0x1c1d: 0x7949,
1907 0x1c1e: 0xbc71, 0x1c1f: 0xbc89, 0x1c20: 0x0040, 0x1c21: 0xb1a1, 0x1c22: 0xb201, 0x1c23: 0x0040,
1908 0x1c24: 0xb3f9, 0x1c25: 0x0040, 0x1c26: 0x0040, 0x1c27: 0xb219, 0x1c28: 0x0040, 0x1c29: 0xb429,
1909 0x1c2a: 0xb399, 0x1c2b: 0xb3b1, 0x1c2c: 0xb3c9, 0x1c2d: 0xb3e1, 0x1c2e: 0xb2a9, 0x1c2f: 0xb339,
1910 0x1c30: 0xb369, 0x1c31: 0xb2d9, 0x1c32: 0xb381, 0x1c33: 0x0040, 0x1c34: 0xb2c1, 0x1c35: 0xb1d1,
1911 0x1c36: 0xb1e9, 0x1c37: 0xb231, 0x1c38: 0x0040, 0x1c39: 0xb2f1, 0x1c3a: 0x0040, 0x1c3b: 0xb351,
1912 0x1c3c: 0x0040, 0x1c3d: 0x0040, 0x1c3e: 0x0040, 0x1c3f: 0x0040,
1913 // Block 0x71, offset 0x1c40
1914 0x1c40: 0x0040, 0x1c41: 0x0040, 0x1c42: 0xb201, 0x1c43: 0x0040, 0x1c44: 0x0040, 0x1c45: 0x0040,
1915 0x1c46: 0x0040, 0x1c47: 0xb219, 0x1c48: 0x0040, 0x1c49: 0xb429, 0x1c4a: 0x0040, 0x1c4b: 0xb3b1,
1916 0x1c4c: 0x0040, 0x1c4d: 0xb3e1, 0x1c4e: 0xb2a9, 0x1c4f: 0xb339, 0x1c50: 0x0040, 0x1c51: 0xb2d9,
1917 0x1c52: 0xb381, 0x1c53: 0x0040, 0x1c54: 0xb2c1, 0x1c55: 0x0040, 0x1c56: 0x0040, 0x1c57: 0xb231,
1918 0x1c58: 0x0040, 0x1c59: 0xb2f1, 0x1c5a: 0x0040, 0x1c5b: 0xb351, 0x1c5c: 0x0040, 0x1c5d: 0x7949,
1919 0x1c5e: 0x0040, 0x1c5f: 0xbc89, 0x1c60: 0x0040, 0x1c61: 0xb1a1, 0x1c62: 0xb201, 0x1c63: 0x0040,
1920 0x1c64: 0xb3f9, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0xb219, 0x1c68: 0xb309, 0x1c69: 0xb429,
1921 0x1c6a: 0xb399, 0x1c6b: 0x0040, 0x1c6c: 0xb3c9, 0x1c6d: 0xb3e1, 0x1c6e: 0xb2a9, 0x1c6f: 0xb339,
1922 0x1c70: 0xb369, 0x1c71: 0xb2d9, 0x1c72: 0xb381, 0x1c73: 0x0040, 0x1c74: 0xb2c1, 0x1c75: 0xb1d1,
1923 0x1c76: 0xb1e9, 0x1c77: 0xb231, 0x1c78: 0x0040, 0x1c79: 0xb2f1, 0x1c7a: 0xb321, 0x1c7b: 0xb351,
1924 0x1c7c: 0xbc59, 0x1c7d: 0x0040, 0x1c7e: 0xbc71, 0x1c7f: 0x0040,
1925 // Block 0x72, offset 0x1c80
1926 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0xb3f9, 0x1c85: 0xb411,
1927 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0x0040, 0x1c8b: 0xb3b1,
1928 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9,
1929 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231,
1930 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0x0040, 0x1c9d: 0x0040,
1931 0x1c9e: 0x0040, 0x1c9f: 0x0040, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0xb249,
1932 0x1ca4: 0x0040, 0x1ca5: 0xb411, 0x1ca6: 0xb291, 0x1ca7: 0xb219, 0x1ca8: 0xb309, 0x1ca9: 0xb429,
1933 0x1caa: 0x0040, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,
1934 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0xb279, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,
1935 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0xb261, 0x1cb9: 0xb2f1, 0x1cba: 0xb321, 0x1cbb: 0xb351,
1936 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040,
1937 // Block 0x73, offset 0x1cc0
1938 0x1cc0: 0x0040, 0x1cc1: 0xbca2, 0x1cc2: 0xbcba, 0x1cc3: 0xbcd2, 0x1cc4: 0xbcea, 0x1cc5: 0xbd02,
1939 0x1cc6: 0xbd1a, 0x1cc7: 0xbd32, 0x1cc8: 0xbd4a, 0x1cc9: 0xbd62, 0x1cca: 0xbd7a, 0x1ccb: 0x0018,
1940 0x1ccc: 0x0018, 0x1ccd: 0x0040, 0x1cce: 0x0040, 0x1ccf: 0x0040, 0x1cd0: 0xbd92, 0x1cd1: 0xbdb2,
1941 0x1cd2: 0xbdd2, 0x1cd3: 0xbdf2, 0x1cd4: 0xbe12, 0x1cd5: 0xbe32, 0x1cd6: 0xbe52, 0x1cd7: 0xbe72,
1942 0x1cd8: 0xbe92, 0x1cd9: 0xbeb2, 0x1cda: 0xbed2, 0x1cdb: 0xbef2, 0x1cdc: 0xbf12, 0x1cdd: 0xbf32,
1943 0x1cde: 0xbf52, 0x1cdf: 0xbf72, 0x1ce0: 0xbf92, 0x1ce1: 0xbfb2, 0x1ce2: 0xbfd2, 0x1ce3: 0xbff2,
1944 0x1ce4: 0xc012, 0x1ce5: 0xc032, 0x1ce6: 0xc052, 0x1ce7: 0xc072, 0x1ce8: 0xc092, 0x1ce9: 0xc0b2,
1945 0x1cea: 0xc0d1, 0x1ceb: 0x1159, 0x1cec: 0x0269, 0x1ced: 0x6671, 0x1cee: 0xc111, 0x1cef: 0x0040,
1946 0x1cf0: 0x0039, 0x1cf1: 0x0ee9, 0x1cf2: 0x1159, 0x1cf3: 0x0ef9, 0x1cf4: 0x0f09, 0x1cf5: 0x1199,
1947 0x1cf6: 0x0f31, 0x1cf7: 0x0249, 0x1cf8: 0x0f41, 0x1cf9: 0x0259, 0x1cfa: 0x0f51, 0x1cfb: 0x0359,
1948 0x1cfc: 0x0f61, 0x1cfd: 0x0f71, 0x1cfe: 0x00d9, 0x1cff: 0x0f99,
1949 // Block 0x74, offset 0x1d00
1950 0x1d00: 0x2039, 0x1d01: 0x0269, 0x1d02: 0x01d9, 0x1d03: 0x0fa9, 0x1d04: 0x0fb9, 0x1d05: 0x1089,
1951 0x1d06: 0x0279, 0x1d07: 0x0369, 0x1d08: 0x0289, 0x1d09: 0x13d1, 0x1d0a: 0xc129, 0x1d0b: 0x65b1,
1952 0x1d0c: 0xc141, 0x1d0d: 0x1441, 0x1d0e: 0xc159, 0x1d0f: 0xc179, 0x1d10: 0x0018, 0x1d11: 0x0018,
1953 0x1d12: 0x0018, 0x1d13: 0x0018, 0x1d14: 0x0018, 0x1d15: 0x0018, 0x1d16: 0x0018, 0x1d17: 0x0018,
1954 0x1d18: 0x0018, 0x1d19: 0x0018, 0x1d1a: 0x0018, 0x1d1b: 0x0018, 0x1d1c: 0x0018, 0x1d1d: 0x0018,
1955 0x1d1e: 0x0018, 0x1d1f: 0x0018, 0x1d20: 0x0018, 0x1d21: 0x0018, 0x1d22: 0x0018, 0x1d23: 0x0018,
1956 0x1d24: 0x0018, 0x1d25: 0x0018, 0x1d26: 0x0018, 0x1d27: 0x0018, 0x1d28: 0x0018, 0x1d29: 0x0018,
1957 0x1d2a: 0xc191, 0x1d2b: 0xc1a9, 0x1d2c: 0x0040, 0x1d2d: 0x0040, 0x1d2e: 0x0040, 0x1d2f: 0x0040,
1958 0x1d30: 0x0018, 0x1d31: 0x0018, 0x1d32: 0x0018, 0x1d33: 0x0018, 0x1d34: 0x0018, 0x1d35: 0x0018,
1959 0x1d36: 0x0018, 0x1d37: 0x0018, 0x1d38: 0x0018, 0x1d39: 0x0018, 0x1d3a: 0x0018, 0x1d3b: 0x0018,
1960 0x1d3c: 0x0018, 0x1d3d: 0x0018, 0x1d3e: 0x0018, 0x1d3f: 0x0018,
1961 // Block 0x75, offset 0x1d40
1962 0x1d40: 0xc1d9, 0x1d41: 0xc211, 0x1d42: 0xc249, 0x1d43: 0x0040, 0x1d44: 0x0040, 0x1d45: 0x0040,
1963 0x1d46: 0x0040, 0x1d47: 0x0040, 0x1d48: 0x0040, 0x1d49: 0x0040, 0x1d4a: 0x0040, 0x1d4b: 0x0040,
1964 0x1d4c: 0x0040, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xc269, 0x1d51: 0xc289,
1965 0x1d52: 0xc2a9, 0x1d53: 0xc2c9, 0x1d54: 0xc2e9, 0x1d55: 0xc309, 0x1d56: 0xc329, 0x1d57: 0xc349,
1966 0x1d58: 0xc369, 0x1d59: 0xc389, 0x1d5a: 0xc3a9, 0x1d5b: 0xc3c9, 0x1d5c: 0xc3e9, 0x1d5d: 0xc409,
1967 0x1d5e: 0xc429, 0x1d5f: 0xc449, 0x1d60: 0xc469, 0x1d61: 0xc489, 0x1d62: 0xc4a9, 0x1d63: 0xc4c9,
1968 0x1d64: 0xc4e9, 0x1d65: 0xc509, 0x1d66: 0xc529, 0x1d67: 0xc549, 0x1d68: 0xc569, 0x1d69: 0xc589,
1969 0x1d6a: 0xc5a9, 0x1d6b: 0xc5c9, 0x1d6c: 0xc5e9, 0x1d6d: 0xc609, 0x1d6e: 0xc629, 0x1d6f: 0xc649,
1970 0x1d70: 0xc669, 0x1d71: 0xc689, 0x1d72: 0xc6a9, 0x1d73: 0xc6c9, 0x1d74: 0xc6e9, 0x1d75: 0xc709,
1971 0x1d76: 0xc729, 0x1d77: 0xc749, 0x1d78: 0xc769, 0x1d79: 0xc789, 0x1d7a: 0xc7a9, 0x1d7b: 0xc7c9,
1972 0x1d7c: 0x0040, 0x1d7d: 0x0040, 0x1d7e: 0x0040, 0x1d7f: 0x0040,
1973 // Block 0x76, offset 0x1d80
1974 0x1d80: 0xcaf9, 0x1d81: 0xcb19, 0x1d82: 0xcb39, 0x1d83: 0x8b1d, 0x1d84: 0xcb59, 0x1d85: 0xcb79,
1975 0x1d86: 0xcb99, 0x1d87: 0xcbb9, 0x1d88: 0xcbd9, 0x1d89: 0xcbf9, 0x1d8a: 0xcc19, 0x1d8b: 0xcc39,
1976 0x1d8c: 0xcc59, 0x1d8d: 0x8b3d, 0x1d8e: 0xcc79, 0x1d8f: 0xcc99, 0x1d90: 0xccb9, 0x1d91: 0xccd9,
1977 0x1d92: 0x8b5d, 0x1d93: 0xccf9, 0x1d94: 0xcd19, 0x1d95: 0xc429, 0x1d96: 0x8b7d, 0x1d97: 0xcd39,
1978 0x1d98: 0xcd59, 0x1d99: 0xcd79, 0x1d9a: 0xcd99, 0x1d9b: 0xcdb9, 0x1d9c: 0x8b9d, 0x1d9d: 0xcdd9,
1979 0x1d9e: 0xcdf9, 0x1d9f: 0xce19, 0x1da0: 0xce39, 0x1da1: 0xce59, 0x1da2: 0xc789, 0x1da3: 0xce79,
1980 0x1da4: 0xce99, 0x1da5: 0xceb9, 0x1da6: 0xced9, 0x1da7: 0xcef9, 0x1da8: 0xcf19, 0x1da9: 0xcf39,
1981 0x1daa: 0xcf59, 0x1dab: 0xcf79, 0x1dac: 0xcf99, 0x1dad: 0xcfb9, 0x1dae: 0xcfd9, 0x1daf: 0xcff9,
1982 0x1db0: 0xd019, 0x1db1: 0xd039, 0x1db2: 0xd039, 0x1db3: 0xd039, 0x1db4: 0x8bbd, 0x1db5: 0xd059,
1983 0x1db6: 0xd079, 0x1db7: 0xd099, 0x1db8: 0x8bdd, 0x1db9: 0xd0b9, 0x1dba: 0xd0d9, 0x1dbb: 0xd0f9,
1984 0x1dbc: 0xd119, 0x1dbd: 0xd139, 0x1dbe: 0xd159, 0x1dbf: 0xd179,
1985 // Block 0x77, offset 0x1dc0
1986 0x1dc0: 0xd199, 0x1dc1: 0xd1b9, 0x1dc2: 0xd1d9, 0x1dc3: 0xd1f9, 0x1dc4: 0xd219, 0x1dc5: 0xd239,
1987 0x1dc6: 0xd239, 0x1dc7: 0xd259, 0x1dc8: 0xd279, 0x1dc9: 0xd299, 0x1dca: 0xd2b9, 0x1dcb: 0xd2d9,
1988 0x1dcc: 0xd2f9, 0x1dcd: 0xd319, 0x1dce: 0xd339, 0x1dcf: 0xd359, 0x1dd0: 0xd379, 0x1dd1: 0xd399,
1989 0x1dd2: 0xd3b9, 0x1dd3: 0xd3d9, 0x1dd4: 0xd3f9, 0x1dd5: 0xd419, 0x1dd6: 0xd439, 0x1dd7: 0xd459,
1990 0x1dd8: 0xd479, 0x1dd9: 0x8bfd, 0x1dda: 0xd499, 0x1ddb: 0xd4b9, 0x1ddc: 0xd4d9, 0x1ddd: 0xc309,
1991 0x1dde: 0xd4f9, 0x1ddf: 0xd519, 0x1de0: 0x8c1d, 0x1de1: 0x8c3d, 0x1de2: 0xd539, 0x1de3: 0xd559,
1992 0x1de4: 0xd579, 0x1de5: 0xd599, 0x1de6: 0xd5b9, 0x1de7: 0xd5d9, 0x1de8: 0x0040, 0x1de9: 0xd5f9,
1993 0x1dea: 0xd619, 0x1deb: 0xd619, 0x1dec: 0x8c5d, 0x1ded: 0xd639, 0x1dee: 0xd659, 0x1def: 0xd679,
1994 0x1df0: 0xd699, 0x1df1: 0x8c7d, 0x1df2: 0xd6b9, 0x1df3: 0xd6d9, 0x1df4: 0x0040, 0x1df5: 0xd6f9,
1995 0x1df6: 0xd719, 0x1df7: 0xd739, 0x1df8: 0xd759, 0x1df9: 0xd779, 0x1dfa: 0xd799, 0x1dfb: 0x8c9d,
1996 0x1dfc: 0xd7b9, 0x1dfd: 0x8cbd, 0x1dfe: 0xd7d9, 0x1dff: 0xd7f9,
1997 // Block 0x78, offset 0x1e00
1998 0x1e00: 0xd819, 0x1e01: 0xd839, 0x1e02: 0xd859, 0x1e03: 0xd879, 0x1e04: 0xd899, 0x1e05: 0xd8b9,
1999 0x1e06: 0xd8d9, 0x1e07: 0xd8f9, 0x1e08: 0xd919, 0x1e09: 0x8cdd, 0x1e0a: 0xd939, 0x1e0b: 0xd959,
2000 0x1e0c: 0xd979, 0x1e0d: 0xd999, 0x1e0e: 0xd9b9, 0x1e0f: 0x8cfd, 0x1e10: 0xd9d9, 0x1e11: 0x8d1d,
2001 0x1e12: 0x8d3d, 0x1e13: 0xd9f9, 0x1e14: 0xda19, 0x1e15: 0xda19, 0x1e16: 0xda39, 0x1e17: 0x8d5d,
2002 0x1e18: 0x8d7d, 0x1e19: 0xda59, 0x1e1a: 0xda79, 0x1e1b: 0xda99, 0x1e1c: 0xdab9, 0x1e1d: 0xdad9,
2003 0x1e1e: 0xdaf9, 0x1e1f: 0xdb19, 0x1e20: 0xdb39, 0x1e21: 0xdb59, 0x1e22: 0xdb79, 0x1e23: 0xdb99,
2004 0x1e24: 0x8d9d, 0x1e25: 0xdbb9, 0x1e26: 0xdbd9, 0x1e27: 0xdbf9, 0x1e28: 0xdc19, 0x1e29: 0xdbf9,
2005 0x1e2a: 0xdc39, 0x1e2b: 0xdc59, 0x1e2c: 0xdc79, 0x1e2d: 0xdc99, 0x1e2e: 0xdcb9, 0x1e2f: 0xdcd9,
2006 0x1e30: 0xdcf9, 0x1e31: 0xdd19, 0x1e32: 0xdd39, 0x1e33: 0xdd59, 0x1e34: 0xdd79, 0x1e35: 0xdd99,
2007 0x1e36: 0xddb9, 0x1e37: 0xddd9, 0x1e38: 0x8dbd, 0x1e39: 0xddf9, 0x1e3a: 0xde19, 0x1e3b: 0xde39,
2008 0x1e3c: 0xde59, 0x1e3d: 0xde79, 0x1e3e: 0x8ddd, 0x1e3f: 0xde99,
2009 // Block 0x79, offset 0x1e40
2010 0x1e40: 0xe599, 0x1e41: 0xe5b9, 0x1e42: 0xe5d9, 0x1e43: 0xe5f9, 0x1e44: 0xe619, 0x1e45: 0xe639,
2011 0x1e46: 0x8efd, 0x1e47: 0xe659, 0x1e48: 0xe679, 0x1e49: 0xe699, 0x1e4a: 0xe6b9, 0x1e4b: 0xe6d9,
2012 0x1e4c: 0xe6f9, 0x1e4d: 0x8f1d, 0x1e4e: 0xe719, 0x1e4f: 0xe739, 0x1e50: 0x8f3d, 0x1e51: 0x8f5d,
2013 0x1e52: 0xe759, 0x1e53: 0xe779, 0x1e54: 0xe799, 0x1e55: 0xe7b9, 0x1e56: 0xe7d9, 0x1e57: 0xe7f9,
2014 0x1e58: 0xe819, 0x1e59: 0xe839, 0x1e5a: 0xe859, 0x1e5b: 0x8f7d, 0x1e5c: 0xe879, 0x1e5d: 0x8f9d,
2015 0x1e5e: 0xe899, 0x1e5f: 0x0040, 0x1e60: 0xe8b9, 0x1e61: 0xe8d9, 0x1e62: 0xe8f9, 0x1e63: 0x8fbd,
2016 0x1e64: 0xe919, 0x1e65: 0xe939, 0x1e66: 0x8fdd, 0x1e67: 0x8ffd, 0x1e68: 0xe959, 0x1e69: 0xe979,
2017 0x1e6a: 0xe999, 0x1e6b: 0xe9b9, 0x1e6c: 0xe9d9, 0x1e6d: 0xe9d9, 0x1e6e: 0xe9f9, 0x1e6f: 0xea19,
2018 0x1e70: 0xea39, 0x1e71: 0xea59, 0x1e72: 0xea79, 0x1e73: 0xea99, 0x1e74: 0xeab9, 0x1e75: 0x901d,
2019 0x1e76: 0xead9, 0x1e77: 0x903d, 0x1e78: 0xeaf9, 0x1e79: 0x905d, 0x1e7a: 0xeb19, 0x1e7b: 0x907d,
2020 0x1e7c: 0x909d, 0x1e7d: 0x90bd, 0x1e7e: 0xeb39, 0x1e7f: 0xeb59,
2021 // Block 0x7a, offset 0x1e80
2022 0x1e80: 0xeb79, 0x1e81: 0x90dd, 0x1e82: 0x90fd, 0x1e83: 0x911d, 0x1e84: 0x913d, 0x1e85: 0xeb99,
2023 0x1e86: 0xebb9, 0x1e87: 0xebb9, 0x1e88: 0xebd9, 0x1e89: 0xebf9, 0x1e8a: 0xec19, 0x1e8b: 0xec39,
2024 0x1e8c: 0xec59, 0x1e8d: 0x915d, 0x1e8e: 0xec79, 0x1e8f: 0xec99, 0x1e90: 0xecb9, 0x1e91: 0xecd9,
2025 0x1e92: 0x917d, 0x1e93: 0xecf9, 0x1e94: 0x919d, 0x1e95: 0x91bd, 0x1e96: 0xed19, 0x1e97: 0xed39,
2026 0x1e98: 0xed59, 0x1e99: 0xed79, 0x1e9a: 0xed99, 0x1e9b: 0xedb9, 0x1e9c: 0x91dd, 0x1e9d: 0x91fd,
2027 0x1e9e: 0x921d, 0x1e9f: 0x0040, 0x1ea0: 0xedd9, 0x1ea1: 0x923d, 0x1ea2: 0xedf9, 0x1ea3: 0xee19,
2028 0x1ea4: 0xee39, 0x1ea5: 0x925d, 0x1ea6: 0xee59, 0x1ea7: 0xee79, 0x1ea8: 0xee99, 0x1ea9: 0xeeb9,
2029 0x1eaa: 0xeed9, 0x1eab: 0x927d, 0x1eac: 0xeef9, 0x1ead: 0xef19, 0x1eae: 0xef39, 0x1eaf: 0xef59,
2030 0x1eb0: 0xef79, 0x1eb1: 0xef99, 0x1eb2: 0x929d, 0x1eb3: 0x92bd, 0x1eb4: 0xefb9, 0x1eb5: 0x92dd,
2031 0x1eb6: 0xefd9, 0x1eb7: 0x92fd, 0x1eb8: 0xeff9, 0x1eb9: 0xf019, 0x1eba: 0xf039, 0x1ebb: 0x931d,
2032 0x1ebc: 0x933d, 0x1ebd: 0xf059, 0x1ebe: 0x935d, 0x1ebf: 0xf079,
2033 // Block 0x7b, offset 0x1ec0
2034 0x1ec0: 0xf6b9, 0x1ec1: 0xf6d9, 0x1ec2: 0xf6f9, 0x1ec3: 0xf719, 0x1ec4: 0xf739, 0x1ec5: 0x951d,
2035 0x1ec6: 0xf759, 0x1ec7: 0xf779, 0x1ec8: 0xf799, 0x1ec9: 0xf7b9, 0x1eca: 0xf7d9, 0x1ecb: 0x953d,
2036 0x1ecc: 0x955d, 0x1ecd: 0xf7f9, 0x1ece: 0xf819, 0x1ecf: 0xf839, 0x1ed0: 0xf859, 0x1ed1: 0xf879,
2037 0x1ed2: 0xf899, 0x1ed3: 0x957d, 0x1ed4: 0xf8b9, 0x1ed5: 0xf8d9, 0x1ed6: 0xf8f9, 0x1ed7: 0xf919,
2038 0x1ed8: 0x959d, 0x1ed9: 0x95bd, 0x1eda: 0xf939, 0x1edb: 0xf959, 0x1edc: 0xf979, 0x1edd: 0x95dd,
2039 0x1ede: 0xf999, 0x1edf: 0xf9b9, 0x1ee0: 0x6815, 0x1ee1: 0x95fd, 0x1ee2: 0xf9d9, 0x1ee3: 0xf9f9,
2040 0x1ee4: 0xfa19, 0x1ee5: 0x961d, 0x1ee6: 0xfa39, 0x1ee7: 0xfa59, 0x1ee8: 0xfa79, 0x1ee9: 0xfa99,
2041 0x1eea: 0xfab9, 0x1eeb: 0xfad9, 0x1eec: 0xfaf9, 0x1eed: 0x963d, 0x1eee: 0xfb19, 0x1eef: 0xfb39,
2042 0x1ef0: 0xfb59, 0x1ef1: 0x965d, 0x1ef2: 0xfb79, 0x1ef3: 0xfb99, 0x1ef4: 0xfbb9, 0x1ef5: 0xfbd9,
2043 0x1ef6: 0x7b35, 0x1ef7: 0x967d, 0x1ef8: 0xfbf9, 0x1ef9: 0xfc19, 0x1efa: 0xfc39, 0x1efb: 0x969d,
2044 0x1efc: 0xfc59, 0x1efd: 0x96bd, 0x1efe: 0xfc79, 0x1eff: 0xfc79,
2045 // Block 0x7c, offset 0x1f00
2046 0x1f00: 0xfc99, 0x1f01: 0x96dd, 0x1f02: 0xfcb9, 0x1f03: 0xfcd9, 0x1f04: 0xfcf9, 0x1f05: 0xfd19,
2047 0x1f06: 0xfd39, 0x1f07: 0xfd59, 0x1f08: 0xfd79, 0x1f09: 0x96fd, 0x1f0a: 0xfd99, 0x1f0b: 0xfdb9,
2048 0x1f0c: 0xfdd9, 0x1f0d: 0xfdf9, 0x1f0e: 0xfe19, 0x1f0f: 0xfe39, 0x1f10: 0x971d, 0x1f11: 0xfe59,
2049 0x1f12: 0x973d, 0x1f13: 0x975d, 0x1f14: 0x977d, 0x1f15: 0xfe79, 0x1f16: 0xfe99, 0x1f17: 0xfeb9,
2050 0x1f18: 0xfed9, 0x1f19: 0xfef9, 0x1f1a: 0xff19, 0x1f1b: 0xff39, 0x1f1c: 0xff59, 0x1f1d: 0x979d,
2051 0x1f1e: 0x0040, 0x1f1f: 0x0040, 0x1f20: 0x0040, 0x1f21: 0x0040, 0x1f22: 0x0040, 0x1f23: 0x0040,
2052 0x1f24: 0x0040, 0x1f25: 0x0040, 0x1f26: 0x0040, 0x1f27: 0x0040, 0x1f28: 0x0040, 0x1f29: 0x0040,
2053 0x1f2a: 0x0040, 0x1f2b: 0x0040, 0x1f2c: 0x0040, 0x1f2d: 0x0040, 0x1f2e: 0x0040, 0x1f2f: 0x0040,
2054 0x1f30: 0x0040, 0x1f31: 0x0040, 0x1f32: 0x0040, 0x1f33: 0x0040, 0x1f34: 0x0040, 0x1f35: 0x0040,
2055 0x1f36: 0x0040, 0x1f37: 0x0040, 0x1f38: 0x0040, 0x1f39: 0x0040, 0x1f3a: 0x0040, 0x1f3b: 0x0040,
2056 0x1f3c: 0x0040, 0x1f3d: 0x0040, 0x1f3e: 0x0040, 0x1f3f: 0x0040,
2057}
2058
2059// idnaIndex: 35 blocks, 2240 entries, 4480 bytes
2060// Block 0 is the zero block.
2061var idnaIndex = [2240]uint16{
2062 // Block 0x0, offset 0x0
2063 // Block 0x1, offset 0x40
2064 // Block 0x2, offset 0x80
2065 // Block 0x3, offset 0xc0
2066 0xc2: 0x01, 0xc3: 0x7b, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,
2067 0xc8: 0x06, 0xc9: 0x7c, 0xca: 0x7d, 0xcb: 0x07, 0xcc: 0x7e, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,
2068 0xd0: 0x7f, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x80, 0xd6: 0x81, 0xd7: 0x82,
2069 0xd8: 0x0f, 0xd9: 0x83, 0xda: 0x84, 0xdb: 0x10, 0xdc: 0x11, 0xdd: 0x85, 0xde: 0x86, 0xdf: 0x87,
2070 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,
2071 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,
2072 0xf0: 0x1c, 0xf1: 0x1d, 0xf2: 0x1d, 0xf3: 0x1f, 0xf4: 0x20,
2073 // Block 0x4, offset 0x100
2074 0x120: 0x88, 0x121: 0x89, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x12, 0x126: 0x13, 0x127: 0x14,
2075 0x128: 0x15, 0x129: 0x16, 0x12a: 0x17, 0x12b: 0x18, 0x12c: 0x19, 0x12d: 0x1a, 0x12e: 0x1b, 0x12f: 0x8d,
2076 0x130: 0x8e, 0x131: 0x1c, 0x132: 0x1d, 0x133: 0x1e, 0x134: 0x8f, 0x135: 0x1f, 0x136: 0x90, 0x137: 0x91,
2077 0x138: 0x92, 0x139: 0x93, 0x13a: 0x20, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x21, 0x13e: 0x22, 0x13f: 0x96,
2078 // Block 0x5, offset 0x140
2079 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9b, 0x147: 0x9b,
2080 0x148: 0x9d, 0x149: 0x9e, 0x14a: 0x9f, 0x14b: 0xa0, 0x14c: 0xa1, 0x14d: 0xa2, 0x14e: 0xa3, 0x14f: 0xa4,
2081 0x150: 0xa5, 0x151: 0x9d, 0x152: 0x9d, 0x153: 0x9d, 0x154: 0x9d, 0x155: 0x9d, 0x156: 0x9d, 0x157: 0x9d,
2082 0x158: 0x9d, 0x159: 0xa6, 0x15a: 0xa7, 0x15b: 0xa8, 0x15c: 0xa9, 0x15d: 0xaa, 0x15e: 0xab, 0x15f: 0xac,
2083 0x160: 0xad, 0x161: 0xae, 0x162: 0xaf, 0x163: 0xb0, 0x164: 0xb1, 0x165: 0xb2, 0x166: 0xb3, 0x167: 0xb4,
2084 0x168: 0xb5, 0x169: 0xb6, 0x16a: 0xb7, 0x16b: 0xb8, 0x16c: 0xb9, 0x16d: 0xba, 0x16e: 0xbb, 0x16f: 0xbc,
2085 0x170: 0xbd, 0x171: 0xbe, 0x172: 0xbf, 0x173: 0xc0, 0x174: 0x23, 0x175: 0x24, 0x176: 0x25, 0x177: 0xc1,
2086 0x178: 0x26, 0x179: 0x26, 0x17a: 0x27, 0x17b: 0x26, 0x17c: 0xc2, 0x17d: 0x28, 0x17e: 0x29, 0x17f: 0x2a,
2087 // Block 0x6, offset 0x180
2088 0x180: 0x2b, 0x181: 0x2c, 0x182: 0x2d, 0x183: 0xc3, 0x184: 0x2e, 0x185: 0x2f, 0x186: 0xc4, 0x187: 0x9b,
2089 0x188: 0xc5, 0x189: 0xc6, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc7, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0xc8,
2090 0x190: 0xc9, 0x191: 0x30, 0x192: 0x31, 0x193: 0x32, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,
2091 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,
2092 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,
2093 0x1a8: 0xca, 0x1a9: 0xcb, 0x1aa: 0x9b, 0x1ab: 0xcc, 0x1ac: 0x9b, 0x1ad: 0xcd, 0x1ae: 0xce, 0x1af: 0xcf,
2094 0x1b0: 0xd0, 0x1b1: 0x33, 0x1b2: 0x26, 0x1b3: 0x34, 0x1b4: 0xd1, 0x1b5: 0xd2, 0x1b6: 0xd3, 0x1b7: 0xd4,
2095 0x1b8: 0xd5, 0x1b9: 0xd6, 0x1ba: 0xd7, 0x1bb: 0xd8, 0x1bc: 0xd9, 0x1bd: 0xda, 0x1be: 0xdb, 0x1bf: 0x35,
2096 // Block 0x7, offset 0x1c0
2097 0x1c0: 0x36, 0x1c1: 0xdc, 0x1c2: 0xdd, 0x1c3: 0xde, 0x1c4: 0xdf, 0x1c5: 0x37, 0x1c6: 0x38, 0x1c7: 0xe0,
2098 0x1c8: 0xe1, 0x1c9: 0x39, 0x1ca: 0x3a, 0x1cb: 0x3b, 0x1cc: 0x3c, 0x1cd: 0x3d, 0x1ce: 0x3e, 0x1cf: 0x3f,
2099 0x1d0: 0x9d, 0x1d1: 0x9d, 0x1d2: 0x9d, 0x1d3: 0x9d, 0x1d4: 0x9d, 0x1d5: 0x9d, 0x1d6: 0x9d, 0x1d7: 0x9d,
2100 0x1d8: 0x9d, 0x1d9: 0x9d, 0x1da: 0x9d, 0x1db: 0x9d, 0x1dc: 0x9d, 0x1dd: 0x9d, 0x1de: 0x9d, 0x1df: 0x9d,
2101 0x1e0: 0x9d, 0x1e1: 0x9d, 0x1e2: 0x9d, 0x1e3: 0x9d, 0x1e4: 0x9d, 0x1e5: 0x9d, 0x1e6: 0x9d, 0x1e7: 0x9d,
2102 0x1e8: 0x9d, 0x1e9: 0x9d, 0x1ea: 0x9d, 0x1eb: 0x9d, 0x1ec: 0x9d, 0x1ed: 0x9d, 0x1ee: 0x9d, 0x1ef: 0x9d,
2103 0x1f0: 0x9d, 0x1f1: 0x9d, 0x1f2: 0x9d, 0x1f3: 0x9d, 0x1f4: 0x9d, 0x1f5: 0x9d, 0x1f6: 0x9d, 0x1f7: 0x9d,
2104 0x1f8: 0x9d, 0x1f9: 0x9d, 0x1fa: 0x9d, 0x1fb: 0x9d, 0x1fc: 0x9d, 0x1fd: 0x9d, 0x1fe: 0x9d, 0x1ff: 0x9d,
2105 // Block 0x8, offset 0x200
2106 0x200: 0x9d, 0x201: 0x9d, 0x202: 0x9d, 0x203: 0x9d, 0x204: 0x9d, 0x205: 0x9d, 0x206: 0x9d, 0x207: 0x9d,
2107 0x208: 0x9d, 0x209: 0x9d, 0x20a: 0x9d, 0x20b: 0x9d, 0x20c: 0x9d, 0x20d: 0x9d, 0x20e: 0x9d, 0x20f: 0x9d,
2108 0x210: 0x9d, 0x211: 0x9d, 0x212: 0x9d, 0x213: 0x9d, 0x214: 0x9d, 0x215: 0x9d, 0x216: 0x9d, 0x217: 0x9d,
2109 0x218: 0x9d, 0x219: 0x9d, 0x21a: 0x9d, 0x21b: 0x9d, 0x21c: 0x9d, 0x21d: 0x9d, 0x21e: 0x9d, 0x21f: 0x9d,
2110 0x220: 0x9d, 0x221: 0x9d, 0x222: 0x9d, 0x223: 0x9d, 0x224: 0x9d, 0x225: 0x9d, 0x226: 0x9d, 0x227: 0x9d,
2111 0x228: 0x9d, 0x229: 0x9d, 0x22a: 0x9d, 0x22b: 0x9d, 0x22c: 0x9d, 0x22d: 0x9d, 0x22e: 0x9d, 0x22f: 0x9d,
2112 0x230: 0x9d, 0x231: 0x9d, 0x232: 0x9d, 0x233: 0x9d, 0x234: 0x9d, 0x235: 0x9d, 0x236: 0xb0, 0x237: 0x9b,
2113 0x238: 0x9d, 0x239: 0x9d, 0x23a: 0x9d, 0x23b: 0x9d, 0x23c: 0x9d, 0x23d: 0x9d, 0x23e: 0x9d, 0x23f: 0x9d,
2114 // Block 0x9, offset 0x240
2115 0x240: 0x9d, 0x241: 0x9d, 0x242: 0x9d, 0x243: 0x9d, 0x244: 0x9d, 0x245: 0x9d, 0x246: 0x9d, 0x247: 0x9d,
2116 0x248: 0x9d, 0x249: 0x9d, 0x24a: 0x9d, 0x24b: 0x9d, 0x24c: 0x9d, 0x24d: 0x9d, 0x24e: 0x9d, 0x24f: 0x9d,
2117 0x250: 0x9d, 0x251: 0x9d, 0x252: 0x9d, 0x253: 0x9d, 0x254: 0x9d, 0x255: 0x9d, 0x256: 0x9d, 0x257: 0x9d,
2118 0x258: 0x9d, 0x259: 0x9d, 0x25a: 0x9d, 0x25b: 0x9d, 0x25c: 0x9d, 0x25d: 0x9d, 0x25e: 0x9d, 0x25f: 0x9d,
2119 0x260: 0x9d, 0x261: 0x9d, 0x262: 0x9d, 0x263: 0x9d, 0x264: 0x9d, 0x265: 0x9d, 0x266: 0x9d, 0x267: 0x9d,
2120 0x268: 0x9d, 0x269: 0x9d, 0x26a: 0x9d, 0x26b: 0x9d, 0x26c: 0x9d, 0x26d: 0x9d, 0x26e: 0x9d, 0x26f: 0x9d,
2121 0x270: 0x9d, 0x271: 0x9d, 0x272: 0x9d, 0x273: 0x9d, 0x274: 0x9d, 0x275: 0x9d, 0x276: 0x9d, 0x277: 0x9d,
2122 0x278: 0x9d, 0x279: 0x9d, 0x27a: 0x9d, 0x27b: 0x9d, 0x27c: 0x9d, 0x27d: 0x9d, 0x27e: 0x9d, 0x27f: 0x9d,
2123 // Block 0xa, offset 0x280
2124 0x280: 0x9d, 0x281: 0x9d, 0x282: 0x9d, 0x283: 0x9d, 0x284: 0x9d, 0x285: 0x9d, 0x286: 0x9d, 0x287: 0x9d,
2125 0x288: 0x9d, 0x289: 0x9d, 0x28a: 0x9d, 0x28b: 0x9d, 0x28c: 0x9d, 0x28d: 0x9d, 0x28e: 0x9d, 0x28f: 0x9d,
2126 0x290: 0x9d, 0x291: 0x9d, 0x292: 0x9d, 0x293: 0x9d, 0x294: 0x9d, 0x295: 0x9d, 0x296: 0x9d, 0x297: 0x9d,
2127 0x298: 0x9d, 0x299: 0x9d, 0x29a: 0x9d, 0x29b: 0x9d, 0x29c: 0x9d, 0x29d: 0x9d, 0x29e: 0x9d, 0x29f: 0x9d,
2128 0x2a0: 0x9d, 0x2a1: 0x9d, 0x2a2: 0x9d, 0x2a3: 0x9d, 0x2a4: 0x9d, 0x2a5: 0x9d, 0x2a6: 0x9d, 0x2a7: 0x9d,
2129 0x2a8: 0x9d, 0x2a9: 0x9d, 0x2aa: 0x9d, 0x2ab: 0x9d, 0x2ac: 0x9d, 0x2ad: 0x9d, 0x2ae: 0x9d, 0x2af: 0x9d,
2130 0x2b0: 0x9d, 0x2b1: 0x9d, 0x2b2: 0x9d, 0x2b3: 0x9d, 0x2b4: 0x9d, 0x2b5: 0x9d, 0x2b6: 0x9d, 0x2b7: 0x9d,
2131 0x2b8: 0x9d, 0x2b9: 0x9d, 0x2ba: 0x9d, 0x2bb: 0x9d, 0x2bc: 0x9d, 0x2bd: 0x9d, 0x2be: 0x9d, 0x2bf: 0xe2,
2132 // Block 0xb, offset 0x2c0
2133 0x2c0: 0x9d, 0x2c1: 0x9d, 0x2c2: 0x9d, 0x2c3: 0x9d, 0x2c4: 0x9d, 0x2c5: 0x9d, 0x2c6: 0x9d, 0x2c7: 0x9d,
2134 0x2c8: 0x9d, 0x2c9: 0x9d, 0x2ca: 0x9d, 0x2cb: 0x9d, 0x2cc: 0x9d, 0x2cd: 0x9d, 0x2ce: 0x9d, 0x2cf: 0x9d,
2135 0x2d0: 0x9d, 0x2d1: 0x9d, 0x2d2: 0xe3, 0x2d3: 0xe4, 0x2d4: 0x9d, 0x2d5: 0x9d, 0x2d6: 0x9d, 0x2d7: 0x9d,
2136 0x2d8: 0xe5, 0x2d9: 0x40, 0x2da: 0x41, 0x2db: 0xe6, 0x2dc: 0x42, 0x2dd: 0x43, 0x2de: 0x44, 0x2df: 0xe7,
2137 0x2e0: 0xe8, 0x2e1: 0xe9, 0x2e2: 0xea, 0x2e3: 0xeb, 0x2e4: 0xec, 0x2e5: 0xed, 0x2e6: 0xee, 0x2e7: 0xef,
2138 0x2e8: 0xf0, 0x2e9: 0xf1, 0x2ea: 0xf2, 0x2eb: 0xf3, 0x2ec: 0xf4, 0x2ed: 0xf5, 0x2ee: 0xf6, 0x2ef: 0xf7,
2139 0x2f0: 0x9d, 0x2f1: 0x9d, 0x2f2: 0x9d, 0x2f3: 0x9d, 0x2f4: 0x9d, 0x2f5: 0x9d, 0x2f6: 0x9d, 0x2f7: 0x9d,
2140 0x2f8: 0x9d, 0x2f9: 0x9d, 0x2fa: 0x9d, 0x2fb: 0x9d, 0x2fc: 0x9d, 0x2fd: 0x9d, 0x2fe: 0x9d, 0x2ff: 0x9d,
2141 // Block 0xc, offset 0x300
2142 0x300: 0x9d, 0x301: 0x9d, 0x302: 0x9d, 0x303: 0x9d, 0x304: 0x9d, 0x305: 0x9d, 0x306: 0x9d, 0x307: 0x9d,
2143 0x308: 0x9d, 0x309: 0x9d, 0x30a: 0x9d, 0x30b: 0x9d, 0x30c: 0x9d, 0x30d: 0x9d, 0x30e: 0x9d, 0x30f: 0x9d,
2144 0x310: 0x9d, 0x311: 0x9d, 0x312: 0x9d, 0x313: 0x9d, 0x314: 0x9d, 0x315: 0x9d, 0x316: 0x9d, 0x317: 0x9d,
2145 0x318: 0x9d, 0x319: 0x9d, 0x31a: 0x9d, 0x31b: 0x9d, 0x31c: 0x9d, 0x31d: 0x9d, 0x31e: 0xf8, 0x31f: 0xf9,
2146 // Block 0xd, offset 0x340
2147 0x340: 0xb8, 0x341: 0xb8, 0x342: 0xb8, 0x343: 0xb8, 0x344: 0xb8, 0x345: 0xb8, 0x346: 0xb8, 0x347: 0xb8,
2148 0x348: 0xb8, 0x349: 0xb8, 0x34a: 0xb8, 0x34b: 0xb8, 0x34c: 0xb8, 0x34d: 0xb8, 0x34e: 0xb8, 0x34f: 0xb8,
2149 0x350: 0xb8, 0x351: 0xb8, 0x352: 0xb8, 0x353: 0xb8, 0x354: 0xb8, 0x355: 0xb8, 0x356: 0xb8, 0x357: 0xb8,
2150 0x358: 0xb8, 0x359: 0xb8, 0x35a: 0xb8, 0x35b: 0xb8, 0x35c: 0xb8, 0x35d: 0xb8, 0x35e: 0xb8, 0x35f: 0xb8,
2151 0x360: 0xb8, 0x361: 0xb8, 0x362: 0xb8, 0x363: 0xb8, 0x364: 0xb8, 0x365: 0xb8, 0x366: 0xb8, 0x367: 0xb8,
2152 0x368: 0xb8, 0x369: 0xb8, 0x36a: 0xb8, 0x36b: 0xb8, 0x36c: 0xb8, 0x36d: 0xb8, 0x36e: 0xb8, 0x36f: 0xb8,
2153 0x370: 0xb8, 0x371: 0xb8, 0x372: 0xb8, 0x373: 0xb8, 0x374: 0xb8, 0x375: 0xb8, 0x376: 0xb8, 0x377: 0xb8,
2154 0x378: 0xb8, 0x379: 0xb8, 0x37a: 0xb8, 0x37b: 0xb8, 0x37c: 0xb8, 0x37d: 0xb8, 0x37e: 0xb8, 0x37f: 0xb8,
2155 // Block 0xe, offset 0x380
2156 0x380: 0xb8, 0x381: 0xb8, 0x382: 0xb8, 0x383: 0xb8, 0x384: 0xb8, 0x385: 0xb8, 0x386: 0xb8, 0x387: 0xb8,
2157 0x388: 0xb8, 0x389: 0xb8, 0x38a: 0xb8, 0x38b: 0xb8, 0x38c: 0xb8, 0x38d: 0xb8, 0x38e: 0xb8, 0x38f: 0xb8,
2158 0x390: 0xb8, 0x391: 0xb8, 0x392: 0xb8, 0x393: 0xb8, 0x394: 0xb8, 0x395: 0xb8, 0x396: 0xb8, 0x397: 0xb8,
2159 0x398: 0xb8, 0x399: 0xb8, 0x39a: 0xb8, 0x39b: 0xb8, 0x39c: 0xb8, 0x39d: 0xb8, 0x39e: 0xb8, 0x39f: 0xb8,
2160 0x3a0: 0xb8, 0x3a1: 0xb8, 0x3a2: 0xb8, 0x3a3: 0xb8, 0x3a4: 0xfa, 0x3a5: 0xfb, 0x3a6: 0xfc, 0x3a7: 0xfd,
2161 0x3a8: 0x45, 0x3a9: 0xfe, 0x3aa: 0xff, 0x3ab: 0x46, 0x3ac: 0x47, 0x3ad: 0x48, 0x3ae: 0x49, 0x3af: 0x4a,
2162 0x3b0: 0x100, 0x3b1: 0x4b, 0x3b2: 0x4c, 0x3b3: 0x4d, 0x3b4: 0x4e, 0x3b5: 0x4f, 0x3b6: 0x101, 0x3b7: 0x50,
2163 0x3b8: 0x51, 0x3b9: 0x52, 0x3ba: 0x53, 0x3bb: 0x54, 0x3bc: 0x55, 0x3bd: 0x56, 0x3be: 0x57, 0x3bf: 0x58,
2164 // Block 0xf, offset 0x3c0
2165 0x3c0: 0x102, 0x3c1: 0x103, 0x3c2: 0x9d, 0x3c3: 0x104, 0x3c4: 0x105, 0x3c5: 0x9b, 0x3c6: 0x106, 0x3c7: 0x107,
2166 0x3c8: 0xb8, 0x3c9: 0xb8, 0x3ca: 0x108, 0x3cb: 0x109, 0x3cc: 0x10a, 0x3cd: 0x10b, 0x3ce: 0x10c, 0x3cf: 0x10d,
2167 0x3d0: 0x10e, 0x3d1: 0x9d, 0x3d2: 0x10f, 0x3d3: 0x110, 0x3d4: 0x111, 0x3d5: 0x112, 0x3d6: 0xb8, 0x3d7: 0xb8,
2168 0x3d8: 0x9d, 0x3d9: 0x9d, 0x3da: 0x9d, 0x3db: 0x9d, 0x3dc: 0x113, 0x3dd: 0x114, 0x3de: 0xb8, 0x3df: 0xb8,
2169 0x3e0: 0x115, 0x3e1: 0x116, 0x3e2: 0x117, 0x3e3: 0x118, 0x3e4: 0x119, 0x3e5: 0xb8, 0x3e6: 0x11a, 0x3e7: 0x11b,
2170 0x3e8: 0x11c, 0x3e9: 0x11d, 0x3ea: 0x11e, 0x3eb: 0x59, 0x3ec: 0x11f, 0x3ed: 0x120, 0x3ee: 0x5a, 0x3ef: 0xb8,
2171 0x3f0: 0x9d, 0x3f1: 0x121, 0x3f2: 0x122, 0x3f3: 0x123, 0x3f4: 0xb8, 0x3f5: 0xb8, 0x3f6: 0xb8, 0x3f7: 0xb8,
2172 0x3f8: 0xb8, 0x3f9: 0x124, 0x3fa: 0xb8, 0x3fb: 0xb8, 0x3fc: 0xb8, 0x3fd: 0xb8, 0x3fe: 0xb8, 0x3ff: 0xb8,
2173 // Block 0x10, offset 0x400
2174 0x400: 0x125, 0x401: 0x126, 0x402: 0x127, 0x403: 0x128, 0x404: 0x129, 0x405: 0x12a, 0x406: 0x12b, 0x407: 0x12c,
2175 0x408: 0x12d, 0x409: 0xb8, 0x40a: 0x12e, 0x40b: 0x12f, 0x40c: 0x5b, 0x40d: 0x5c, 0x40e: 0xb8, 0x40f: 0xb8,
2176 0x410: 0x130, 0x411: 0x131, 0x412: 0x132, 0x413: 0x133, 0x414: 0xb8, 0x415: 0xb8, 0x416: 0x134, 0x417: 0x135,
2177 0x418: 0x136, 0x419: 0x137, 0x41a: 0x138, 0x41b: 0x139, 0x41c: 0x13a, 0x41d: 0xb8, 0x41e: 0xb8, 0x41f: 0xb8,
2178 0x420: 0xb8, 0x421: 0xb8, 0x422: 0x13b, 0x423: 0x13c, 0x424: 0xb8, 0x425: 0xb8, 0x426: 0xb8, 0x427: 0xb8,
2179 0x428: 0xb8, 0x429: 0xb8, 0x42a: 0xb8, 0x42b: 0x13d, 0x42c: 0xb8, 0x42d: 0xb8, 0x42e: 0xb8, 0x42f: 0xb8,
2180 0x430: 0x13e, 0x431: 0x13f, 0x432: 0x140, 0x433: 0xb8, 0x434: 0xb8, 0x435: 0xb8, 0x436: 0xb8, 0x437: 0xb8,
2181 0x438: 0xb8, 0x439: 0xb8, 0x43a: 0xb8, 0x43b: 0xb8, 0x43c: 0xb8, 0x43d: 0xb8, 0x43e: 0xb8, 0x43f: 0xb8,
2182 // Block 0x11, offset 0x440
2183 0x440: 0x9d, 0x441: 0x9d, 0x442: 0x9d, 0x443: 0x9d, 0x444: 0x9d, 0x445: 0x9d, 0x446: 0x9d, 0x447: 0x9d,
2184 0x448: 0x9d, 0x449: 0x9d, 0x44a: 0x9d, 0x44b: 0x9d, 0x44c: 0x9d, 0x44d: 0x9d, 0x44e: 0x141, 0x44f: 0xb8,
2185 0x450: 0x9b, 0x451: 0x142, 0x452: 0x9d, 0x453: 0x9d, 0x454: 0x9d, 0x455: 0x143, 0x456: 0xb8, 0x457: 0xb8,
2186 0x458: 0xb8, 0x459: 0xb8, 0x45a: 0xb8, 0x45b: 0xb8, 0x45c: 0xb8, 0x45d: 0xb8, 0x45e: 0xb8, 0x45f: 0xb8,
2187 0x460: 0xb8, 0x461: 0xb8, 0x462: 0xb8, 0x463: 0xb8, 0x464: 0xb8, 0x465: 0xb8, 0x466: 0xb8, 0x467: 0xb8,
2188 0x468: 0xb8, 0x469: 0xb8, 0x46a: 0xb8, 0x46b: 0xb8, 0x46c: 0xb8, 0x46d: 0xb8, 0x46e: 0xb8, 0x46f: 0xb8,
2189 0x470: 0xb8, 0x471: 0xb8, 0x472: 0xb8, 0x473: 0xb8, 0x474: 0xb8, 0x475: 0xb8, 0x476: 0xb8, 0x477: 0xb8,
2190 0x478: 0xb8, 0x479: 0xb8, 0x47a: 0xb8, 0x47b: 0xb8, 0x47c: 0xb8, 0x47d: 0xb8, 0x47e: 0xb8, 0x47f: 0xb8,
2191 // Block 0x12, offset 0x480
2192 0x480: 0x9d, 0x481: 0x9d, 0x482: 0x9d, 0x483: 0x9d, 0x484: 0x9d, 0x485: 0x9d, 0x486: 0x9d, 0x487: 0x9d,
2193 0x488: 0x9d, 0x489: 0x9d, 0x48a: 0x9d, 0x48b: 0x9d, 0x48c: 0x9d, 0x48d: 0x9d, 0x48e: 0x9d, 0x48f: 0x9d,
2194 0x490: 0x144, 0x491: 0xb8, 0x492: 0xb8, 0x493: 0xb8, 0x494: 0xb8, 0x495: 0xb8, 0x496: 0xb8, 0x497: 0xb8,
2195 0x498: 0xb8, 0x499: 0xb8, 0x49a: 0xb8, 0x49b: 0xb8, 0x49c: 0xb8, 0x49d: 0xb8, 0x49e: 0xb8, 0x49f: 0xb8,
2196 0x4a0: 0xb8, 0x4a1: 0xb8, 0x4a2: 0xb8, 0x4a3: 0xb8, 0x4a4: 0xb8, 0x4a5: 0xb8, 0x4a6: 0xb8, 0x4a7: 0xb8,
2197 0x4a8: 0xb8, 0x4a9: 0xb8, 0x4aa: 0xb8, 0x4ab: 0xb8, 0x4ac: 0xb8, 0x4ad: 0xb8, 0x4ae: 0xb8, 0x4af: 0xb8,
2198 0x4b0: 0xb8, 0x4b1: 0xb8, 0x4b2: 0xb8, 0x4b3: 0xb8, 0x4b4: 0xb8, 0x4b5: 0xb8, 0x4b6: 0xb8, 0x4b7: 0xb8,
2199 0x4b8: 0xb8, 0x4b9: 0xb8, 0x4ba: 0xb8, 0x4bb: 0xb8, 0x4bc: 0xb8, 0x4bd: 0xb8, 0x4be: 0xb8, 0x4bf: 0xb8,
2200 // Block 0x13, offset 0x4c0
2201 0x4c0: 0xb8, 0x4c1: 0xb8, 0x4c2: 0xb8, 0x4c3: 0xb8, 0x4c4: 0xb8, 0x4c5: 0xb8, 0x4c6: 0xb8, 0x4c7: 0xb8,
2202 0x4c8: 0xb8, 0x4c9: 0xb8, 0x4ca: 0xb8, 0x4cb: 0xb8, 0x4cc: 0xb8, 0x4cd: 0xb8, 0x4ce: 0xb8, 0x4cf: 0xb8,
2203 0x4d0: 0x9d, 0x4d1: 0x9d, 0x4d2: 0x9d, 0x4d3: 0x9d, 0x4d4: 0x9d, 0x4d5: 0x9d, 0x4d6: 0x9d, 0x4d7: 0x9d,
2204 0x4d8: 0x9d, 0x4d9: 0x145, 0x4da: 0xb8, 0x4db: 0xb8, 0x4dc: 0xb8, 0x4dd: 0xb8, 0x4de: 0xb8, 0x4df: 0xb8,
2205 0x4e0: 0xb8, 0x4e1: 0xb8, 0x4e2: 0xb8, 0x4e3: 0xb8, 0x4e4: 0xb8, 0x4e5: 0xb8, 0x4e6: 0xb8, 0x4e7: 0xb8,
2206 0x4e8: 0xb8, 0x4e9: 0xb8, 0x4ea: 0xb8, 0x4eb: 0xb8, 0x4ec: 0xb8, 0x4ed: 0xb8, 0x4ee: 0xb8, 0x4ef: 0xb8,
2207 0x4f0: 0xb8, 0x4f1: 0xb8, 0x4f2: 0xb8, 0x4f3: 0xb8, 0x4f4: 0xb8, 0x4f5: 0xb8, 0x4f6: 0xb8, 0x4f7: 0xb8,
2208 0x4f8: 0xb8, 0x4f9: 0xb8, 0x4fa: 0xb8, 0x4fb: 0xb8, 0x4fc: 0xb8, 0x4fd: 0xb8, 0x4fe: 0xb8, 0x4ff: 0xb8,
2209 // Block 0x14, offset 0x500
2210 0x500: 0xb8, 0x501: 0xb8, 0x502: 0xb8, 0x503: 0xb8, 0x504: 0xb8, 0x505: 0xb8, 0x506: 0xb8, 0x507: 0xb8,
2211 0x508: 0xb8, 0x509: 0xb8, 0x50a: 0xb8, 0x50b: 0xb8, 0x50c: 0xb8, 0x50d: 0xb8, 0x50e: 0xb8, 0x50f: 0xb8,
2212 0x510: 0xb8, 0x511: 0xb8, 0x512: 0xb8, 0x513: 0xb8, 0x514: 0xb8, 0x515: 0xb8, 0x516: 0xb8, 0x517: 0xb8,
2213 0x518: 0xb8, 0x519: 0xb8, 0x51a: 0xb8, 0x51b: 0xb8, 0x51c: 0xb8, 0x51d: 0xb8, 0x51e: 0xb8, 0x51f: 0xb8,
2214 0x520: 0x9d, 0x521: 0x9d, 0x522: 0x9d, 0x523: 0x9d, 0x524: 0x9d, 0x525: 0x9d, 0x526: 0x9d, 0x527: 0x9d,
2215 0x528: 0x13d, 0x529: 0x146, 0x52a: 0xb8, 0x52b: 0x147, 0x52c: 0x148, 0x52d: 0x149, 0x52e: 0x14a, 0x52f: 0xb8,
2216 0x530: 0xb8, 0x531: 0xb8, 0x532: 0xb8, 0x533: 0xb8, 0x534: 0xb8, 0x535: 0xb8, 0x536: 0xb8, 0x537: 0xb8,
2217 0x538: 0xb8, 0x539: 0xb8, 0x53a: 0xb8, 0x53b: 0xb8, 0x53c: 0x9d, 0x53d: 0x14b, 0x53e: 0x14c, 0x53f: 0x14d,
2218 // Block 0x15, offset 0x540
2219 0x540: 0x9d, 0x541: 0x9d, 0x542: 0x9d, 0x543: 0x9d, 0x544: 0x9d, 0x545: 0x9d, 0x546: 0x9d, 0x547: 0x9d,
2220 0x548: 0x9d, 0x549: 0x9d, 0x54a: 0x9d, 0x54b: 0x9d, 0x54c: 0x9d, 0x54d: 0x9d, 0x54e: 0x9d, 0x54f: 0x9d,
2221 0x550: 0x9d, 0x551: 0x9d, 0x552: 0x9d, 0x553: 0x9d, 0x554: 0x9d, 0x555: 0x9d, 0x556: 0x9d, 0x557: 0x9d,
2222 0x558: 0x9d, 0x559: 0x9d, 0x55a: 0x9d, 0x55b: 0x9d, 0x55c: 0x9d, 0x55d: 0x9d, 0x55e: 0x9d, 0x55f: 0x14e,
2223 0x560: 0x9d, 0x561: 0x9d, 0x562: 0x9d, 0x563: 0x9d, 0x564: 0x9d, 0x565: 0x9d, 0x566: 0x9d, 0x567: 0x9d,
2224 0x568: 0x9d, 0x569: 0x9d, 0x56a: 0x9d, 0x56b: 0x14f, 0x56c: 0xb8, 0x56d: 0xb8, 0x56e: 0xb8, 0x56f: 0xb8,
2225 0x570: 0xb8, 0x571: 0xb8, 0x572: 0xb8, 0x573: 0xb8, 0x574: 0xb8, 0x575: 0xb8, 0x576: 0xb8, 0x577: 0xb8,
2226 0x578: 0xb8, 0x579: 0xb8, 0x57a: 0xb8, 0x57b: 0xb8, 0x57c: 0xb8, 0x57d: 0xb8, 0x57e: 0xb8, 0x57f: 0xb8,
2227 // Block 0x16, offset 0x580
2228 0x580: 0x150, 0x581: 0xb8, 0x582: 0xb8, 0x583: 0xb8, 0x584: 0xb8, 0x585: 0xb8, 0x586: 0xb8, 0x587: 0xb8,
2229 0x588: 0xb8, 0x589: 0xb8, 0x58a: 0xb8, 0x58b: 0xb8, 0x58c: 0xb8, 0x58d: 0xb8, 0x58e: 0xb8, 0x58f: 0xb8,
2230 0x590: 0xb8, 0x591: 0xb8, 0x592: 0xb8, 0x593: 0xb8, 0x594: 0xb8, 0x595: 0xb8, 0x596: 0xb8, 0x597: 0xb8,
2231 0x598: 0xb8, 0x599: 0xb8, 0x59a: 0xb8, 0x59b: 0xb8, 0x59c: 0xb8, 0x59d: 0xb8, 0x59e: 0xb8, 0x59f: 0xb8,
2232 0x5a0: 0xb8, 0x5a1: 0xb8, 0x5a2: 0xb8, 0x5a3: 0xb8, 0x5a4: 0xb8, 0x5a5: 0xb8, 0x5a6: 0xb8, 0x5a7: 0xb8,
2233 0x5a8: 0xb8, 0x5a9: 0xb8, 0x5aa: 0xb8, 0x5ab: 0xb8, 0x5ac: 0xb8, 0x5ad: 0xb8, 0x5ae: 0xb8, 0x5af: 0xb8,
2234 0x5b0: 0x9d, 0x5b1: 0x151, 0x5b2: 0x152, 0x5b3: 0xb8, 0x5b4: 0xb8, 0x5b5: 0xb8, 0x5b6: 0xb8, 0x5b7: 0xb8,
2235 0x5b8: 0xb8, 0x5b9: 0xb8, 0x5ba: 0xb8, 0x5bb: 0xb8, 0x5bc: 0xb8, 0x5bd: 0xb8, 0x5be: 0xb8, 0x5bf: 0xb8,
2236 // Block 0x17, offset 0x5c0
2237 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x153, 0x5c4: 0x154, 0x5c5: 0x155, 0x5c6: 0x156, 0x5c7: 0x157,
2238 0x5c8: 0x9b, 0x5c9: 0x158, 0x5ca: 0xb8, 0x5cb: 0xb8, 0x5cc: 0x9b, 0x5cd: 0x159, 0x5ce: 0xb8, 0x5cf: 0xb8,
2239 0x5d0: 0x5d, 0x5d1: 0x5e, 0x5d2: 0x5f, 0x5d3: 0x60, 0x5d4: 0x61, 0x5d5: 0x62, 0x5d6: 0x63, 0x5d7: 0x64,
2240 0x5d8: 0x65, 0x5d9: 0x66, 0x5da: 0x67, 0x5db: 0x68, 0x5dc: 0x69, 0x5dd: 0x6a, 0x5de: 0x6b, 0x5df: 0x6c,
2241 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,
2242 0x5e8: 0x15a, 0x5e9: 0x15b, 0x5ea: 0x15c, 0x5eb: 0xb8, 0x5ec: 0xb8, 0x5ed: 0xb8, 0x5ee: 0xb8, 0x5ef: 0xb8,
2243 0x5f0: 0xb8, 0x5f1: 0xb8, 0x5f2: 0xb8, 0x5f3: 0xb8, 0x5f4: 0xb8, 0x5f5: 0xb8, 0x5f6: 0xb8, 0x5f7: 0xb8,
2244 0x5f8: 0xb8, 0x5f9: 0xb8, 0x5fa: 0xb8, 0x5fb: 0xb8, 0x5fc: 0xb8, 0x5fd: 0xb8, 0x5fe: 0xb8, 0x5ff: 0xb8,
2245 // Block 0x18, offset 0x600
2246 0x600: 0x15d, 0x601: 0xb8, 0x602: 0xb8, 0x603: 0xb8, 0x604: 0xb8, 0x605: 0xb8, 0x606: 0xb8, 0x607: 0xb8,
2247 0x608: 0xb8, 0x609: 0xb8, 0x60a: 0xb8, 0x60b: 0xb8, 0x60c: 0xb8, 0x60d: 0xb8, 0x60e: 0xb8, 0x60f: 0xb8,
2248 0x610: 0xb8, 0x611: 0xb8, 0x612: 0xb8, 0x613: 0xb8, 0x614: 0xb8, 0x615: 0xb8, 0x616: 0xb8, 0x617: 0xb8,
2249 0x618: 0xb8, 0x619: 0xb8, 0x61a: 0xb8, 0x61b: 0xb8, 0x61c: 0xb8, 0x61d: 0xb8, 0x61e: 0xb8, 0x61f: 0xb8,
2250 0x620: 0x9d, 0x621: 0x9d, 0x622: 0x9d, 0x623: 0x15e, 0x624: 0x6d, 0x625: 0x15f, 0x626: 0xb8, 0x627: 0xb8,
2251 0x628: 0xb8, 0x629: 0xb8, 0x62a: 0xb8, 0x62b: 0xb8, 0x62c: 0xb8, 0x62d: 0xb8, 0x62e: 0xb8, 0x62f: 0xb8,
2252 0x630: 0xb8, 0x631: 0xb8, 0x632: 0xb8, 0x633: 0xb8, 0x634: 0xb8, 0x635: 0xb8, 0x636: 0xb8, 0x637: 0xb8,
2253 0x638: 0x6e, 0x639: 0x6f, 0x63a: 0x70, 0x63b: 0x160, 0x63c: 0xb8, 0x63d: 0xb8, 0x63e: 0xb8, 0x63f: 0xb8,
2254 // Block 0x19, offset 0x640
2255 0x640: 0x161, 0x641: 0x9b, 0x642: 0x162, 0x643: 0x163, 0x644: 0x71, 0x645: 0x72, 0x646: 0x164, 0x647: 0x165,
2256 0x648: 0x73, 0x649: 0x166, 0x64a: 0xb8, 0x64b: 0xb8, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,
2257 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,
2258 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x167, 0x65c: 0x9b, 0x65d: 0x168, 0x65e: 0x9b, 0x65f: 0x169,
2259 0x660: 0x16a, 0x661: 0x16b, 0x662: 0x16c, 0x663: 0xb8, 0x664: 0x16d, 0x665: 0x16e, 0x666: 0x16f, 0x667: 0x170,
2260 0x668: 0xb8, 0x669: 0xb8, 0x66a: 0xb8, 0x66b: 0xb8, 0x66c: 0xb8, 0x66d: 0xb8, 0x66e: 0xb8, 0x66f: 0xb8,
2261 0x670: 0xb8, 0x671: 0xb8, 0x672: 0xb8, 0x673: 0xb8, 0x674: 0xb8, 0x675: 0xb8, 0x676: 0xb8, 0x677: 0xb8,
2262 0x678: 0xb8, 0x679: 0xb8, 0x67a: 0xb8, 0x67b: 0xb8, 0x67c: 0xb8, 0x67d: 0xb8, 0x67e: 0xb8, 0x67f: 0xb8,
2263 // Block 0x1a, offset 0x680
2264 0x680: 0x9d, 0x681: 0x9d, 0x682: 0x9d, 0x683: 0x9d, 0x684: 0x9d, 0x685: 0x9d, 0x686: 0x9d, 0x687: 0x9d,
2265 0x688: 0x9d, 0x689: 0x9d, 0x68a: 0x9d, 0x68b: 0x9d, 0x68c: 0x9d, 0x68d: 0x9d, 0x68e: 0x9d, 0x68f: 0x9d,
2266 0x690: 0x9d, 0x691: 0x9d, 0x692: 0x9d, 0x693: 0x9d, 0x694: 0x9d, 0x695: 0x9d, 0x696: 0x9d, 0x697: 0x9d,
2267 0x698: 0x9d, 0x699: 0x9d, 0x69a: 0x9d, 0x69b: 0x171, 0x69c: 0x9d, 0x69d: 0x9d, 0x69e: 0x9d, 0x69f: 0x9d,
2268 0x6a0: 0x9d, 0x6a1: 0x9d, 0x6a2: 0x9d, 0x6a3: 0x9d, 0x6a4: 0x9d, 0x6a5: 0x9d, 0x6a6: 0x9d, 0x6a7: 0x9d,
2269 0x6a8: 0x9d, 0x6a9: 0x9d, 0x6aa: 0x9d, 0x6ab: 0x9d, 0x6ac: 0x9d, 0x6ad: 0x9d, 0x6ae: 0x9d, 0x6af: 0x9d,
2270 0x6b0: 0x9d, 0x6b1: 0x9d, 0x6b2: 0x9d, 0x6b3: 0x9d, 0x6b4: 0x9d, 0x6b5: 0x9d, 0x6b6: 0x9d, 0x6b7: 0x9d,
2271 0x6b8: 0x9d, 0x6b9: 0x9d, 0x6ba: 0x9d, 0x6bb: 0x9d, 0x6bc: 0x9d, 0x6bd: 0x9d, 0x6be: 0x9d, 0x6bf: 0x9d,
2272 // Block 0x1b, offset 0x6c0
2273 0x6c0: 0x9d, 0x6c1: 0x9d, 0x6c2: 0x9d, 0x6c3: 0x9d, 0x6c4: 0x9d, 0x6c5: 0x9d, 0x6c6: 0x9d, 0x6c7: 0x9d,
2274 0x6c8: 0x9d, 0x6c9: 0x9d, 0x6ca: 0x9d, 0x6cb: 0x9d, 0x6cc: 0x9d, 0x6cd: 0x9d, 0x6ce: 0x9d, 0x6cf: 0x9d,
2275 0x6d0: 0x9d, 0x6d1: 0x9d, 0x6d2: 0x9d, 0x6d3: 0x9d, 0x6d4: 0x9d, 0x6d5: 0x9d, 0x6d6: 0x9d, 0x6d7: 0x9d,
2276 0x6d8: 0x9d, 0x6d9: 0x9d, 0x6da: 0x9d, 0x6db: 0x9d, 0x6dc: 0x172, 0x6dd: 0x9d, 0x6de: 0x9d, 0x6df: 0x9d,
2277 0x6e0: 0x173, 0x6e1: 0x9d, 0x6e2: 0x9d, 0x6e3: 0x9d, 0x6e4: 0x9d, 0x6e5: 0x9d, 0x6e6: 0x9d, 0x6e7: 0x9d,
2278 0x6e8: 0x9d, 0x6e9: 0x9d, 0x6ea: 0x9d, 0x6eb: 0x9d, 0x6ec: 0x9d, 0x6ed: 0x9d, 0x6ee: 0x9d, 0x6ef: 0x9d,
2279 0x6f0: 0x9d, 0x6f1: 0x9d, 0x6f2: 0x9d, 0x6f3: 0x9d, 0x6f4: 0x9d, 0x6f5: 0x9d, 0x6f6: 0x9d, 0x6f7: 0x9d,
2280 0x6f8: 0x9d, 0x6f9: 0x9d, 0x6fa: 0x9d, 0x6fb: 0x9d, 0x6fc: 0x9d, 0x6fd: 0x9d, 0x6fe: 0x9d, 0x6ff: 0x9d,
2281 // Block 0x1c, offset 0x700
2282 0x700: 0x9d, 0x701: 0x9d, 0x702: 0x9d, 0x703: 0x9d, 0x704: 0x9d, 0x705: 0x9d, 0x706: 0x9d, 0x707: 0x9d,
2283 0x708: 0x9d, 0x709: 0x9d, 0x70a: 0x9d, 0x70b: 0x9d, 0x70c: 0x9d, 0x70d: 0x9d, 0x70e: 0x9d, 0x70f: 0x9d,
2284 0x710: 0x9d, 0x711: 0x9d, 0x712: 0x9d, 0x713: 0x9d, 0x714: 0x9d, 0x715: 0x9d, 0x716: 0x9d, 0x717: 0x9d,
2285 0x718: 0x9d, 0x719: 0x9d, 0x71a: 0x9d, 0x71b: 0x9d, 0x71c: 0x9d, 0x71d: 0x9d, 0x71e: 0x9d, 0x71f: 0x9d,
2286 0x720: 0x9d, 0x721: 0x9d, 0x722: 0x9d, 0x723: 0x9d, 0x724: 0x9d, 0x725: 0x9d, 0x726: 0x9d, 0x727: 0x9d,
2287 0x728: 0x9d, 0x729: 0x9d, 0x72a: 0x9d, 0x72b: 0x9d, 0x72c: 0x9d, 0x72d: 0x9d, 0x72e: 0x9d, 0x72f: 0x9d,
2288 0x730: 0x9d, 0x731: 0x9d, 0x732: 0x9d, 0x733: 0x9d, 0x734: 0x9d, 0x735: 0x9d, 0x736: 0x9d, 0x737: 0x9d,
2289 0x738: 0x9d, 0x739: 0x9d, 0x73a: 0x174, 0x73b: 0xb8, 0x73c: 0xb8, 0x73d: 0xb8, 0x73e: 0xb8, 0x73f: 0xb8,
2290 // Block 0x1d, offset 0x740
2291 0x740: 0xb8, 0x741: 0xb8, 0x742: 0xb8, 0x743: 0xb8, 0x744: 0xb8, 0x745: 0xb8, 0x746: 0xb8, 0x747: 0xb8,
2292 0x748: 0xb8, 0x749: 0xb8, 0x74a: 0xb8, 0x74b: 0xb8, 0x74c: 0xb8, 0x74d: 0xb8, 0x74e: 0xb8, 0x74f: 0xb8,
2293 0x750: 0xb8, 0x751: 0xb8, 0x752: 0xb8, 0x753: 0xb8, 0x754: 0xb8, 0x755: 0xb8, 0x756: 0xb8, 0x757: 0xb8,
2294 0x758: 0xb8, 0x759: 0xb8, 0x75a: 0xb8, 0x75b: 0xb8, 0x75c: 0xb8, 0x75d: 0xb8, 0x75e: 0xb8, 0x75f: 0xb8,
2295 0x760: 0x74, 0x761: 0x75, 0x762: 0x76, 0x763: 0x175, 0x764: 0x77, 0x765: 0x78, 0x766: 0x176, 0x767: 0x79,
2296 0x768: 0x7a, 0x769: 0xb8, 0x76a: 0xb8, 0x76b: 0xb8, 0x76c: 0xb8, 0x76d: 0xb8, 0x76e: 0xb8, 0x76f: 0xb8,
2297 0x770: 0xb8, 0x771: 0xb8, 0x772: 0xb8, 0x773: 0xb8, 0x774: 0xb8, 0x775: 0xb8, 0x776: 0xb8, 0x777: 0xb8,
2298 0x778: 0xb8, 0x779: 0xb8, 0x77a: 0xb8, 0x77b: 0xb8, 0x77c: 0xb8, 0x77d: 0xb8, 0x77e: 0xb8, 0x77f: 0xb8,
2299 // Block 0x1e, offset 0x780
2300 0x790: 0x0d, 0x791: 0x0e, 0x792: 0x0f, 0x793: 0x10, 0x794: 0x11, 0x795: 0x0b, 0x796: 0x12, 0x797: 0x07,
2301 0x798: 0x13, 0x799: 0x0b, 0x79a: 0x0b, 0x79b: 0x14, 0x79c: 0x0b, 0x79d: 0x15, 0x79e: 0x16, 0x79f: 0x17,
2302 0x7a0: 0x07, 0x7a1: 0x07, 0x7a2: 0x07, 0x7a3: 0x07, 0x7a4: 0x07, 0x7a5: 0x07, 0x7a6: 0x07, 0x7a7: 0x07,
2303 0x7a8: 0x07, 0x7a9: 0x07, 0x7aa: 0x18, 0x7ab: 0x19, 0x7ac: 0x1a, 0x7ad: 0x0b, 0x7ae: 0x0b, 0x7af: 0x1b,
2304 0x7b0: 0x0b, 0x7b1: 0x0b, 0x7b2: 0x0b, 0x7b3: 0x0b, 0x7b4: 0x0b, 0x7b5: 0x0b, 0x7b6: 0x0b, 0x7b7: 0x0b,
2305 0x7b8: 0x0b, 0x7b9: 0x0b, 0x7ba: 0x0b, 0x7bb: 0x0b, 0x7bc: 0x0b, 0x7bd: 0x0b, 0x7be: 0x0b, 0x7bf: 0x0b,
2306 // Block 0x1f, offset 0x7c0
2307 0x7c0: 0x0b, 0x7c1: 0x0b, 0x7c2: 0x0b, 0x7c3: 0x0b, 0x7c4: 0x0b, 0x7c5: 0x0b, 0x7c6: 0x0b, 0x7c7: 0x0b,
2308 0x7c8: 0x0b, 0x7c9: 0x0b, 0x7ca: 0x0b, 0x7cb: 0x0b, 0x7cc: 0x0b, 0x7cd: 0x0b, 0x7ce: 0x0b, 0x7cf: 0x0b,
2309 0x7d0: 0x0b, 0x7d1: 0x0b, 0x7d2: 0x0b, 0x7d3: 0x0b, 0x7d4: 0x0b, 0x7d5: 0x0b, 0x7d6: 0x0b, 0x7d7: 0x0b,
2310 0x7d8: 0x0b, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x0b, 0x7dc: 0x0b, 0x7dd: 0x0b, 0x7de: 0x0b, 0x7df: 0x0b,
2311 0x7e0: 0x0b, 0x7e1: 0x0b, 0x7e2: 0x0b, 0x7e3: 0x0b, 0x7e4: 0x0b, 0x7e5: 0x0b, 0x7e6: 0x0b, 0x7e7: 0x0b,
2312 0x7e8: 0x0b, 0x7e9: 0x0b, 0x7ea: 0x0b, 0x7eb: 0x0b, 0x7ec: 0x0b, 0x7ed: 0x0b, 0x7ee: 0x0b, 0x7ef: 0x0b,
2313 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,
2314 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,
2315 // Block 0x20, offset 0x800
2316 0x800: 0x177, 0x801: 0x178, 0x802: 0xb8, 0x803: 0xb8, 0x804: 0x179, 0x805: 0x179, 0x806: 0x179, 0x807: 0x17a,
2317 0x808: 0xb8, 0x809: 0xb8, 0x80a: 0xb8, 0x80b: 0xb8, 0x80c: 0xb8, 0x80d: 0xb8, 0x80e: 0xb8, 0x80f: 0xb8,
2318 0x810: 0xb8, 0x811: 0xb8, 0x812: 0xb8, 0x813: 0xb8, 0x814: 0xb8, 0x815: 0xb8, 0x816: 0xb8, 0x817: 0xb8,
2319 0x818: 0xb8, 0x819: 0xb8, 0x81a: 0xb8, 0x81b: 0xb8, 0x81c: 0xb8, 0x81d: 0xb8, 0x81e: 0xb8, 0x81f: 0xb8,
2320 0x820: 0xb8, 0x821: 0xb8, 0x822: 0xb8, 0x823: 0xb8, 0x824: 0xb8, 0x825: 0xb8, 0x826: 0xb8, 0x827: 0xb8,
2321 0x828: 0xb8, 0x829: 0xb8, 0x82a: 0xb8, 0x82b: 0xb8, 0x82c: 0xb8, 0x82d: 0xb8, 0x82e: 0xb8, 0x82f: 0xb8,
2322 0x830: 0xb8, 0x831: 0xb8, 0x832: 0xb8, 0x833: 0xb8, 0x834: 0xb8, 0x835: 0xb8, 0x836: 0xb8, 0x837: 0xb8,
2323 0x838: 0xb8, 0x839: 0xb8, 0x83a: 0xb8, 0x83b: 0xb8, 0x83c: 0xb8, 0x83d: 0xb8, 0x83e: 0xb8, 0x83f: 0xb8,
2324 // Block 0x21, offset 0x840
2325 0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b,
2326 0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b,
2327 0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b,
2328 0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b,
2329 0x860: 0x1e, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b,
2330 0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b,
2331 0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b,
2332 0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b,
2333 // Block 0x22, offset 0x880
2334 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,
2335 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,
2336}
2337
2338// idnaSparseOffset: 256 entries, 512 bytes
2339var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x5c, 0x60, 0x6f, 0x74, 0x7b, 0x87, 0x95, 0xa3, 0xa8, 0xb1, 0xc1, 0xcf, 0xdc, 0xe8, 0xf9, 0x103, 0x10a, 0x117, 0x128, 0x12f, 0x13a, 0x149, 0x157, 0x161, 0x163, 0x167, 0x169, 0x175, 0x180, 0x188, 0x18e, 0x194, 0x199, 0x19e, 0x1a1, 0x1a5, 0x1ab, 0x1b0, 0x1bc, 0x1c6, 0x1cc, 0x1dd, 0x1e7, 0x1ea, 0x1f2, 0x1f5, 0x202, 0x20a, 0x20e, 0x215, 0x21d, 0x22d, 0x239, 0x23b, 0x245, 0x251, 0x25d, 0x269, 0x271, 0x276, 0x280, 0x291, 0x295, 0x2a0, 0x2a4, 0x2ad, 0x2b5, 0x2bb, 0x2c0, 0x2c3, 0x2c6, 0x2ca, 0x2d0, 0x2d4, 0x2d8, 0x2de, 0x2e5, 0x2eb, 0x2f3, 0x2fa, 0x305, 0x30f, 0x313, 0x316, 0x31c, 0x320, 0x322, 0x325, 0x327, 0x32a, 0x334, 0x337, 0x346, 0x34a, 0x34f, 0x352, 0x356, 0x35b, 0x360, 0x366, 0x36c, 0x37b, 0x381, 0x385, 0x394, 0x399, 0x3a1, 0x3ab, 0x3b6, 0x3be, 0x3cf, 0x3d8, 0x3e8, 0x3f5, 0x3ff, 0x404, 0x411, 0x415, 0x41a, 0x41c, 0x420, 0x422, 0x426, 0x42f, 0x435, 0x439, 0x449, 0x453, 0x458, 0x45b, 0x461, 0x468, 0x46d, 0x471, 0x477, 0x47c, 0x485, 0x48a, 0x490, 0x497, 0x49e, 0x4a5, 0x4a9, 0x4ae, 0x4b1, 0x4b6, 0x4c2, 0x4c8, 0x4cd, 0x4d4, 0x4dc, 0x4e1, 0x4e5, 0x4f5, 0x4fc, 0x500, 0x504, 0x50b, 0x50e, 0x511, 0x515, 0x519, 0x51f, 0x528, 0x534, 0x53b, 0x544, 0x54c, 0x553, 0x561, 0x56e, 0x57b, 0x584, 0x588, 0x596, 0x59e, 0x5a9, 0x5b2, 0x5b8, 0x5c0, 0x5c9, 0x5d3, 0x5d6, 0x5e2, 0x5e5, 0x5ea, 0x5ed, 0x5f7, 0x600, 0x60c, 0x60f, 0x614, 0x617, 0x61a, 0x61d, 0x624, 0x62b, 0x62f, 0x63a, 0x63d, 0x643, 0x648, 0x64c, 0x64f, 0x652, 0x655, 0x65a, 0x664, 0x667, 0x66b, 0x67a, 0x686, 0x68a, 0x68f, 0x694, 0x698, 0x69d, 0x6a6, 0x6b1, 0x6b7, 0x6bf, 0x6c3, 0x6c7, 0x6cd, 0x6d3, 0x6d8, 0x6db, 0x6e9, 0x6f0, 0x6f3, 0x6f6, 0x6fa, 0x700, 0x705, 0x70f, 0x714, 0x717, 0x71a, 0x71d, 0x720, 0x724, 0x727, 0x737, 0x748, 0x74d, 0x74f, 0x751}
2340
2341// idnaSparseValues: 1876 entries, 7504 bytes
2342var idnaSparseValues = [1876]valueRange{
2343 // Block 0x0, offset 0x0
2344 {value: 0x0000, lo: 0x07},
2345 {value: 0xe105, lo: 0x80, hi: 0x96},
2346 {value: 0x0018, lo: 0x97, hi: 0x97},
2347 {value: 0xe105, lo: 0x98, hi: 0x9e},
2348 {value: 0x001f, lo: 0x9f, hi: 0x9f},
2349 {value: 0x0008, lo: 0xa0, hi: 0xb6},
2350 {value: 0x0018, lo: 0xb7, hi: 0xb7},
2351 {value: 0x0008, lo: 0xb8, hi: 0xbf},
2352 // Block 0x1, offset 0x8
2353 {value: 0x0000, lo: 0x10},
2354 {value: 0x0008, lo: 0x80, hi: 0x80},
2355 {value: 0xe01d, lo: 0x81, hi: 0x81},
2356 {value: 0x0008, lo: 0x82, hi: 0x82},
2357 {value: 0x0335, lo: 0x83, hi: 0x83},
2358 {value: 0x034d, lo: 0x84, hi: 0x84},
2359 {value: 0x0365, lo: 0x85, hi: 0x85},
2360 {value: 0xe00d, lo: 0x86, hi: 0x86},
2361 {value: 0x0008, lo: 0x87, hi: 0x87},
2362 {value: 0xe00d, lo: 0x88, hi: 0x88},
2363 {value: 0x0008, lo: 0x89, hi: 0x89},
2364 {value: 0xe00d, lo: 0x8a, hi: 0x8a},
2365 {value: 0x0008, lo: 0x8b, hi: 0x8b},
2366 {value: 0xe00d, lo: 0x8c, hi: 0x8c},
2367 {value: 0x0008, lo: 0x8d, hi: 0x8d},
2368 {value: 0xe00d, lo: 0x8e, hi: 0x8e},
2369 {value: 0x0008, lo: 0x8f, hi: 0xbf},
2370 // Block 0x2, offset 0x19
2371 {value: 0x0000, lo: 0x0b},
2372 {value: 0x0008, lo: 0x80, hi: 0xaf},
2373 {value: 0x0249, lo: 0xb0, hi: 0xb0},
2374 {value: 0x037d, lo: 0xb1, hi: 0xb1},
2375 {value: 0x0259, lo: 0xb2, hi: 0xb2},
2376 {value: 0x0269, lo: 0xb3, hi: 0xb3},
2377 {value: 0x034d, lo: 0xb4, hi: 0xb4},
2378 {value: 0x0395, lo: 0xb5, hi: 0xb5},
2379 {value: 0xe1bd, lo: 0xb6, hi: 0xb6},
2380 {value: 0x0279, lo: 0xb7, hi: 0xb7},
2381 {value: 0x0289, lo: 0xb8, hi: 0xb8},
2382 {value: 0x0008, lo: 0xb9, hi: 0xbf},
2383 // Block 0x3, offset 0x25
2384 {value: 0x0000, lo: 0x01},
2385 {value: 0x1308, lo: 0x80, hi: 0xbf},
2386 // Block 0x4, offset 0x27
2387 {value: 0x0000, lo: 0x04},
2388 {value: 0x03f5, lo: 0x80, hi: 0x8f},
2389 {value: 0xe105, lo: 0x90, hi: 0x9f},
2390 {value: 0x049d, lo: 0xa0, hi: 0xaf},
2391 {value: 0x0008, lo: 0xb0, hi: 0xbf},
2392 // Block 0x5, offset 0x2c
2393 {value: 0x0000, lo: 0x07},
2394 {value: 0xe185, lo: 0x80, hi: 0x8f},
2395 {value: 0x0545, lo: 0x90, hi: 0x96},
2396 {value: 0x0040, lo: 0x97, hi: 0x98},
2397 {value: 0x0008, lo: 0x99, hi: 0x99},
2398 {value: 0x0018, lo: 0x9a, hi: 0x9f},
2399 {value: 0x0040, lo: 0xa0, hi: 0xa0},
2400 {value: 0x0008, lo: 0xa1, hi: 0xbf},
2401 // Block 0x6, offset 0x34
2402 {value: 0x0000, lo: 0x0a},
2403 {value: 0x0008, lo: 0x80, hi: 0x86},
2404 {value: 0x0401, lo: 0x87, hi: 0x87},
2405 {value: 0x0040, lo: 0x88, hi: 0x88},
2406 {value: 0x0018, lo: 0x89, hi: 0x8a},
2407 {value: 0x0040, lo: 0x8b, hi: 0x8c},
2408 {value: 0x0018, lo: 0x8d, hi: 0x8f},
2409 {value: 0x0040, lo: 0x90, hi: 0x90},
2410 {value: 0x1308, lo: 0x91, hi: 0xbd},
2411 {value: 0x0018, lo: 0xbe, hi: 0xbe},
2412 {value: 0x1308, lo: 0xbf, hi: 0xbf},
2413 // Block 0x7, offset 0x3f
2414 {value: 0x0000, lo: 0x0b},
2415 {value: 0x0018, lo: 0x80, hi: 0x80},
2416 {value: 0x1308, lo: 0x81, hi: 0x82},
2417 {value: 0x0018, lo: 0x83, hi: 0x83},
2418 {value: 0x1308, lo: 0x84, hi: 0x85},
2419 {value: 0x0018, lo: 0x86, hi: 0x86},
2420 {value: 0x1308, lo: 0x87, hi: 0x87},
2421 {value: 0x0040, lo: 0x88, hi: 0x8f},
2422 {value: 0x0008, lo: 0x90, hi: 0xaa},
2423 {value: 0x0040, lo: 0xab, hi: 0xaf},
2424 {value: 0x0008, lo: 0xb0, hi: 0xb4},
2425 {value: 0x0040, lo: 0xb5, hi: 0xbf},
2426 // Block 0x8, offset 0x4b
2427 {value: 0x0000, lo: 0x10},
2428 {value: 0x0018, lo: 0x80, hi: 0x80},
2429 {value: 0x0208, lo: 0x81, hi: 0x87},
2430 {value: 0x0408, lo: 0x88, hi: 0x88},
2431 {value: 0x0208, lo: 0x89, hi: 0x8a},
2432 {value: 0x1308, lo: 0x8b, hi: 0x9f},
2433 {value: 0x0008, lo: 0xa0, hi: 0xa9},
2434 {value: 0x0018, lo: 0xaa, hi: 0xad},
2435 {value: 0x0208, lo: 0xae, hi: 0xaf},
2436 {value: 0x1308, lo: 0xb0, hi: 0xb0},
2437 {value: 0x0408, lo: 0xb1, hi: 0xb3},
2438 {value: 0x0008, lo: 0xb4, hi: 0xb4},
2439 {value: 0x0429, lo: 0xb5, hi: 0xb5},
2440 {value: 0x0451, lo: 0xb6, hi: 0xb6},
2441 {value: 0x0479, lo: 0xb7, hi: 0xb7},
2442 {value: 0x04a1, lo: 0xb8, hi: 0xb8},
2443 {value: 0x0208, lo: 0xb9, hi: 0xbf},
2444 // Block 0x9, offset 0x5c
2445 {value: 0x0000, lo: 0x03},
2446 {value: 0x0208, lo: 0x80, hi: 0x87},
2447 {value: 0x0408, lo: 0x88, hi: 0x99},
2448 {value: 0x0208, lo: 0x9a, hi: 0xbf},
2449 // Block 0xa, offset 0x60
2450 {value: 0x0000, lo: 0x0e},
2451 {value: 0x1308, lo: 0x80, hi: 0x8a},
2452 {value: 0x0040, lo: 0x8b, hi: 0x8c},
2453 {value: 0x0408, lo: 0x8d, hi: 0x8d},
2454 {value: 0x0208, lo: 0x8e, hi: 0x98},
2455 {value: 0x0408, lo: 0x99, hi: 0x9b},
2456 {value: 0x0208, lo: 0x9c, hi: 0xaa},
2457 {value: 0x0408, lo: 0xab, hi: 0xac},
2458 {value: 0x0208, lo: 0xad, hi: 0xb0},
2459 {value: 0x0408, lo: 0xb1, hi: 0xb1},
2460 {value: 0x0208, lo: 0xb2, hi: 0xb2},
2461 {value: 0x0408, lo: 0xb3, hi: 0xb4},
2462 {value: 0x0208, lo: 0xb5, hi: 0xb7},
2463 {value: 0x0408, lo: 0xb8, hi: 0xb9},
2464 {value: 0x0208, lo: 0xba, hi: 0xbf},
2465 // Block 0xb, offset 0x6f
2466 {value: 0x0000, lo: 0x04},
2467 {value: 0x0008, lo: 0x80, hi: 0xa5},
2468 {value: 0x1308, lo: 0xa6, hi: 0xb0},
2469 {value: 0x0008, lo: 0xb1, hi: 0xb1},
2470 {value: 0x0040, lo: 0xb2, hi: 0xbf},
2471 // Block 0xc, offset 0x74
2472 {value: 0x0000, lo: 0x06},
2473 {value: 0x0008, lo: 0x80, hi: 0x89},
2474 {value: 0x0208, lo: 0x8a, hi: 0xaa},
2475 {value: 0x1308, lo: 0xab, hi: 0xb3},
2476 {value: 0x0008, lo: 0xb4, hi: 0xb5},
2477 {value: 0x0018, lo: 0xb6, hi: 0xba},
2478 {value: 0x0040, lo: 0xbb, hi: 0xbf},
2479 // Block 0xd, offset 0x7b
2480 {value: 0x0000, lo: 0x0b},
2481 {value: 0x0008, lo: 0x80, hi: 0x95},
2482 {value: 0x1308, lo: 0x96, hi: 0x99},
2483 {value: 0x0008, lo: 0x9a, hi: 0x9a},
2484 {value: 0x1308, lo: 0x9b, hi: 0xa3},
2485 {value: 0x0008, lo: 0xa4, hi: 0xa4},
2486 {value: 0x1308, lo: 0xa5, hi: 0xa7},
2487 {value: 0x0008, lo: 0xa8, hi: 0xa8},
2488 {value: 0x1308, lo: 0xa9, hi: 0xad},
2489 {value: 0x0040, lo: 0xae, hi: 0xaf},
2490 {value: 0x0018, lo: 0xb0, hi: 0xbe},
2491 {value: 0x0040, lo: 0xbf, hi: 0xbf},
2492 // Block 0xe, offset 0x87
2493 {value: 0x0000, lo: 0x0d},
2494 {value: 0x0408, lo: 0x80, hi: 0x80},
2495 {value: 0x0208, lo: 0x81, hi: 0x85},
2496 {value: 0x0408, lo: 0x86, hi: 0x87},
2497 {value: 0x0208, lo: 0x88, hi: 0x88},
2498 {value: 0x0408, lo: 0x89, hi: 0x89},
2499 {value: 0x0208, lo: 0x8a, hi: 0x93},
2500 {value: 0x0408, lo: 0x94, hi: 0x94},
2501 {value: 0x0208, lo: 0x95, hi: 0x95},
2502 {value: 0x0008, lo: 0x96, hi: 0x98},
2503 {value: 0x1308, lo: 0x99, hi: 0x9b},
2504 {value: 0x0040, lo: 0x9c, hi: 0x9d},
2505 {value: 0x0018, lo: 0x9e, hi: 0x9e},
2506 {value: 0x0040, lo: 0x9f, hi: 0xbf},
2507 // Block 0xf, offset 0x95
2508 {value: 0x0000, lo: 0x0d},
2509 {value: 0x0040, lo: 0x80, hi: 0x9f},
2510 {value: 0x0208, lo: 0xa0, hi: 0xa9},
2511 {value: 0x0408, lo: 0xaa, hi: 0xac},
2512 {value: 0x0008, lo: 0xad, hi: 0xad},
2513 {value: 0x0408, lo: 0xae, hi: 0xae},
2514 {value: 0x0208, lo: 0xaf, hi: 0xb0},
2515 {value: 0x0408, lo: 0xb1, hi: 0xb2},
2516 {value: 0x0208, lo: 0xb3, hi: 0xb4},
2517 {value: 0x0040, lo: 0xb5, hi: 0xb5},
2518 {value: 0x0208, lo: 0xb6, hi: 0xb8},
2519 {value: 0x0408, lo: 0xb9, hi: 0xb9},
2520 {value: 0x0208, lo: 0xba, hi: 0xbd},
2521 {value: 0x0040, lo: 0xbe, hi: 0xbf},
2522 // Block 0x10, offset 0xa3
2523 {value: 0x0000, lo: 0x04},
2524 {value: 0x0040, lo: 0x80, hi: 0x93},
2525 {value: 0x1308, lo: 0x94, hi: 0xa1},
2526 {value: 0x0040, lo: 0xa2, hi: 0xa2},
2527 {value: 0x1308, lo: 0xa3, hi: 0xbf},
2528 // Block 0x11, offset 0xa8
2529 {value: 0x0000, lo: 0x08},
2530 {value: 0x1308, lo: 0x80, hi: 0x82},
2531 {value: 0x1008, lo: 0x83, hi: 0x83},
2532 {value: 0x0008, lo: 0x84, hi: 0xb9},
2533 {value: 0x1308, lo: 0xba, hi: 0xba},
2534 {value: 0x1008, lo: 0xbb, hi: 0xbb},
2535 {value: 0x1308, lo: 0xbc, hi: 0xbc},
2536 {value: 0x0008, lo: 0xbd, hi: 0xbd},
2537 {value: 0x1008, lo: 0xbe, hi: 0xbf},
2538 // Block 0x12, offset 0xb1
2539 {value: 0x0000, lo: 0x0f},
2540 {value: 0x1308, lo: 0x80, hi: 0x80},
2541 {value: 0x1008, lo: 0x81, hi: 0x82},
2542 {value: 0x0040, lo: 0x83, hi: 0x85},
2543 {value: 0x1008, lo: 0x86, hi: 0x88},
2544 {value: 0x0040, lo: 0x89, hi: 0x89},
2545 {value: 0x1008, lo: 0x8a, hi: 0x8c},
2546 {value: 0x1b08, lo: 0x8d, hi: 0x8d},
2547 {value: 0x0040, lo: 0x8e, hi: 0x8f},
2548 {value: 0x0008, lo: 0x90, hi: 0x90},
2549 {value: 0x0040, lo: 0x91, hi: 0x96},
2550 {value: 0x1008, lo: 0x97, hi: 0x97},
2551 {value: 0x0040, lo: 0x98, hi: 0xa5},
2552 {value: 0x0008, lo: 0xa6, hi: 0xaf},
2553 {value: 0x0018, lo: 0xb0, hi: 0xba},
2554 {value: 0x0040, lo: 0xbb, hi: 0xbf},
2555 // Block 0x13, offset 0xc1
2556 {value: 0x0000, lo: 0x0d},
2557 {value: 0x1308, lo: 0x80, hi: 0x80},
2558 {value: 0x1008, lo: 0x81, hi: 0x83},
2559 {value: 0x0040, lo: 0x84, hi: 0x84},
2560 {value: 0x0008, lo: 0x85, hi: 0x8c},
2561 {value: 0x0040, lo: 0x8d, hi: 0x8d},
2562 {value: 0x0008, lo: 0x8e, hi: 0x90},
2563 {value: 0x0040, lo: 0x91, hi: 0x91},
2564 {value: 0x0008, lo: 0x92, hi: 0xa8},
2565 {value: 0x0040, lo: 0xa9, hi: 0xa9},
2566 {value: 0x0008, lo: 0xaa, hi: 0xb9},
2567 {value: 0x0040, lo: 0xba, hi: 0xbc},
2568 {value: 0x0008, lo: 0xbd, hi: 0xbd},
2569 {value: 0x1308, lo: 0xbe, hi: 0xbf},
2570 // Block 0x14, offset 0xcf
2571 {value: 0x0000, lo: 0x0c},
2572 {value: 0x0040, lo: 0x80, hi: 0x80},
2573 {value: 0x1308, lo: 0x81, hi: 0x81},
2574 {value: 0x1008, lo: 0x82, hi: 0x83},
2575 {value: 0x0040, lo: 0x84, hi: 0x84},
2576 {value: 0x0008, lo: 0x85, hi: 0x8c},
2577 {value: 0x0040, lo: 0x8d, hi: 0x8d},
2578 {value: 0x0008, lo: 0x8e, hi: 0x90},
2579 {value: 0x0040, lo: 0x91, hi: 0x91},
2580 {value: 0x0008, lo: 0x92, hi: 0xba},
2581 {value: 0x0040, lo: 0xbb, hi: 0xbc},
2582 {value: 0x0008, lo: 0xbd, hi: 0xbd},
2583 {value: 0x1008, lo: 0xbe, hi: 0xbf},
2584 // Block 0x15, offset 0xdc
2585 {value: 0x0000, lo: 0x0b},
2586 {value: 0x0040, lo: 0x80, hi: 0x81},
2587 {value: 0x1008, lo: 0x82, hi: 0x83},
2588 {value: 0x0040, lo: 0x84, hi: 0x84},
2589 {value: 0x0008, lo: 0x85, hi: 0x96},
2590 {value: 0x0040, lo: 0x97, hi: 0x99},
2591 {value: 0x0008, lo: 0x9a, hi: 0xb1},
2592 {value: 0x0040, lo: 0xb2, hi: 0xb2},
2593 {value: 0x0008, lo: 0xb3, hi: 0xbb},
2594 {value: 0x0040, lo: 0xbc, hi: 0xbc},
2595 {value: 0x0008, lo: 0xbd, hi: 0xbd},
2596 {value: 0x0040, lo: 0xbe, hi: 0xbf},
2597 // Block 0x16, offset 0xe8
2598 {value: 0x0000, lo: 0x10},
2599 {value: 0x0008, lo: 0x80, hi: 0x86},
2600 {value: 0x0040, lo: 0x87, hi: 0x89},
2601 {value: 0x1b08, lo: 0x8a, hi: 0x8a},
2602 {value: 0x0040, lo: 0x8b, hi: 0x8e},
2603 {value: 0x1008, lo: 0x8f, hi: 0x91},
2604 {value: 0x1308, lo: 0x92, hi: 0x94},
2605 {value: 0x0040, lo: 0x95, hi: 0x95},
2606 {value: 0x1308, lo: 0x96, hi: 0x96},
2607 {value: 0x0040, lo: 0x97, hi: 0x97},
2608 {value: 0x1008, lo: 0x98, hi: 0x9f},
2609 {value: 0x0040, lo: 0xa0, hi: 0xa5},
2610 {value: 0x0008, lo: 0xa6, hi: 0xaf},
2611 {value: 0x0040, lo: 0xb0, hi: 0xb1},
2612 {value: 0x1008, lo: 0xb2, hi: 0xb3},
2613 {value: 0x0018, lo: 0xb4, hi: 0xb4},
2614 {value: 0x0040, lo: 0xb5, hi: 0xbf},
2615 // Block 0x17, offset 0xf9
2616 {value: 0x0000, lo: 0x09},
2617 {value: 0x0040, lo: 0x80, hi: 0x80},
2618 {value: 0x0008, lo: 0x81, hi: 0xb0},
2619 {value: 0x1308, lo: 0xb1, hi: 0xb1},
2620 {value: 0x0008, lo: 0xb2, hi: 0xb2},
2621 {value: 0x08f1, lo: 0xb3, hi: 0xb3},
2622 {value: 0x1308, lo: 0xb4, hi: 0xb9},
2623 {value: 0x1b08, lo: 0xba, hi: 0xba},
2624 {value: 0x0040, lo: 0xbb, hi: 0xbe},
2625 {value: 0x0018, lo: 0xbf, hi: 0xbf},
2626 // Block 0x18, offset 0x103
2627 {value: 0x0000, lo: 0x06},
2628 {value: 0x0008, lo: 0x80, hi: 0x86},
2629 {value: 0x1308, lo: 0x87, hi: 0x8e},
2630 {value: 0x0018, lo: 0x8f, hi: 0x8f},
2631 {value: 0x0008, lo: 0x90, hi: 0x99},
2632 {value: 0x0018, lo: 0x9a, hi: 0x9b},
2633 {value: 0x0040, lo: 0x9c, hi: 0xbf},
2634 // Block 0x19, offset 0x10a
2635 {value: 0x0000, lo: 0x0c},
2636 {value: 0x0008, lo: 0x80, hi: 0x84},
2637 {value: 0x0040, lo: 0x85, hi: 0x85},
2638 {value: 0x0008, lo: 0x86, hi: 0x86},
2639 {value: 0x0040, lo: 0x87, hi: 0x87},
2640 {value: 0x1308, lo: 0x88, hi: 0x8d},
2641 {value: 0x0040, lo: 0x8e, hi: 0x8f},
2642 {value: 0x0008, lo: 0x90, hi: 0x99},
2643 {value: 0x0040, lo: 0x9a, hi: 0x9b},
2644 {value: 0x0961, lo: 0x9c, hi: 0x9c},
2645 {value: 0x0999, lo: 0x9d, hi: 0x9d},
2646 {value: 0x0008, lo: 0x9e, hi: 0x9f},
2647 {value: 0x0040, lo: 0xa0, hi: 0xbf},
2648 // Block 0x1a, offset 0x117
2649 {value: 0x0000, lo: 0x10},
2650 {value: 0x0008, lo: 0x80, hi: 0x80},
2651 {value: 0x0018, lo: 0x81, hi: 0x8a},
2652 {value: 0x0008, lo: 0x8b, hi: 0x8b},
2653 {value: 0xe03d, lo: 0x8c, hi: 0x8c},
2654 {value: 0x0018, lo: 0x8d, hi: 0x97},
2655 {value: 0x1308, lo: 0x98, hi: 0x99},
2656 {value: 0x0018, lo: 0x9a, hi: 0x9f},
2657 {value: 0x0008, lo: 0xa0, hi: 0xa9},
2658 {value: 0x0018, lo: 0xaa, hi: 0xb4},
2659 {value: 0x1308, lo: 0xb5, hi: 0xb5},
2660 {value: 0x0018, lo: 0xb6, hi: 0xb6},
2661 {value: 0x1308, lo: 0xb7, hi: 0xb7},
2662 {value: 0x0018, lo: 0xb8, hi: 0xb8},
2663 {value: 0x1308, lo: 0xb9, hi: 0xb9},
2664 {value: 0x0018, lo: 0xba, hi: 0xbd},
2665 {value: 0x1008, lo: 0xbe, hi: 0xbf},
2666 // Block 0x1b, offset 0x128
2667 {value: 0x0000, lo: 0x06},
2668 {value: 0x0018, lo: 0x80, hi: 0x85},
2669 {value: 0x1308, lo: 0x86, hi: 0x86},
2670 {value: 0x0018, lo: 0x87, hi: 0x8c},
2671 {value: 0x0040, lo: 0x8d, hi: 0x8d},
2672 {value: 0x0018, lo: 0x8e, hi: 0x9a},
2673 {value: 0x0040, lo: 0x9b, hi: 0xbf},
2674 // Block 0x1c, offset 0x12f
2675 {value: 0x0000, lo: 0x0a},
2676 {value: 0x0008, lo: 0x80, hi: 0xaa},
2677 {value: 0x1008, lo: 0xab, hi: 0xac},
2678 {value: 0x1308, lo: 0xad, hi: 0xb0},
2679 {value: 0x1008, lo: 0xb1, hi: 0xb1},
2680 {value: 0x1308, lo: 0xb2, hi: 0xb7},
2681 {value: 0x1008, lo: 0xb8, hi: 0xb8},
2682 {value: 0x1b08, lo: 0xb9, hi: 0xba},
2683 {value: 0x1008, lo: 0xbb, hi: 0xbc},
2684 {value: 0x1308, lo: 0xbd, hi: 0xbe},
2685 {value: 0x0008, lo: 0xbf, hi: 0xbf},
2686 // Block 0x1d, offset 0x13a
2687 {value: 0x0000, lo: 0x0e},
2688 {value: 0x0008, lo: 0x80, hi: 0x89},
2689 {value: 0x0018, lo: 0x8a, hi: 0x8f},
2690 {value: 0x0008, lo: 0x90, hi: 0x95},
2691 {value: 0x1008, lo: 0x96, hi: 0x97},
2692 {value: 0x1308, lo: 0x98, hi: 0x99},
2693 {value: 0x0008, lo: 0x9a, hi: 0x9d},
2694 {value: 0x1308, lo: 0x9e, hi: 0xa0},
2695 {value: 0x0008, lo: 0xa1, hi: 0xa1},
2696 {value: 0x1008, lo: 0xa2, hi: 0xa4},
2697 {value: 0x0008, lo: 0xa5, hi: 0xa6},
2698 {value: 0x1008, lo: 0xa7, hi: 0xad},
2699 {value: 0x0008, lo: 0xae, hi: 0xb0},
2700 {value: 0x1308, lo: 0xb1, hi: 0xb4},
2701 {value: 0x0008, lo: 0xb5, hi: 0xbf},
2702 // Block 0x1e, offset 0x149
2703 {value: 0x0000, lo: 0x0d},
2704 {value: 0x0008, lo: 0x80, hi: 0x81},
2705 {value: 0x1308, lo: 0x82, hi: 0x82},
2706 {value: 0x1008, lo: 0x83, hi: 0x84},
2707 {value: 0x1308, lo: 0x85, hi: 0x86},
2708 {value: 0x1008, lo: 0x87, hi: 0x8c},
2709 {value: 0x1308, lo: 0x8d, hi: 0x8d},
2710 {value: 0x0008, lo: 0x8e, hi: 0x8e},
2711 {value: 0x1008, lo: 0x8f, hi: 0x8f},
2712 {value: 0x0008, lo: 0x90, hi: 0x99},
2713 {value: 0x1008, lo: 0x9a, hi: 0x9c},
2714 {value: 0x1308, lo: 0x9d, hi: 0x9d},
2715 {value: 0x0018, lo: 0x9e, hi: 0x9f},
2716 {value: 0x0040, lo: 0xa0, hi: 0xbf},
2717 // Block 0x1f, offset 0x157
2718 {value: 0x0000, lo: 0x09},
2719 {value: 0x0040, lo: 0x80, hi: 0x86},
2720 {value: 0x055d, lo: 0x87, hi: 0x87},
2721 {value: 0x0040, lo: 0x88, hi: 0x8c},
2722 {value: 0x055d, lo: 0x8d, hi: 0x8d},
2723 {value: 0x0040, lo: 0x8e, hi: 0x8f},
2724 {value: 0x0008, lo: 0x90, hi: 0xba},
2725 {value: 0x0018, lo: 0xbb, hi: 0xbb},
2726 {value: 0xe105, lo: 0xbc, hi: 0xbc},
2727 {value: 0x0008, lo: 0xbd, hi: 0xbf},
2728 // Block 0x20, offset 0x161
2729 {value: 0x0000, lo: 0x01},
2730 {value: 0x0018, lo: 0x80, hi: 0xbf},
2731 // Block 0x21, offset 0x163
2732 {value: 0x0000, lo: 0x03},
2733 {value: 0x0018, lo: 0x80, hi: 0x9e},
2734 {value: 0x0040, lo: 0x9f, hi: 0xa0},
2735 {value: 0x0018, lo: 0xa1, hi: 0xbf},
2736 // Block 0x22, offset 0x167
2737 {value: 0x0000, lo: 0x01},
2738 {value: 0x0008, lo: 0x80, hi: 0xbf},
2739 // Block 0x23, offset 0x169
2740 {value: 0x0000, lo: 0x0b},
2741 {value: 0x0008, lo: 0x80, hi: 0x88},
2742 {value: 0x0040, lo: 0x89, hi: 0x89},
2743 {value: 0x0008, lo: 0x8a, hi: 0x8d},
2744 {value: 0x0040, lo: 0x8e, hi: 0x8f},
2745 {value: 0x0008, lo: 0x90, hi: 0x96},
2746 {value: 0x0040, lo: 0x97, hi: 0x97},
2747 {value: 0x0008, lo: 0x98, hi: 0x98},
2748 {value: 0x0040, lo: 0x99, hi: 0x99},
2749 {value: 0x0008, lo: 0x9a, hi: 0x9d},
2750 {value: 0x0040, lo: 0x9e, hi: 0x9f},
2751 {value: 0x0008, lo: 0xa0, hi: 0xbf},
2752 // Block 0x24, offset 0x175
2753 {value: 0x0000, lo: 0x0a},
2754 {value: 0x0008, lo: 0x80, hi: 0x88},
2755 {value: 0x0040, lo: 0x89, hi: 0x89},
2756 {value: 0x0008, lo: 0x8a, hi: 0x8d},
2757 {value: 0x0040, lo: 0x8e, hi: 0x8f},
2758 {value: 0x0008, lo: 0x90, hi: 0xb0},
2759 {value: 0x0040, lo: 0xb1, hi: 0xb1},
2760 {value: 0x0008, lo: 0xb2, hi: 0xb5},
2761 {value: 0x0040, lo: 0xb6, hi: 0xb7},
2762 {value: 0x0008, lo: 0xb8, hi: 0xbe},
2763 {value: 0x0040, lo: 0xbf, hi: 0xbf},
2764 // Block 0x25, offset 0x180
2765 {value: 0x0000, lo: 0x07},
2766 {value: 0x0008, lo: 0x80, hi: 0x80},
2767 {value: 0x0040, lo: 0x81, hi: 0x81},
2768 {value: 0x0008, lo: 0x82, hi: 0x85},
2769 {value: 0x0040, lo: 0x86, hi: 0x87},
2770 {value: 0x0008, lo: 0x88, hi: 0x96},
2771 {value: 0x0040, lo: 0x97, hi: 0x97},
2772 {value: 0x0008, lo: 0x98, hi: 0xbf},
2773 // Block 0x26, offset 0x188
2774 {value: 0x0000, lo: 0x05},
2775 {value: 0x0008, lo: 0x80, hi: 0x90},
2776 {value: 0x0040, lo: 0x91, hi: 0x91},
2777 {value: 0x0008, lo: 0x92, hi: 0x95},
2778 {value: 0x0040, lo: 0x96, hi: 0x97},
2779 {value: 0x0008, lo: 0x98, hi: 0xbf},
2780 // Block 0x27, offset 0x18e
2781 {value: 0x0000, lo: 0x05},
2782 {value: 0x0008, lo: 0x80, hi: 0x9a},
2783 {value: 0x0040, lo: 0x9b, hi: 0x9c},
2784 {value: 0x1308, lo: 0x9d, hi: 0x9f},
2785 {value: 0x0018, lo: 0xa0, hi: 0xbc},
2786 {value: 0x0040, lo: 0xbd, hi: 0xbf},
2787 // Block 0x28, offset 0x194
2788 {value: 0x0000, lo: 0x04},
2789 {value: 0x0008, lo: 0x80, hi: 0x8f},
2790 {value: 0x0018, lo: 0x90, hi: 0x99},
2791 {value: 0x0040, lo: 0x9a, hi: 0x9f},
2792 {value: 0x0008, lo: 0xa0, hi: 0xbf},
2793 // Block 0x29, offset 0x199
2794 {value: 0x0000, lo: 0x04},
2795 {value: 0x0008, lo: 0x80, hi: 0xb5},
2796 {value: 0x0040, lo: 0xb6, hi: 0xb7},
2797 {value: 0xe045, lo: 0xb8, hi: 0xbd},
2798 {value: 0x0040, lo: 0xbe, hi: 0xbf},
2799 // Block 0x2a, offset 0x19e
2800 {value: 0x0000, lo: 0x02},
2801 {value: 0x0018, lo: 0x80, hi: 0x80},
2802 {value: 0x0008, lo: 0x81, hi: 0xbf},
2803 // Block 0x2b, offset 0x1a1
2804 {value: 0x0000, lo: 0x03},
2805 {value: 0x0008, lo: 0x80, hi: 0xac},
2806 {value: 0x0018, lo: 0xad, hi: 0xae},
2807 {value: 0x0008, lo: 0xaf, hi: 0xbf},
2808 // Block 0x2c, offset 0x1a5
2809 {value: 0x0000, lo: 0x05},
2810 {value: 0x0040, lo: 0x80, hi: 0x80},
2811 {value: 0x0008, lo: 0x81, hi: 0x9a},
2812 {value: 0x0018, lo: 0x9b, hi: 0x9c},
2813 {value: 0x0040, lo: 0x9d, hi: 0x9f},
2814 {value: 0x0008, lo: 0xa0, hi: 0xbf},
2815 // Block 0x2d, offset 0x1ab
2816 {value: 0x0000, lo: 0x04},
2817 {value: 0x0008, lo: 0x80, hi: 0xaa},
2818 {value: 0x0018, lo: 0xab, hi: 0xb0},
2819 {value: 0x0008, lo: 0xb1, hi: 0xb8},
2820 {value: 0x0040, lo: 0xb9, hi: 0xbf},
2821 // Block 0x2e, offset 0x1b0
2822 {value: 0x0000, lo: 0x0b},
2823 {value: 0x0008, lo: 0x80, hi: 0x8c},
2824 {value: 0x0040, lo: 0x8d, hi: 0x8d},
2825 {value: 0x0008, lo: 0x8e, hi: 0x91},
2826 {value: 0x1308, lo: 0x92, hi: 0x93},
2827 {value: 0x1b08, lo: 0x94, hi: 0x94},
2828 {value: 0x0040, lo: 0x95, hi: 0x9f},
2829 {value: 0x0008, lo: 0xa0, hi: 0xb1},
2830 {value: 0x1308, lo: 0xb2, hi: 0xb3},
2831 {value: 0x1b08, lo: 0xb4, hi: 0xb4},
2832 {value: 0x0018, lo: 0xb5, hi: 0xb6},
2833 {value: 0x0040, lo: 0xb7, hi: 0xbf},
2834 // Block 0x2f, offset 0x1bc
2835 {value: 0x0000, lo: 0x09},
2836 {value: 0x0008, lo: 0x80, hi: 0x91},
2837 {value: 0x1308, lo: 0x92, hi: 0x93},
2838 {value: 0x0040, lo: 0x94, hi: 0x9f},
2839 {value: 0x0008, lo: 0xa0, hi: 0xac},
2840 {value: 0x0040, lo: 0xad, hi: 0xad},
2841 {value: 0x0008, lo: 0xae, hi: 0xb0},
2842 {value: 0x0040, lo: 0xb1, hi: 0xb1},
2843 {value: 0x1308, lo: 0xb2, hi: 0xb3},
2844 {value: 0x0040, lo: 0xb4, hi: 0xbf},
2845 // Block 0x30, offset 0x1c6
2846 {value: 0x0000, lo: 0x05},
2847 {value: 0x0008, lo: 0x80, hi: 0xb3},
2848 {value: 0x1340, lo: 0xb4, hi: 0xb5},
2849 {value: 0x1008, lo: 0xb6, hi: 0xb6},
2850 {value: 0x1308, lo: 0xb7, hi: 0xbd},
2851 {value: 0x1008, lo: 0xbe, hi: 0xbf},
2852 // Block 0x31, offset 0x1cc
2853 {value: 0x0000, lo: 0x10},
2854 {value: 0x1008, lo: 0x80, hi: 0x85},
2855 {value: 0x1308, lo: 0x86, hi: 0x86},
2856 {value: 0x1008, lo: 0x87, hi: 0x88},
2857 {value: 0x1308, lo: 0x89, hi: 0x91},
2858 {value: 0x1b08, lo: 0x92, hi: 0x92},
2859 {value: 0x1308, lo: 0x93, hi: 0x93},
2860 {value: 0x0018, lo: 0x94, hi: 0x96},
2861 {value: 0x0008, lo: 0x97, hi: 0x97},
2862 {value: 0x0018, lo: 0x98, hi: 0x9b},
2863 {value: 0x0008, lo: 0x9c, hi: 0x9c},
2864 {value: 0x1308, lo: 0x9d, hi: 0x9d},
2865 {value: 0x0040, lo: 0x9e, hi: 0x9f},
2866 {value: 0x0008, lo: 0xa0, hi: 0xa9},
2867 {value: 0x0040, lo: 0xaa, hi: 0xaf},
2868 {value: 0x0018, lo: 0xb0, hi: 0xb9},
2869 {value: 0x0040, lo: 0xba, hi: 0xbf},
2870 // Block 0x32, offset 0x1dd
2871 {value: 0x0000, lo: 0x09},
2872 {value: 0x0018, lo: 0x80, hi: 0x85},
2873 {value: 0x0040, lo: 0x86, hi: 0x86},
2874 {value: 0x0218, lo: 0x87, hi: 0x87},
2875 {value: 0x0018, lo: 0x88, hi: 0x8a},
2876 {value: 0x13c0, lo: 0x8b, hi: 0x8d},
2877 {value: 0x0040, lo: 0x8e, hi: 0x8f},
2878 {value: 0x0008, lo: 0x90, hi: 0x99},
2879 {value: 0x0040, lo: 0x9a, hi: 0x9f},
2880 {value: 0x0208, lo: 0xa0, hi: 0xbf},
2881 // Block 0x33, offset 0x1e7
2882 {value: 0x0000, lo: 0x02},
2883 {value: 0x0208, lo: 0x80, hi: 0xb7},
2884 {value: 0x0040, lo: 0xb8, hi: 0xbf},
2885 // Block 0x34, offset 0x1ea
2886 {value: 0x0000, lo: 0x07},
2887 {value: 0x0008, lo: 0x80, hi: 0x84},
2888 {value: 0x1308, lo: 0x85, hi: 0x86},
2889 {value: 0x0208, lo: 0x87, hi: 0xa8},
2890 {value: 0x1308, lo: 0xa9, hi: 0xa9},
2891 {value: 0x0208, lo: 0xaa, hi: 0xaa},
2892 {value: 0x0040, lo: 0xab, hi: 0xaf},
2893 {value: 0x0008, lo: 0xb0, hi: 0xbf},
2894 // Block 0x35, offset 0x1f2
2895 {value: 0x0000, lo: 0x02},
2896 {value: 0x0008, lo: 0x80, hi: 0xb5},
2897 {value: 0x0040, lo: 0xb6, hi: 0xbf},
2898 // Block 0x36, offset 0x1f5
2899 {value: 0x0000, lo: 0x0c},
2900 {value: 0x0008, lo: 0x80, hi: 0x9e},
2901 {value: 0x0040, lo: 0x9f, hi: 0x9f},
2902 {value: 0x1308, lo: 0xa0, hi: 0xa2},
2903 {value: 0x1008, lo: 0xa3, hi: 0xa6},
2904 {value: 0x1308, lo: 0xa7, hi: 0xa8},
2905 {value: 0x1008, lo: 0xa9, hi: 0xab},
2906 {value: 0x0040, lo: 0xac, hi: 0xaf},
2907 {value: 0x1008, lo: 0xb0, hi: 0xb1},
2908 {value: 0x1308, lo: 0xb2, hi: 0xb2},
2909 {value: 0x1008, lo: 0xb3, hi: 0xb8},
2910 {value: 0x1308, lo: 0xb9, hi: 0xbb},
2911 {value: 0x0040, lo: 0xbc, hi: 0xbf},
2912 // Block 0x37, offset 0x202
2913 {value: 0x0000, lo: 0x07},
2914 {value: 0x0018, lo: 0x80, hi: 0x80},
2915 {value: 0x0040, lo: 0x81, hi: 0x83},
2916 {value: 0x0018, lo: 0x84, hi: 0x85},
2917 {value: 0x0008, lo: 0x86, hi: 0xad},
2918 {value: 0x0040, lo: 0xae, hi: 0xaf},
2919 {value: 0x0008, lo: 0xb0, hi: 0xb4},
2920 {value: 0x0040, lo: 0xb5, hi: 0xbf},
2921 // Block 0x38, offset 0x20a
2922 {value: 0x0000, lo: 0x03},
2923 {value: 0x0008, lo: 0x80, hi: 0xab},
2924 {value: 0x0040, lo: 0xac, hi: 0xaf},
2925 {value: 0x0008, lo: 0xb0, hi: 0xbf},
2926 // Block 0x39, offset 0x20e
2927 {value: 0x0000, lo: 0x06},
2928 {value: 0x0008, lo: 0x80, hi: 0x89},
2929 {value: 0x0040, lo: 0x8a, hi: 0x8f},
2930 {value: 0x0008, lo: 0x90, hi: 0x99},
2931 {value: 0x0028, lo: 0x9a, hi: 0x9a},
2932 {value: 0x0040, lo: 0x9b, hi: 0x9d},
2933 {value: 0x0018, lo: 0x9e, hi: 0xbf},
2934 // Block 0x3a, offset 0x215
2935 {value: 0x0000, lo: 0x07},
2936 {value: 0x0008, lo: 0x80, hi: 0x96},
2937 {value: 0x1308, lo: 0x97, hi: 0x98},
2938 {value: 0x1008, lo: 0x99, hi: 0x9a},
2939 {value: 0x1308, lo: 0x9b, hi: 0x9b},
2940 {value: 0x0040, lo: 0x9c, hi: 0x9d},
2941 {value: 0x0018, lo: 0x9e, hi: 0x9f},
2942 {value: 0x0008, lo: 0xa0, hi: 0xbf},
2943 // Block 0x3b, offset 0x21d
2944 {value: 0x0000, lo: 0x0f},
2945 {value: 0x0008, lo: 0x80, hi: 0x94},
2946 {value: 0x1008, lo: 0x95, hi: 0x95},
2947 {value: 0x1308, lo: 0x96, hi: 0x96},
2948 {value: 0x1008, lo: 0x97, hi: 0x97},
2949 {value: 0x1308, lo: 0x98, hi: 0x9e},
2950 {value: 0x0040, lo: 0x9f, hi: 0x9f},
2951 {value: 0x1b08, lo: 0xa0, hi: 0xa0},
2952 {value: 0x1008, lo: 0xa1, hi: 0xa1},
2953 {value: 0x1308, lo: 0xa2, hi: 0xa2},
2954 {value: 0x1008, lo: 0xa3, hi: 0xa4},
2955 {value: 0x1308, lo: 0xa5, hi: 0xac},
2956 {value: 0x1008, lo: 0xad, hi: 0xb2},
2957 {value: 0x1308, lo: 0xb3, hi: 0xbc},
2958 {value: 0x0040, lo: 0xbd, hi: 0xbe},
2959 {value: 0x1308, lo: 0xbf, hi: 0xbf},
2960 // Block 0x3c, offset 0x22d
2961 {value: 0x0000, lo: 0x0b},
2962 {value: 0x0008, lo: 0x80, hi: 0x89},
2963 {value: 0x0040, lo: 0x8a, hi: 0x8f},
2964 {value: 0x0008, lo: 0x90, hi: 0x99},
2965 {value: 0x0040, lo: 0x9a, hi: 0x9f},
2966 {value: 0x0018, lo: 0xa0, hi: 0xa6},
2967 {value: 0x0008, lo: 0xa7, hi: 0xa7},
2968 {value: 0x0018, lo: 0xa8, hi: 0xad},
2969 {value: 0x0040, lo: 0xae, hi: 0xaf},
2970 {value: 0x1308, lo: 0xb0, hi: 0xbd},
2971 {value: 0x1318, lo: 0xbe, hi: 0xbe},
2972 {value: 0x0040, lo: 0xbf, hi: 0xbf},
2973 // Block 0x3d, offset 0x239
2974 {value: 0x0000, lo: 0x01},
2975 {value: 0x0040, lo: 0x80, hi: 0xbf},
2976 // Block 0x3e, offset 0x23b
2977 {value: 0x0000, lo: 0x09},
2978 {value: 0x1308, lo: 0x80, hi: 0x83},
2979 {value: 0x1008, lo: 0x84, hi: 0x84},
2980 {value: 0x0008, lo: 0x85, hi: 0xb3},
2981 {value: 0x1308, lo: 0xb4, hi: 0xb4},
2982 {value: 0x1008, lo: 0xb5, hi: 0xb5},
2983 {value: 0x1308, lo: 0xb6, hi: 0xba},
2984 {value: 0x1008, lo: 0xbb, hi: 0xbb},
2985 {value: 0x1308, lo: 0xbc, hi: 0xbc},
2986 {value: 0x1008, lo: 0xbd, hi: 0xbf},
2987 // Block 0x3f, offset 0x245
2988 {value: 0x0000, lo: 0x0b},
2989 {value: 0x1008, lo: 0x80, hi: 0x81},
2990 {value: 0x1308, lo: 0x82, hi: 0x82},
2991 {value: 0x1008, lo: 0x83, hi: 0x83},
2992 {value: 0x1808, lo: 0x84, hi: 0x84},
2993 {value: 0x0008, lo: 0x85, hi: 0x8b},
2994 {value: 0x0040, lo: 0x8c, hi: 0x8f},
2995 {value: 0x0008, lo: 0x90, hi: 0x99},
2996 {value: 0x0018, lo: 0x9a, hi: 0xaa},
2997 {value: 0x1308, lo: 0xab, hi: 0xb3},
2998 {value: 0x0018, lo: 0xb4, hi: 0xbc},
2999 {value: 0x0040, lo: 0xbd, hi: 0xbf},
3000 // Block 0x40, offset 0x251
3001 {value: 0x0000, lo: 0x0b},
3002 {value: 0x1308, lo: 0x80, hi: 0x81},
3003 {value: 0x1008, lo: 0x82, hi: 0x82},
3004 {value: 0x0008, lo: 0x83, hi: 0xa0},
3005 {value: 0x1008, lo: 0xa1, hi: 0xa1},
3006 {value: 0x1308, lo: 0xa2, hi: 0xa5},
3007 {value: 0x1008, lo: 0xa6, hi: 0xa7},
3008 {value: 0x1308, lo: 0xa8, hi: 0xa9},
3009 {value: 0x1808, lo: 0xaa, hi: 0xaa},
3010 {value: 0x1b08, lo: 0xab, hi: 0xab},
3011 {value: 0x1308, lo: 0xac, hi: 0xad},
3012 {value: 0x0008, lo: 0xae, hi: 0xbf},
3013 // Block 0x41, offset 0x25d
3014 {value: 0x0000, lo: 0x0b},
3015 {value: 0x0008, lo: 0x80, hi: 0xa5},
3016 {value: 0x1308, lo: 0xa6, hi: 0xa6},
3017 {value: 0x1008, lo: 0xa7, hi: 0xa7},
3018 {value: 0x1308, lo: 0xa8, hi: 0xa9},
3019 {value: 0x1008, lo: 0xaa, hi: 0xac},
3020 {value: 0x1308, lo: 0xad, hi: 0xad},
3021 {value: 0x1008, lo: 0xae, hi: 0xae},
3022 {value: 0x1308, lo: 0xaf, hi: 0xb1},
3023 {value: 0x1808, lo: 0xb2, hi: 0xb3},
3024 {value: 0x0040, lo: 0xb4, hi: 0xbb},
3025 {value: 0x0018, lo: 0xbc, hi: 0xbf},
3026 // Block 0x42, offset 0x269
3027 {value: 0x0000, lo: 0x07},
3028 {value: 0x0008, lo: 0x80, hi: 0xa3},
3029 {value: 0x1008, lo: 0xa4, hi: 0xab},
3030 {value: 0x1308, lo: 0xac, hi: 0xb3},
3031 {value: 0x1008, lo: 0xb4, hi: 0xb5},
3032 {value: 0x1308, lo: 0xb6, hi: 0xb7},
3033 {value: 0x0040, lo: 0xb8, hi: 0xba},
3034 {value: 0x0018, lo: 0xbb, hi: 0xbf},
3035 // Block 0x43, offset 0x271
3036 {value: 0x0000, lo: 0x04},
3037 {value: 0x0008, lo: 0x80, hi: 0x89},
3038 {value: 0x0040, lo: 0x8a, hi: 0x8c},
3039 {value: 0x0008, lo: 0x8d, hi: 0xbd},
3040 {value: 0x0018, lo: 0xbe, hi: 0xbf},
3041 // Block 0x44, offset 0x276
3042 {value: 0x0000, lo: 0x09},
3043 {value: 0x0e29, lo: 0x80, hi: 0x80},
3044 {value: 0x0e41, lo: 0x81, hi: 0x81},
3045 {value: 0x0e59, lo: 0x82, hi: 0x82},
3046 {value: 0x0e71, lo: 0x83, hi: 0x83},
3047 {value: 0x0e89, lo: 0x84, hi: 0x85},
3048 {value: 0x0ea1, lo: 0x86, hi: 0x86},
3049 {value: 0x0eb9, lo: 0x87, hi: 0x87},
3050 {value: 0x057d, lo: 0x88, hi: 0x88},
3051 {value: 0x0040, lo: 0x89, hi: 0xbf},
3052 // Block 0x45, offset 0x280
3053 {value: 0x0000, lo: 0x10},
3054 {value: 0x0018, lo: 0x80, hi: 0x87},
3055 {value: 0x0040, lo: 0x88, hi: 0x8f},
3056 {value: 0x1308, lo: 0x90, hi: 0x92},
3057 {value: 0x0018, lo: 0x93, hi: 0x93},
3058 {value: 0x1308, lo: 0x94, hi: 0xa0},
3059 {value: 0x1008, lo: 0xa1, hi: 0xa1},
3060 {value: 0x1308, lo: 0xa2, hi: 0xa8},
3061 {value: 0x0008, lo: 0xa9, hi: 0xac},
3062 {value: 0x1308, lo: 0xad, hi: 0xad},
3063 {value: 0x0008, lo: 0xae, hi: 0xb1},
3064 {value: 0x1008, lo: 0xb2, hi: 0xb3},
3065 {value: 0x1308, lo: 0xb4, hi: 0xb4},
3066 {value: 0x0008, lo: 0xb5, hi: 0xb6},
3067 {value: 0x0040, lo: 0xb7, hi: 0xb7},
3068 {value: 0x1308, lo: 0xb8, hi: 0xb9},
3069 {value: 0x0040, lo: 0xba, hi: 0xbf},
3070 // Block 0x46, offset 0x291
3071 {value: 0x0000, lo: 0x03},
3072 {value: 0x1308, lo: 0x80, hi: 0xb5},
3073 {value: 0x0040, lo: 0xb6, hi: 0xba},
3074 {value: 0x1308, lo: 0xbb, hi: 0xbf},
3075 // Block 0x47, offset 0x295
3076 {value: 0x0000, lo: 0x0a},
3077 {value: 0x0008, lo: 0x80, hi: 0x87},
3078 {value: 0xe045, lo: 0x88, hi: 0x8f},
3079 {value: 0x0008, lo: 0x90, hi: 0x95},
3080 {value: 0x0040, lo: 0x96, hi: 0x97},
3081 {value: 0xe045, lo: 0x98, hi: 0x9d},
3082 {value: 0x0040, lo: 0x9e, hi: 0x9f},
3083 {value: 0x0008, lo: 0xa0, hi: 0xa7},
3084 {value: 0xe045, lo: 0xa8, hi: 0xaf},
3085 {value: 0x0008, lo: 0xb0, hi: 0xb7},
3086 {value: 0xe045, lo: 0xb8, hi: 0xbf},
3087 // Block 0x48, offset 0x2a0
3088 {value: 0x0000, lo: 0x03},
3089 {value: 0x0040, lo: 0x80, hi: 0x8f},
3090 {value: 0x1318, lo: 0x90, hi: 0xb0},
3091 {value: 0x0040, lo: 0xb1, hi: 0xbf},
3092 // Block 0x49, offset 0x2a4
3093 {value: 0x0000, lo: 0x08},
3094 {value: 0x0018, lo: 0x80, hi: 0x82},
3095 {value: 0x0040, lo: 0x83, hi: 0x83},
3096 {value: 0x0008, lo: 0x84, hi: 0x84},
3097 {value: 0x0018, lo: 0x85, hi: 0x88},
3098 {value: 0x24c1, lo: 0x89, hi: 0x89},
3099 {value: 0x0018, lo: 0x8a, hi: 0x8b},
3100 {value: 0x0040, lo: 0x8c, hi: 0x8f},
3101 {value: 0x0018, lo: 0x90, hi: 0xbf},
3102 // Block 0x4a, offset 0x2ad
3103 {value: 0x0000, lo: 0x07},
3104 {value: 0x0018, lo: 0x80, hi: 0xab},
3105 {value: 0x24f1, lo: 0xac, hi: 0xac},
3106 {value: 0x2529, lo: 0xad, hi: 0xad},
3107 {value: 0x0018, lo: 0xae, hi: 0xae},
3108 {value: 0x2579, lo: 0xaf, hi: 0xaf},
3109 {value: 0x25b1, lo: 0xb0, hi: 0xb0},
3110 {value: 0x0018, lo: 0xb1, hi: 0xbf},
3111 // Block 0x4b, offset 0x2b5
3112 {value: 0x0000, lo: 0x05},
3113 {value: 0x0018, lo: 0x80, hi: 0x9f},
3114 {value: 0x0080, lo: 0xa0, hi: 0xa0},
3115 {value: 0x0018, lo: 0xa1, hi: 0xad},
3116 {value: 0x0080, lo: 0xae, hi: 0xaf},
3117 {value: 0x0018, lo: 0xb0, hi: 0xbf},
3118 // Block 0x4c, offset 0x2bb
3119 {value: 0x0000, lo: 0x04},
3120 {value: 0x0018, lo: 0x80, hi: 0xa8},
3121 {value: 0x09c5, lo: 0xa9, hi: 0xa9},
3122 {value: 0x09e5, lo: 0xaa, hi: 0xaa},
3123 {value: 0x0018, lo: 0xab, hi: 0xbf},
3124 // Block 0x4d, offset 0x2c0
3125 {value: 0x0000, lo: 0x02},
3126 {value: 0x0018, lo: 0x80, hi: 0xbe},
3127 {value: 0x0040, lo: 0xbf, hi: 0xbf},
3128 // Block 0x4e, offset 0x2c3
3129 {value: 0x0000, lo: 0x02},
3130 {value: 0x0018, lo: 0x80, hi: 0xa6},
3131 {value: 0x0040, lo: 0xa7, hi: 0xbf},
3132 // Block 0x4f, offset 0x2c6
3133 {value: 0x0000, lo: 0x03},
3134 {value: 0x0018, lo: 0x80, hi: 0x8b},
3135 {value: 0x28c1, lo: 0x8c, hi: 0x8c},
3136 {value: 0x0018, lo: 0x8d, hi: 0xbf},
3137 // Block 0x50, offset 0x2ca
3138 {value: 0x0000, lo: 0x05},
3139 {value: 0x0018, lo: 0x80, hi: 0xb3},
3140 {value: 0x0e66, lo: 0xb4, hi: 0xb4},
3141 {value: 0x292a, lo: 0xb5, hi: 0xb5},
3142 {value: 0x0e86, lo: 0xb6, hi: 0xb6},
3143 {value: 0x0018, lo: 0xb7, hi: 0xbf},
3144 // Block 0x51, offset 0x2d0
3145 {value: 0x0000, lo: 0x03},
3146 {value: 0x0018, lo: 0x80, hi: 0x9b},
3147 {value: 0x2941, lo: 0x9c, hi: 0x9c},
3148 {value: 0x0018, lo: 0x9d, hi: 0xbf},
3149 // Block 0x52, offset 0x2d4
3150 {value: 0x0000, lo: 0x03},
3151 {value: 0x0018, lo: 0x80, hi: 0xb3},
3152 {value: 0x0040, lo: 0xb4, hi: 0xb5},
3153 {value: 0x0018, lo: 0xb6, hi: 0xbf},
3154 // Block 0x53, offset 0x2d8
3155 {value: 0x0000, lo: 0x05},
3156 {value: 0x0018, lo: 0x80, hi: 0x95},
3157 {value: 0x0040, lo: 0x96, hi: 0x97},
3158 {value: 0x0018, lo: 0x98, hi: 0xb9},
3159 {value: 0x0040, lo: 0xba, hi: 0xbc},
3160 {value: 0x0018, lo: 0xbd, hi: 0xbf},
3161 // Block 0x54, offset 0x2de
3162 {value: 0x0000, lo: 0x06},
3163 {value: 0x0018, lo: 0x80, hi: 0x88},
3164 {value: 0x0040, lo: 0x89, hi: 0x89},
3165 {value: 0x0018, lo: 0x8a, hi: 0x91},
3166 {value: 0x0040, lo: 0x92, hi: 0xab},
3167 {value: 0x0018, lo: 0xac, hi: 0xaf},
3168 {value: 0x0040, lo: 0xb0, hi: 0xbf},
3169 // Block 0x55, offset 0x2e5
3170 {value: 0x0000, lo: 0x05},
3171 {value: 0xe185, lo: 0x80, hi: 0x8f},
3172 {value: 0x03f5, lo: 0x90, hi: 0x9f},
3173 {value: 0x0ea5, lo: 0xa0, hi: 0xae},
3174 {value: 0x0040, lo: 0xaf, hi: 0xaf},
3175 {value: 0x0008, lo: 0xb0, hi: 0xbf},
3176 // Block 0x56, offset 0x2eb
3177 {value: 0x0000, lo: 0x07},
3178 {value: 0x0008, lo: 0x80, hi: 0xa5},
3179 {value: 0x0040, lo: 0xa6, hi: 0xa6},
3180 {value: 0x0008, lo: 0xa7, hi: 0xa7},
3181 {value: 0x0040, lo: 0xa8, hi: 0xac},
3182 {value: 0x0008, lo: 0xad, hi: 0xad},
3183 {value: 0x0040, lo: 0xae, hi: 0xaf},
3184 {value: 0x0008, lo: 0xb0, hi: 0xbf},
3185 // Block 0x57, offset 0x2f3
3186 {value: 0x0000, lo: 0x06},
3187 {value: 0x0008, lo: 0x80, hi: 0xa7},
3188 {value: 0x0040, lo: 0xa8, hi: 0xae},
3189 {value: 0xe075, lo: 0xaf, hi: 0xaf},
3190 {value: 0x0018, lo: 0xb0, hi: 0xb0},
3191 {value: 0x0040, lo: 0xb1, hi: 0xbe},
3192 {value: 0x1b08, lo: 0xbf, hi: 0xbf},
3193 // Block 0x58, offset 0x2fa
3194 {value: 0x0000, lo: 0x0a},
3195 {value: 0x0008, lo: 0x80, hi: 0x96},
3196 {value: 0x0040, lo: 0x97, hi: 0x9f},
3197 {value: 0x0008, lo: 0xa0, hi: 0xa6},
3198 {value: 0x0040, lo: 0xa7, hi: 0xa7},
3199 {value: 0x0008, lo: 0xa8, hi: 0xae},
3200 {value: 0x0040, lo: 0xaf, hi: 0xaf},
3201 {value: 0x0008, lo: 0xb0, hi: 0xb6},
3202 {value: 0x0040, lo: 0xb7, hi: 0xb7},
3203 {value: 0x0008, lo: 0xb8, hi: 0xbe},
3204 {value: 0x0040, lo: 0xbf, hi: 0xbf},
3205 // Block 0x59, offset 0x305
3206 {value: 0x0000, lo: 0x09},
3207 {value: 0x0008, lo: 0x80, hi: 0x86},
3208 {value: 0x0040, lo: 0x87, hi: 0x87},
3209 {value: 0x0008, lo: 0x88, hi: 0x8e},
3210 {value: 0x0040, lo: 0x8f, hi: 0x8f},
3211 {value: 0x0008, lo: 0x90, hi: 0x96},
3212 {value: 0x0040, lo: 0x97, hi: 0x97},
3213 {value: 0x0008, lo: 0x98, hi: 0x9e},
3214 {value: 0x0040, lo: 0x9f, hi: 0x9f},
3215 {value: 0x1308, lo: 0xa0, hi: 0xbf},
3216 // Block 0x5a, offset 0x30f
3217 {value: 0x0000, lo: 0x03},
3218 {value: 0x0018, lo: 0x80, hi: 0xae},
3219 {value: 0x0008, lo: 0xaf, hi: 0xaf},
3220 {value: 0x0018, lo: 0xb0, hi: 0xbf},
3221 // Block 0x5b, offset 0x313
3222 {value: 0x0000, lo: 0x02},
3223 {value: 0x0018, lo: 0x80, hi: 0x84},
3224 {value: 0x0040, lo: 0x85, hi: 0xbf},
3225 // Block 0x5c, offset 0x316
3226 {value: 0x0000, lo: 0x05},
3227 {value: 0x0018, lo: 0x80, hi: 0x99},
3228 {value: 0x0040, lo: 0x9a, hi: 0x9a},
3229 {value: 0x0018, lo: 0x9b, hi: 0x9e},
3230 {value: 0x0edd, lo: 0x9f, hi: 0x9f},
3231 {value: 0x0018, lo: 0xa0, hi: 0xbf},
3232 // Block 0x5d, offset 0x31c
3233 {value: 0x0000, lo: 0x03},
3234 {value: 0x0018, lo: 0x80, hi: 0xb2},
3235 {value: 0x0efd, lo: 0xb3, hi: 0xb3},
3236 {value: 0x0040, lo: 0xb4, hi: 0xbf},
3237 // Block 0x5e, offset 0x320
3238 {value: 0x0020, lo: 0x01},
3239 {value: 0x0f1d, lo: 0x80, hi: 0xbf},
3240 // Block 0x5f, offset 0x322
3241 {value: 0x0020, lo: 0x02},
3242 {value: 0x171d, lo: 0x80, hi: 0x8f},
3243 {value: 0x18fd, lo: 0x90, hi: 0xbf},
3244 // Block 0x60, offset 0x325
3245 {value: 0x0020, lo: 0x01},
3246 {value: 0x1efd, lo: 0x80, hi: 0xbf},
3247 // Block 0x61, offset 0x327
3248 {value: 0x0000, lo: 0x02},
3249 {value: 0x0040, lo: 0x80, hi: 0x80},
3250 {value: 0x0008, lo: 0x81, hi: 0xbf},
3251 // Block 0x62, offset 0x32a
3252 {value: 0x0000, lo: 0x09},
3253 {value: 0x0008, lo: 0x80, hi: 0x96},
3254 {value: 0x0040, lo: 0x97, hi: 0x98},
3255 {value: 0x1308, lo: 0x99, hi: 0x9a},
3256 {value: 0x29e2, lo: 0x9b, hi: 0x9b},
3257 {value: 0x2a0a, lo: 0x9c, hi: 0x9c},
3258 {value: 0x0008, lo: 0x9d, hi: 0x9e},
3259 {value: 0x2a31, lo: 0x9f, hi: 0x9f},
3260 {value: 0x0018, lo: 0xa0, hi: 0xa0},
3261 {value: 0x0008, lo: 0xa1, hi: 0xbf},
3262 // Block 0x63, offset 0x334
3263 {value: 0x0000, lo: 0x02},
3264 {value: 0x0008, lo: 0x80, hi: 0xbe},
3265 {value: 0x2a69, lo: 0xbf, hi: 0xbf},
3266 // Block 0x64, offset 0x337
3267 {value: 0x0000, lo: 0x0e},
3268 {value: 0x0040, lo: 0x80, hi: 0x84},
3269 {value: 0x0008, lo: 0x85, hi: 0xad},
3270 {value: 0x0040, lo: 0xae, hi: 0xb0},
3271 {value: 0x2a1d, lo: 0xb1, hi: 0xb1},
3272 {value: 0x2a3d, lo: 0xb2, hi: 0xb2},
3273 {value: 0x2a5d, lo: 0xb3, hi: 0xb3},
3274 {value: 0x2a7d, lo: 0xb4, hi: 0xb4},
3275 {value: 0x2a5d, lo: 0xb5, hi: 0xb5},
3276 {value: 0x2a9d, lo: 0xb6, hi: 0xb6},
3277 {value: 0x2abd, lo: 0xb7, hi: 0xb7},
3278 {value: 0x2add, lo: 0xb8, hi: 0xb9},
3279 {value: 0x2afd, lo: 0xba, hi: 0xbb},
3280 {value: 0x2b1d, lo: 0xbc, hi: 0xbd},
3281 {value: 0x2afd, lo: 0xbe, hi: 0xbf},
3282 // Block 0x65, offset 0x346
3283 {value: 0x0000, lo: 0x03},
3284 {value: 0x0018, lo: 0x80, hi: 0xa3},
3285 {value: 0x0040, lo: 0xa4, hi: 0xaf},
3286 {value: 0x0008, lo: 0xb0, hi: 0xbf},
3287 // Block 0x66, offset 0x34a
3288 {value: 0x0030, lo: 0x04},
3289 {value: 0x2aa2, lo: 0x80, hi: 0x9d},
3290 {value: 0x305a, lo: 0x9e, hi: 0x9e},
3291 {value: 0x0040, lo: 0x9f, hi: 0x9f},
3292 {value: 0x30a2, lo: 0xa0, hi: 0xbf},
3293 // Block 0x67, offset 0x34f
3294 {value: 0x0000, lo: 0x02},
3295 {value: 0x0008, lo: 0x80, hi: 0x95},
3296 {value: 0x0040, lo: 0x96, hi: 0xbf},
3297 // Block 0x68, offset 0x352
3298 {value: 0x0000, lo: 0x03},
3299 {value: 0x0008, lo: 0x80, hi: 0x8c},
3300 {value: 0x0040, lo: 0x8d, hi: 0x8f},
3301 {value: 0x0018, lo: 0x90, hi: 0xbf},
3302 // Block 0x69, offset 0x356
3303 {value: 0x0000, lo: 0x04},
3304 {value: 0x0018, lo: 0x80, hi: 0x86},
3305 {value: 0x0040, lo: 0x87, hi: 0x8f},
3306 {value: 0x0008, lo: 0x90, hi: 0xbd},
3307 {value: 0x0018, lo: 0xbe, hi: 0xbf},
3308 // Block 0x6a, offset 0x35b
3309 {value: 0x0000, lo: 0x04},
3310 {value: 0x0008, lo: 0x80, hi: 0x8c},
3311 {value: 0x0018, lo: 0x8d, hi: 0x8f},
3312 {value: 0x0008, lo: 0x90, hi: 0xab},
3313 {value: 0x0040, lo: 0xac, hi: 0xbf},
3314 // Block 0x6b, offset 0x360
3315 {value: 0x0000, lo: 0x05},
3316 {value: 0x0008, lo: 0x80, hi: 0xa5},
3317 {value: 0x0018, lo: 0xa6, hi: 0xaf},
3318 {value: 0x1308, lo: 0xb0, hi: 0xb1},
3319 {value: 0x0018, lo: 0xb2, hi: 0xb7},
3320 {value: 0x0040, lo: 0xb8, hi: 0xbf},
3321 // Block 0x6c, offset 0x366
3322 {value: 0x0000, lo: 0x05},
3323 {value: 0x0040, lo: 0x80, hi: 0xb6},
3324 {value: 0x0008, lo: 0xb7, hi: 0xb7},
3325 {value: 0x2009, lo: 0xb8, hi: 0xb8},
3326 {value: 0x6e89, lo: 0xb9, hi: 0xb9},
3327 {value: 0x0008, lo: 0xba, hi: 0xbf},
3328 // Block 0x6d, offset 0x36c
3329 {value: 0x0000, lo: 0x0e},
3330 {value: 0x0008, lo: 0x80, hi: 0x81},
3331 {value: 0x1308, lo: 0x82, hi: 0x82},
3332 {value: 0x0008, lo: 0x83, hi: 0x85},
3333 {value: 0x1b08, lo: 0x86, hi: 0x86},
3334 {value: 0x0008, lo: 0x87, hi: 0x8a},
3335 {value: 0x1308, lo: 0x8b, hi: 0x8b},
3336 {value: 0x0008, lo: 0x8c, hi: 0xa2},
3337 {value: 0x1008, lo: 0xa3, hi: 0xa4},
3338 {value: 0x1308, lo: 0xa5, hi: 0xa6},
3339 {value: 0x1008, lo: 0xa7, hi: 0xa7},
3340 {value: 0x0018, lo: 0xa8, hi: 0xab},
3341 {value: 0x0040, lo: 0xac, hi: 0xaf},
3342 {value: 0x0018, lo: 0xb0, hi: 0xb9},
3343 {value: 0x0040, lo: 0xba, hi: 0xbf},
3344 // Block 0x6e, offset 0x37b
3345 {value: 0x0000, lo: 0x05},
3346 {value: 0x0208, lo: 0x80, hi: 0xb1},
3347 {value: 0x0108, lo: 0xb2, hi: 0xb2},
3348 {value: 0x0008, lo: 0xb3, hi: 0xb3},
3349 {value: 0x0018, lo: 0xb4, hi: 0xb7},
3350 {value: 0x0040, lo: 0xb8, hi: 0xbf},
3351 // Block 0x6f, offset 0x381
3352 {value: 0x0000, lo: 0x03},
3353 {value: 0x1008, lo: 0x80, hi: 0x81},
3354 {value: 0x0008, lo: 0x82, hi: 0xb3},
3355 {value: 0x1008, lo: 0xb4, hi: 0xbf},
3356 // Block 0x70, offset 0x385
3357 {value: 0x0000, lo: 0x0e},
3358 {value: 0x1008, lo: 0x80, hi: 0x83},
3359 {value: 0x1b08, lo: 0x84, hi: 0x84},
3360 {value: 0x1308, lo: 0x85, hi: 0x85},
3361 {value: 0x0040, lo: 0x86, hi: 0x8d},
3362 {value: 0x0018, lo: 0x8e, hi: 0x8f},
3363 {value: 0x0008, lo: 0x90, hi: 0x99},
3364 {value: 0x0040, lo: 0x9a, hi: 0x9f},
3365 {value: 0x1308, lo: 0xa0, hi: 0xb1},
3366 {value: 0x0008, lo: 0xb2, hi: 0xb7},
3367 {value: 0x0018, lo: 0xb8, hi: 0xba},
3368 {value: 0x0008, lo: 0xbb, hi: 0xbb},
3369 {value: 0x0018, lo: 0xbc, hi: 0xbc},
3370 {value: 0x0008, lo: 0xbd, hi: 0xbd},
3371 {value: 0x0040, lo: 0xbe, hi: 0xbf},
3372 // Block 0x71, offset 0x394
3373 {value: 0x0000, lo: 0x04},
3374 {value: 0x0008, lo: 0x80, hi: 0xa5},
3375 {value: 0x1308, lo: 0xa6, hi: 0xad},
3376 {value: 0x0018, lo: 0xae, hi: 0xaf},
3377 {value: 0x0008, lo: 0xb0, hi: 0xbf},
3378 // Block 0x72, offset 0x399
3379 {value: 0x0000, lo: 0x07},
3380 {value: 0x0008, lo: 0x80, hi: 0x86},
3381 {value: 0x1308, lo: 0x87, hi: 0x91},
3382 {value: 0x1008, lo: 0x92, hi: 0x92},
3383 {value: 0x1808, lo: 0x93, hi: 0x93},
3384 {value: 0x0040, lo: 0x94, hi: 0x9e},
3385 {value: 0x0018, lo: 0x9f, hi: 0xbc},
3386 {value: 0x0040, lo: 0xbd, hi: 0xbf},
3387 // Block 0x73, offset 0x3a1
3388 {value: 0x0000, lo: 0x09},
3389 {value: 0x1308, lo: 0x80, hi: 0x82},
3390 {value: 0x1008, lo: 0x83, hi: 0x83},
3391 {value: 0x0008, lo: 0x84, hi: 0xb2},
3392 {value: 0x1308, lo: 0xb3, hi: 0xb3},
3393 {value: 0x1008, lo: 0xb4, hi: 0xb5},
3394 {value: 0x1308, lo: 0xb6, hi: 0xb9},
3395 {value: 0x1008, lo: 0xba, hi: 0xbb},
3396 {value: 0x1308, lo: 0xbc, hi: 0xbc},
3397 {value: 0x1008, lo: 0xbd, hi: 0xbf},
3398 // Block 0x74, offset 0x3ab
3399 {value: 0x0000, lo: 0x0a},
3400 {value: 0x1808, lo: 0x80, hi: 0x80},
3401 {value: 0x0018, lo: 0x81, hi: 0x8d},
3402 {value: 0x0040, lo: 0x8e, hi: 0x8e},
3403 {value: 0x0008, lo: 0x8f, hi: 0x99},
3404 {value: 0x0040, lo: 0x9a, hi: 0x9d},
3405 {value: 0x0018, lo: 0x9e, hi: 0x9f},
3406 {value: 0x0008, lo: 0xa0, hi: 0xa4},
3407 {value: 0x1308, lo: 0xa5, hi: 0xa5},
3408 {value: 0x0008, lo: 0xa6, hi: 0xbe},
3409 {value: 0x0040, lo: 0xbf, hi: 0xbf},
3410 // Block 0x75, offset 0x3b6
3411 {value: 0x0000, lo: 0x07},
3412 {value: 0x0008, lo: 0x80, hi: 0xa8},
3413 {value: 0x1308, lo: 0xa9, hi: 0xae},
3414 {value: 0x1008, lo: 0xaf, hi: 0xb0},
3415 {value: 0x1308, lo: 0xb1, hi: 0xb2},
3416 {value: 0x1008, lo: 0xb3, hi: 0xb4},
3417 {value: 0x1308, lo: 0xb5, hi: 0xb6},
3418 {value: 0x0040, lo: 0xb7, hi: 0xbf},
3419 // Block 0x76, offset 0x3be
3420 {value: 0x0000, lo: 0x10},
3421 {value: 0x0008, lo: 0x80, hi: 0x82},
3422 {value: 0x1308, lo: 0x83, hi: 0x83},
3423 {value: 0x0008, lo: 0x84, hi: 0x8b},
3424 {value: 0x1308, lo: 0x8c, hi: 0x8c},
3425 {value: 0x1008, lo: 0x8d, hi: 0x8d},
3426 {value: 0x0040, lo: 0x8e, hi: 0x8f},
3427 {value: 0x0008, lo: 0x90, hi: 0x99},
3428 {value: 0x0040, lo: 0x9a, hi: 0x9b},
3429 {value: 0x0018, lo: 0x9c, hi: 0x9f},
3430 {value: 0x0008, lo: 0xa0, hi: 0xb6},
3431 {value: 0x0018, lo: 0xb7, hi: 0xb9},
3432 {value: 0x0008, lo: 0xba, hi: 0xba},
3433 {value: 0x1008, lo: 0xbb, hi: 0xbb},
3434 {value: 0x1308, lo: 0xbc, hi: 0xbc},
3435 {value: 0x1008, lo: 0xbd, hi: 0xbd},
3436 {value: 0x0008, lo: 0xbe, hi: 0xbf},
3437 // Block 0x77, offset 0x3cf
3438 {value: 0x0000, lo: 0x08},
3439 {value: 0x0008, lo: 0x80, hi: 0xaf},
3440 {value: 0x1308, lo: 0xb0, hi: 0xb0},
3441 {value: 0x0008, lo: 0xb1, hi: 0xb1},
3442 {value: 0x1308, lo: 0xb2, hi: 0xb4},
3443 {value: 0x0008, lo: 0xb5, hi: 0xb6},
3444 {value: 0x1308, lo: 0xb7, hi: 0xb8},
3445 {value: 0x0008, lo: 0xb9, hi: 0xbd},
3446 {value: 0x1308, lo: 0xbe, hi: 0xbf},
3447 // Block 0x78, offset 0x3d8
3448 {value: 0x0000, lo: 0x0f},
3449 {value: 0x0008, lo: 0x80, hi: 0x80},
3450 {value: 0x1308, lo: 0x81, hi: 0x81},
3451 {value: 0x0008, lo: 0x82, hi: 0x82},
3452 {value: 0x0040, lo: 0x83, hi: 0x9a},
3453 {value: 0x0008, lo: 0x9b, hi: 0x9d},
3454 {value: 0x0018, lo: 0x9e, hi: 0x9f},
3455 {value: 0x0008, lo: 0xa0, hi: 0xaa},
3456 {value: 0x1008, lo: 0xab, hi: 0xab},
3457 {value: 0x1308, lo: 0xac, hi: 0xad},
3458 {value: 0x1008, lo: 0xae, hi: 0xaf},
3459 {value: 0x0018, lo: 0xb0, hi: 0xb1},
3460 {value: 0x0008, lo: 0xb2, hi: 0xb4},
3461 {value: 0x1008, lo: 0xb5, hi: 0xb5},
3462 {value: 0x1b08, lo: 0xb6, hi: 0xb6},
3463 {value: 0x0040, lo: 0xb7, hi: 0xbf},
3464 // Block 0x79, offset 0x3e8
3465 {value: 0x0000, lo: 0x0c},
3466 {value: 0x0040, lo: 0x80, hi: 0x80},
3467 {value: 0x0008, lo: 0x81, hi: 0x86},
3468 {value: 0x0040, lo: 0x87, hi: 0x88},
3469 {value: 0x0008, lo: 0x89, hi: 0x8e},
3470 {value: 0x0040, lo: 0x8f, hi: 0x90},
3471 {value: 0x0008, lo: 0x91, hi: 0x96},
3472 {value: 0x0040, lo: 0x97, hi: 0x9f},
3473 {value: 0x0008, lo: 0xa0, hi: 0xa6},
3474 {value: 0x0040, lo: 0xa7, hi: 0xa7},
3475 {value: 0x0008, lo: 0xa8, hi: 0xae},
3476 {value: 0x0040, lo: 0xaf, hi: 0xaf},
3477 {value: 0x0008, lo: 0xb0, hi: 0xbf},
3478 // Block 0x7a, offset 0x3f5
3479 {value: 0x0000, lo: 0x09},
3480 {value: 0x0008, lo: 0x80, hi: 0x9a},
3481 {value: 0x0018, lo: 0x9b, hi: 0x9b},
3482 {value: 0x4465, lo: 0x9c, hi: 0x9c},
3483 {value: 0x447d, lo: 0x9d, hi: 0x9d},
3484 {value: 0x2971, lo: 0x9e, hi: 0x9e},
3485 {value: 0xe06d, lo: 0x9f, hi: 0x9f},
3486 {value: 0x0008, lo: 0xa0, hi: 0xa5},
3487 {value: 0x0040, lo: 0xa6, hi: 0xaf},
3488 {value: 0x4495, lo: 0xb0, hi: 0xbf},
3489 // Block 0x7b, offset 0x3ff
3490 {value: 0x0000, lo: 0x04},
3491 {value: 0x44b5, lo: 0x80, hi: 0x8f},
3492 {value: 0x44d5, lo: 0x90, hi: 0x9f},
3493 {value: 0x44f5, lo: 0xa0, hi: 0xaf},
3494 {value: 0x44d5, lo: 0xb0, hi: 0xbf},
3495 // Block 0x7c, offset 0x404
3496 {value: 0x0000, lo: 0x0c},
3497 {value: 0x0008, lo: 0x80, hi: 0xa2},
3498 {value: 0x1008, lo: 0xa3, hi: 0xa4},
3499 {value: 0x1308, lo: 0xa5, hi: 0xa5},
3500 {value: 0x1008, lo: 0xa6, hi: 0xa7},
3501 {value: 0x1308, lo: 0xa8, hi: 0xa8},
3502 {value: 0x1008, lo: 0xa9, hi: 0xaa},
3503 {value: 0x0018, lo: 0xab, hi: 0xab},
3504 {value: 0x1008, lo: 0xac, hi: 0xac},
3505 {value: 0x1b08, lo: 0xad, hi: 0xad},
3506 {value: 0x0040, lo: 0xae, hi: 0xaf},
3507 {value: 0x0008, lo: 0xb0, hi: 0xb9},
3508 {value: 0x0040, lo: 0xba, hi: 0xbf},
3509 // Block 0x7d, offset 0x411
3510 {value: 0x0000, lo: 0x03},
3511 {value: 0x0008, lo: 0x80, hi: 0xa3},
3512 {value: 0x0040, lo: 0xa4, hi: 0xaf},
3513 {value: 0x0018, lo: 0xb0, hi: 0xbf},
3514 // Block 0x7e, offset 0x415
3515 {value: 0x0000, lo: 0x04},
3516 {value: 0x0018, lo: 0x80, hi: 0x86},
3517 {value: 0x0040, lo: 0x87, hi: 0x8a},
3518 {value: 0x0018, lo: 0x8b, hi: 0xbb},
3519 {value: 0x0040, lo: 0xbc, hi: 0xbf},
3520 // Block 0x7f, offset 0x41a
3521 {value: 0x0020, lo: 0x01},
3522 {value: 0x4515, lo: 0x80, hi: 0xbf},
3523 // Block 0x80, offset 0x41c
3524 {value: 0x0020, lo: 0x03},
3525 {value: 0x4d15, lo: 0x80, hi: 0x94},
3526 {value: 0x4ad5, lo: 0x95, hi: 0x95},
3527 {value: 0x4fb5, lo: 0x96, hi: 0xbf},
3528 // Block 0x81, offset 0x420
3529 {value: 0x0020, lo: 0x01},
3530 {value: 0x54f5, lo: 0x80, hi: 0xbf},
3531 // Block 0x82, offset 0x422
3532 {value: 0x0020, lo: 0x03},
3533 {value: 0x5cf5, lo: 0x80, hi: 0x84},
3534 {value: 0x5655, lo: 0x85, hi: 0x85},
3535 {value: 0x5d95, lo: 0x86, hi: 0xbf},
3536 // Block 0x83, offset 0x426
3537 {value: 0x0020, lo: 0x08},
3538 {value: 0x6b55, lo: 0x80, hi: 0x8f},
3539 {value: 0x6d15, lo: 0x90, hi: 0x90},
3540 {value: 0x6d55, lo: 0x91, hi: 0xab},
3541 {value: 0x6ea1, lo: 0xac, hi: 0xac},
3542 {value: 0x70b5, lo: 0xad, hi: 0xad},
3543 {value: 0x0040, lo: 0xae, hi: 0xae},
3544 {value: 0x0040, lo: 0xaf, hi: 0xaf},
3545 {value: 0x70d5, lo: 0xb0, hi: 0xbf},
3546 // Block 0x84, offset 0x42f
3547 {value: 0x0020, lo: 0x05},
3548 {value: 0x72d5, lo: 0x80, hi: 0xad},
3549 {value: 0x6535, lo: 0xae, hi: 0xae},
3550 {value: 0x7895, lo: 0xaf, hi: 0xb5},
3551 {value: 0x6f55, lo: 0xb6, hi: 0xb6},
3552 {value: 0x7975, lo: 0xb7, hi: 0xbf},
3553 // Block 0x85, offset 0x435
3554 {value: 0x0028, lo: 0x03},
3555 {value: 0x7c21, lo: 0x80, hi: 0x82},
3556 {value: 0x7be1, lo: 0x83, hi: 0x83},
3557 {value: 0x7c99, lo: 0x84, hi: 0xbf},
3558 // Block 0x86, offset 0x439
3559 {value: 0x0038, lo: 0x0f},
3560 {value: 0x9db1, lo: 0x80, hi: 0x83},
3561 {value: 0x9e59, lo: 0x84, hi: 0x85},
3562 {value: 0x9e91, lo: 0x86, hi: 0x87},
3563 {value: 0x9ec9, lo: 0x88, hi: 0x8f},
3564 {value: 0x0040, lo: 0x90, hi: 0x90},
3565 {value: 0x0040, lo: 0x91, hi: 0x91},
3566 {value: 0xa089, lo: 0x92, hi: 0x97},
3567 {value: 0xa1a1, lo: 0x98, hi: 0x9c},
3568 {value: 0xa281, lo: 0x9d, hi: 0xb3},
3569 {value: 0x9d41, lo: 0xb4, hi: 0xb4},
3570 {value: 0x9db1, lo: 0xb5, hi: 0xb5},
3571 {value: 0xa789, lo: 0xb6, hi: 0xbb},
3572 {value: 0xa869, lo: 0xbc, hi: 0xbc},
3573 {value: 0xa7f9, lo: 0xbd, hi: 0xbd},
3574 {value: 0xa8d9, lo: 0xbe, hi: 0xbf},
3575 // Block 0x87, offset 0x449
3576 {value: 0x0000, lo: 0x09},
3577 {value: 0x0008, lo: 0x80, hi: 0x8b},
3578 {value: 0x0040, lo: 0x8c, hi: 0x8c},
3579 {value: 0x0008, lo: 0x8d, hi: 0xa6},
3580 {value: 0x0040, lo: 0xa7, hi: 0xa7},
3581 {value: 0x0008, lo: 0xa8, hi: 0xba},
3582 {value: 0x0040, lo: 0xbb, hi: 0xbb},
3583 {value: 0x0008, lo: 0xbc, hi: 0xbd},
3584 {value: 0x0040, lo: 0xbe, hi: 0xbe},
3585 {value: 0x0008, lo: 0xbf, hi: 0xbf},
3586 // Block 0x88, offset 0x453
3587 {value: 0x0000, lo: 0x04},
3588 {value: 0x0008, lo: 0x80, hi: 0x8d},
3589 {value: 0x0040, lo: 0x8e, hi: 0x8f},
3590 {value: 0x0008, lo: 0x90, hi: 0x9d},
3591 {value: 0x0040, lo: 0x9e, hi: 0xbf},
3592 // Block 0x89, offset 0x458
3593 {value: 0x0000, lo: 0x02},
3594 {value: 0x0008, lo: 0x80, hi: 0xba},
3595 {value: 0x0040, lo: 0xbb, hi: 0xbf},
3596 // Block 0x8a, offset 0x45b
3597 {value: 0x0000, lo: 0x05},
3598 {value: 0x0018, lo: 0x80, hi: 0x82},
3599 {value: 0x0040, lo: 0x83, hi: 0x86},
3600 {value: 0x0018, lo: 0x87, hi: 0xb3},
3601 {value: 0x0040, lo: 0xb4, hi: 0xb6},
3602 {value: 0x0018, lo: 0xb7, hi: 0xbf},
3603 // Block 0x8b, offset 0x461
3604 {value: 0x0000, lo: 0x06},
3605 {value: 0x0018, lo: 0x80, hi: 0x8e},
3606 {value: 0x0040, lo: 0x8f, hi: 0x8f},
3607 {value: 0x0018, lo: 0x90, hi: 0x9b},
3608 {value: 0x0040, lo: 0x9c, hi: 0x9f},
3609 {value: 0x0018, lo: 0xa0, hi: 0xa0},
3610 {value: 0x0040, lo: 0xa1, hi: 0xbf},
3611 // Block 0x8c, offset 0x468
3612 {value: 0x0000, lo: 0x04},
3613 {value: 0x0040, lo: 0x80, hi: 0x8f},
3614 {value: 0x0018, lo: 0x90, hi: 0xbc},
3615 {value: 0x1308, lo: 0xbd, hi: 0xbd},
3616 {value: 0x0040, lo: 0xbe, hi: 0xbf},
3617 // Block 0x8d, offset 0x46d
3618 {value: 0x0000, lo: 0x03},
3619 {value: 0x0008, lo: 0x80, hi: 0x9c},
3620 {value: 0x0040, lo: 0x9d, hi: 0x9f},
3621 {value: 0x0008, lo: 0xa0, hi: 0xbf},
3622 // Block 0x8e, offset 0x471
3623 {value: 0x0000, lo: 0x05},
3624 {value: 0x0008, lo: 0x80, hi: 0x90},
3625 {value: 0x0040, lo: 0x91, hi: 0x9f},
3626 {value: 0x1308, lo: 0xa0, hi: 0xa0},
3627 {value: 0x0018, lo: 0xa1, hi: 0xbb},
3628 {value: 0x0040, lo: 0xbc, hi: 0xbf},
3629 // Block 0x8f, offset 0x477
3630 {value: 0x0000, lo: 0x04},
3631 {value: 0x0008, lo: 0x80, hi: 0x9f},
3632 {value: 0x0018, lo: 0xa0, hi: 0xa3},
3633 {value: 0x0040, lo: 0xa4, hi: 0xaf},
3634 {value: 0x0008, lo: 0xb0, hi: 0xbf},
3635 // Block 0x90, offset 0x47c
3636 {value: 0x0000, lo: 0x08},
3637 {value: 0x0008, lo: 0x80, hi: 0x80},
3638 {value: 0x0018, lo: 0x81, hi: 0x81},
3639 {value: 0x0008, lo: 0x82, hi: 0x89},
3640 {value: 0x0018, lo: 0x8a, hi: 0x8a},
3641 {value: 0x0040, lo: 0x8b, hi: 0x8f},
3642 {value: 0x0008, lo: 0x90, hi: 0xb5},
3643 {value: 0x1308, lo: 0xb6, hi: 0xba},
3644 {value: 0x0040, lo: 0xbb, hi: 0xbf},
3645 // Block 0x91, offset 0x485
3646 {value: 0x0000, lo: 0x04},
3647 {value: 0x0008, lo: 0x80, hi: 0x9d},
3648 {value: 0x0040, lo: 0x9e, hi: 0x9e},
3649 {value: 0x0018, lo: 0x9f, hi: 0x9f},
3650 {value: 0x0008, lo: 0xa0, hi: 0xbf},
3651 // Block 0x92, offset 0x48a
3652 {value: 0x0000, lo: 0x05},
3653 {value: 0x0008, lo: 0x80, hi: 0x83},
3654 {value: 0x0040, lo: 0x84, hi: 0x87},
3655 {value: 0x0008, lo: 0x88, hi: 0x8f},
3656 {value: 0x0018, lo: 0x90, hi: 0x95},
3657 {value: 0x0040, lo: 0x96, hi: 0xbf},
3658 // Block 0x93, offset 0x490
3659 {value: 0x0000, lo: 0x06},
3660 {value: 0xe145, lo: 0x80, hi: 0x87},
3661 {value: 0xe1c5, lo: 0x88, hi: 0x8f},
3662 {value: 0xe145, lo: 0x90, hi: 0x97},
3663 {value: 0x8ad5, lo: 0x98, hi: 0x9f},
3664 {value: 0x8aed, lo: 0xa0, hi: 0xa7},
3665 {value: 0x0008, lo: 0xa8, hi: 0xbf},
3666 // Block 0x94, offset 0x497
3667 {value: 0x0000, lo: 0x06},
3668 {value: 0x0008, lo: 0x80, hi: 0x9d},
3669 {value: 0x0040, lo: 0x9e, hi: 0x9f},
3670 {value: 0x0008, lo: 0xa0, hi: 0xa9},
3671 {value: 0x0040, lo: 0xaa, hi: 0xaf},
3672 {value: 0x8aed, lo: 0xb0, hi: 0xb7},
3673 {value: 0x8ad5, lo: 0xb8, hi: 0xbf},
3674 // Block 0x95, offset 0x49e
3675 {value: 0x0000, lo: 0x06},
3676 {value: 0xe145, lo: 0x80, hi: 0x87},
3677 {value: 0xe1c5, lo: 0x88, hi: 0x8f},
3678 {value: 0xe145, lo: 0x90, hi: 0x93},
3679 {value: 0x0040, lo: 0x94, hi: 0x97},
3680 {value: 0x0008, lo: 0x98, hi: 0xbb},
3681 {value: 0x0040, lo: 0xbc, hi: 0xbf},
3682 // Block 0x96, offset 0x4a5
3683 {value: 0x0000, lo: 0x03},
3684 {value: 0x0008, lo: 0x80, hi: 0xa7},
3685 {value: 0x0040, lo: 0xa8, hi: 0xaf},
3686 {value: 0x0008, lo: 0xb0, hi: 0xbf},
3687 // Block 0x97, offset 0x4a9
3688 {value: 0x0000, lo: 0x04},
3689 {value: 0x0008, lo: 0x80, hi: 0xa3},
3690 {value: 0x0040, lo: 0xa4, hi: 0xae},
3691 {value: 0x0018, lo: 0xaf, hi: 0xaf},
3692 {value: 0x0040, lo: 0xb0, hi: 0xbf},
3693 // Block 0x98, offset 0x4ae
3694 {value: 0x0000, lo: 0x02},
3695 {value: 0x0008, lo: 0x80, hi: 0xb6},
3696 {value: 0x0040, lo: 0xb7, hi: 0xbf},
3697 // Block 0x99, offset 0x4b1
3698 {value: 0x0000, lo: 0x04},
3699 {value: 0x0008, lo: 0x80, hi: 0x95},
3700 {value: 0x0040, lo: 0x96, hi: 0x9f},
3701 {value: 0x0008, lo: 0xa0, hi: 0xa7},
3702 {value: 0x0040, lo: 0xa8, hi: 0xbf},
3703 // Block 0x9a, offset 0x4b6
3704 {value: 0x0000, lo: 0x0b},
3705 {value: 0x0008, lo: 0x80, hi: 0x85},
3706 {value: 0x0040, lo: 0x86, hi: 0x87},
3707 {value: 0x0008, lo: 0x88, hi: 0x88},
3708 {value: 0x0040, lo: 0x89, hi: 0x89},
3709 {value: 0x0008, lo: 0x8a, hi: 0xb5},
3710 {value: 0x0040, lo: 0xb6, hi: 0xb6},
3711 {value: 0x0008, lo: 0xb7, hi: 0xb8},
3712 {value: 0x0040, lo: 0xb9, hi: 0xbb},
3713 {value: 0x0008, lo: 0xbc, hi: 0xbc},
3714 {value: 0x0040, lo: 0xbd, hi: 0xbe},
3715 {value: 0x0008, lo: 0xbf, hi: 0xbf},
3716 // Block 0x9b, offset 0x4c2
3717 {value: 0x0000, lo: 0x05},
3718 {value: 0x0008, lo: 0x80, hi: 0x95},
3719 {value: 0x0040, lo: 0x96, hi: 0x96},
3720 {value: 0x0018, lo: 0x97, hi: 0x9f},
3721 {value: 0x0008, lo: 0xa0, hi: 0xb6},
3722 {value: 0x0018, lo: 0xb7, hi: 0xbf},
3723 // Block 0x9c, offset 0x4c8
3724 {value: 0x0000, lo: 0x04},
3725 {value: 0x0008, lo: 0x80, hi: 0x9e},
3726 {value: 0x0040, lo: 0x9f, hi: 0xa6},
3727 {value: 0x0018, lo: 0xa7, hi: 0xaf},
3728 {value: 0x0040, lo: 0xb0, hi: 0xbf},
3729 // Block 0x9d, offset 0x4cd
3730 {value: 0x0000, lo: 0x06},
3731 {value: 0x0040, lo: 0x80, hi: 0x9f},
3732 {value: 0x0008, lo: 0xa0, hi: 0xb2},
3733 {value: 0x0040, lo: 0xb3, hi: 0xb3},
3734 {value: 0x0008, lo: 0xb4, hi: 0xb5},
3735 {value: 0x0040, lo: 0xb6, hi: 0xba},
3736 {value: 0x0018, lo: 0xbb, hi: 0xbf},
3737 // Block 0x9e, offset 0x4d4
3738 {value: 0x0000, lo: 0x07},
3739 {value: 0x0008, lo: 0x80, hi: 0x95},
3740 {value: 0x0018, lo: 0x96, hi: 0x9b},
3741 {value: 0x0040, lo: 0x9c, hi: 0x9e},
3742 {value: 0x0018, lo: 0x9f, hi: 0x9f},
3743 {value: 0x0008, lo: 0xa0, hi: 0xb9},
3744 {value: 0x0040, lo: 0xba, hi: 0xbe},
3745 {value: 0x0018, lo: 0xbf, hi: 0xbf},
3746 // Block 0x9f, offset 0x4dc
3747 {value: 0x0000, lo: 0x04},
3748 {value: 0x0008, lo: 0x80, hi: 0xb7},
3749 {value: 0x0040, lo: 0xb8, hi: 0xbb},
3750 {value: 0x0018, lo: 0xbc, hi: 0xbd},
3751 {value: 0x0008, lo: 0xbe, hi: 0xbf},
3752 // Block 0xa0, offset 0x4e1
3753 {value: 0x0000, lo: 0x03},
3754 {value: 0x0018, lo: 0x80, hi: 0x8f},
3755 {value: 0x0040, lo: 0x90, hi: 0x91},
3756 {value: 0x0018, lo: 0x92, hi: 0xbf},
3757 // Block 0xa1, offset 0x4e5
3758 {value: 0x0000, lo: 0x0f},
3759 {value: 0x0008, lo: 0x80, hi: 0x80},
3760 {value: 0x1308, lo: 0x81, hi: 0x83},
3761 {value: 0x0040, lo: 0x84, hi: 0x84},
3762 {value: 0x1308, lo: 0x85, hi: 0x86},
3763 {value: 0x0040, lo: 0x87, hi: 0x8b},
3764 {value: 0x1308, lo: 0x8c, hi: 0x8f},
3765 {value: 0x0008, lo: 0x90, hi: 0x93},
3766 {value: 0x0040, lo: 0x94, hi: 0x94},
3767 {value: 0x0008, lo: 0x95, hi: 0x97},
3768 {value: 0x0040, lo: 0x98, hi: 0x98},
3769 {value: 0x0008, lo: 0x99, hi: 0xb3},
3770 {value: 0x0040, lo: 0xb4, hi: 0xb7},
3771 {value: 0x1308, lo: 0xb8, hi: 0xba},
3772 {value: 0x0040, lo: 0xbb, hi: 0xbe},
3773 {value: 0x1b08, lo: 0xbf, hi: 0xbf},
3774 // Block 0xa2, offset 0x4f5
3775 {value: 0x0000, lo: 0x06},
3776 {value: 0x0018, lo: 0x80, hi: 0x87},
3777 {value: 0x0040, lo: 0x88, hi: 0x8f},
3778 {value: 0x0018, lo: 0x90, hi: 0x98},
3779 {value: 0x0040, lo: 0x99, hi: 0x9f},
3780 {value: 0x0008, lo: 0xa0, hi: 0xbc},
3781 {value: 0x0018, lo: 0xbd, hi: 0xbf},
3782 // Block 0xa3, offset 0x4fc
3783 {value: 0x0000, lo: 0x03},
3784 {value: 0x0008, lo: 0x80, hi: 0x9c},
3785 {value: 0x0018, lo: 0x9d, hi: 0x9f},
3786 {value: 0x0040, lo: 0xa0, hi: 0xbf},
3787 // Block 0xa4, offset 0x500
3788 {value: 0x0000, lo: 0x03},
3789 {value: 0x0008, lo: 0x80, hi: 0xb5},
3790 {value: 0x0040, lo: 0xb6, hi: 0xb8},
3791 {value: 0x0018, lo: 0xb9, hi: 0xbf},
3792 // Block 0xa5, offset 0x504
3793 {value: 0x0000, lo: 0x06},
3794 {value: 0x0008, lo: 0x80, hi: 0x95},
3795 {value: 0x0040, lo: 0x96, hi: 0x97},
3796 {value: 0x0018, lo: 0x98, hi: 0x9f},
3797 {value: 0x0008, lo: 0xa0, hi: 0xb2},
3798 {value: 0x0040, lo: 0xb3, hi: 0xb7},
3799 {value: 0x0018, lo: 0xb8, hi: 0xbf},
3800 // Block 0xa6, offset 0x50b
3801 {value: 0x0000, lo: 0x02},
3802 {value: 0x0008, lo: 0x80, hi: 0x88},
3803 {value: 0x0040, lo: 0x89, hi: 0xbf},
3804 // Block 0xa7, offset 0x50e
3805 {value: 0x0000, lo: 0x02},
3806 {value: 0x03dd, lo: 0x80, hi: 0xb2},
3807 {value: 0x0040, lo: 0xb3, hi: 0xbf},
3808 // Block 0xa8, offset 0x511
3809 {value: 0x0000, lo: 0x03},
3810 {value: 0x0008, lo: 0x80, hi: 0xb2},
3811 {value: 0x0040, lo: 0xb3, hi: 0xb9},
3812 {value: 0x0018, lo: 0xba, hi: 0xbf},
3813 // Block 0xa9, offset 0x515
3814 {value: 0x0000, lo: 0x03},
3815 {value: 0x0040, lo: 0x80, hi: 0x9f},
3816 {value: 0x0018, lo: 0xa0, hi: 0xbe},
3817 {value: 0x0040, lo: 0xbf, hi: 0xbf},
3818 // Block 0xaa, offset 0x519
3819 {value: 0x0000, lo: 0x05},
3820 {value: 0x1008, lo: 0x80, hi: 0x80},
3821 {value: 0x1308, lo: 0x81, hi: 0x81},
3822 {value: 0x1008, lo: 0x82, hi: 0x82},
3823 {value: 0x0008, lo: 0x83, hi: 0xb7},
3824 {value: 0x1308, lo: 0xb8, hi: 0xbf},
3825 // Block 0xab, offset 0x51f
3826 {value: 0x0000, lo: 0x08},
3827 {value: 0x1308, lo: 0x80, hi: 0x85},
3828 {value: 0x1b08, lo: 0x86, hi: 0x86},
3829 {value: 0x0018, lo: 0x87, hi: 0x8d},
3830 {value: 0x0040, lo: 0x8e, hi: 0x91},
3831 {value: 0x0018, lo: 0x92, hi: 0xa5},
3832 {value: 0x0008, lo: 0xa6, hi: 0xaf},
3833 {value: 0x0040, lo: 0xb0, hi: 0xbe},
3834 {value: 0x1b08, lo: 0xbf, hi: 0xbf},
3835 // Block 0xac, offset 0x528
3836 {value: 0x0000, lo: 0x0b},
3837 {value: 0x1308, lo: 0x80, hi: 0x81},
3838 {value: 0x1008, lo: 0x82, hi: 0x82},
3839 {value: 0x0008, lo: 0x83, hi: 0xaf},
3840 {value: 0x1008, lo: 0xb0, hi: 0xb2},
3841 {value: 0x1308, lo: 0xb3, hi: 0xb6},
3842 {value: 0x1008, lo: 0xb7, hi: 0xb8},
3843 {value: 0x1b08, lo: 0xb9, hi: 0xb9},
3844 {value: 0x1308, lo: 0xba, hi: 0xba},
3845 {value: 0x0018, lo: 0xbb, hi: 0xbc},
3846 {value: 0x0340, lo: 0xbd, hi: 0xbd},
3847 {value: 0x0018, lo: 0xbe, hi: 0xbf},
3848 // Block 0xad, offset 0x534
3849 {value: 0x0000, lo: 0x06},
3850 {value: 0x0018, lo: 0x80, hi: 0x81},
3851 {value: 0x0040, lo: 0x82, hi: 0x8f},
3852 {value: 0x0008, lo: 0x90, hi: 0xa8},
3853 {value: 0x0040, lo: 0xa9, hi: 0xaf},
3854 {value: 0x0008, lo: 0xb0, hi: 0xb9},
3855 {value: 0x0040, lo: 0xba, hi: 0xbf},
3856 // Block 0xae, offset 0x53b
3857 {value: 0x0000, lo: 0x08},
3858 {value: 0x1308, lo: 0x80, hi: 0x82},
3859 {value: 0x0008, lo: 0x83, hi: 0xa6},
3860 {value: 0x1308, lo: 0xa7, hi: 0xab},
3861 {value: 0x1008, lo: 0xac, hi: 0xac},
3862 {value: 0x1308, lo: 0xad, hi: 0xb2},
3863 {value: 0x1b08, lo: 0xb3, hi: 0xb4},
3864 {value: 0x0040, lo: 0xb5, hi: 0xb5},
3865 {value: 0x0008, lo: 0xb6, hi: 0xbf},
3866 // Block 0xaf, offset 0x544
3867 {value: 0x0000, lo: 0x07},
3868 {value: 0x0018, lo: 0x80, hi: 0x83},
3869 {value: 0x0040, lo: 0x84, hi: 0x8f},
3870 {value: 0x0008, lo: 0x90, hi: 0xb2},
3871 {value: 0x1308, lo: 0xb3, hi: 0xb3},
3872 {value: 0x0018, lo: 0xb4, hi: 0xb5},
3873 {value: 0x0008, lo: 0xb6, hi: 0xb6},
3874 {value: 0x0040, lo: 0xb7, hi: 0xbf},
3875 // Block 0xb0, offset 0x54c
3876 {value: 0x0000, lo: 0x06},
3877 {value: 0x1308, lo: 0x80, hi: 0x81},
3878 {value: 0x1008, lo: 0x82, hi: 0x82},
3879 {value: 0x0008, lo: 0x83, hi: 0xb2},
3880 {value: 0x1008, lo: 0xb3, hi: 0xb5},
3881 {value: 0x1308, lo: 0xb6, hi: 0xbe},
3882 {value: 0x1008, lo: 0xbf, hi: 0xbf},
3883 // Block 0xb1, offset 0x553
3884 {value: 0x0000, lo: 0x0d},
3885 {value: 0x1808, lo: 0x80, hi: 0x80},
3886 {value: 0x0008, lo: 0x81, hi: 0x84},
3887 {value: 0x0018, lo: 0x85, hi: 0x89},
3888 {value: 0x1308, lo: 0x8a, hi: 0x8c},
3889 {value: 0x0018, lo: 0x8d, hi: 0x8d},
3890 {value: 0x0040, lo: 0x8e, hi: 0x8f},
3891 {value: 0x0008, lo: 0x90, hi: 0x9a},
3892 {value: 0x0018, lo: 0x9b, hi: 0x9b},
3893 {value: 0x0008, lo: 0x9c, hi: 0x9c},
3894 {value: 0x0018, lo: 0x9d, hi: 0x9f},
3895 {value: 0x0040, lo: 0xa0, hi: 0xa0},
3896 {value: 0x0018, lo: 0xa1, hi: 0xb4},
3897 {value: 0x0040, lo: 0xb5, hi: 0xbf},
3898 // Block 0xb2, offset 0x561
3899 {value: 0x0000, lo: 0x0c},
3900 {value: 0x0008, lo: 0x80, hi: 0x91},
3901 {value: 0x0040, lo: 0x92, hi: 0x92},
3902 {value: 0x0008, lo: 0x93, hi: 0xab},
3903 {value: 0x1008, lo: 0xac, hi: 0xae},
3904 {value: 0x1308, lo: 0xaf, hi: 0xb1},
3905 {value: 0x1008, lo: 0xb2, hi: 0xb3},
3906 {value: 0x1308, lo: 0xb4, hi: 0xb4},
3907 {value: 0x1808, lo: 0xb5, hi: 0xb5},
3908 {value: 0x1308, lo: 0xb6, hi: 0xb7},
3909 {value: 0x0018, lo: 0xb8, hi: 0xbd},
3910 {value: 0x1308, lo: 0xbe, hi: 0xbe},
3911 {value: 0x0040, lo: 0xbf, hi: 0xbf},
3912 // Block 0xb3, offset 0x56e
3913 {value: 0x0000, lo: 0x0c},
3914 {value: 0x0008, lo: 0x80, hi: 0x86},
3915 {value: 0x0040, lo: 0x87, hi: 0x87},
3916 {value: 0x0008, lo: 0x88, hi: 0x88},
3917 {value: 0x0040, lo: 0x89, hi: 0x89},
3918 {value: 0x0008, lo: 0x8a, hi: 0x8d},
3919 {value: 0x0040, lo: 0x8e, hi: 0x8e},
3920 {value: 0x0008, lo: 0x8f, hi: 0x9d},
3921 {value: 0x0040, lo: 0x9e, hi: 0x9e},
3922 {value: 0x0008, lo: 0x9f, hi: 0xa8},
3923 {value: 0x0018, lo: 0xa9, hi: 0xa9},
3924 {value: 0x0040, lo: 0xaa, hi: 0xaf},
3925 {value: 0x0008, lo: 0xb0, hi: 0xbf},
3926 // Block 0xb4, offset 0x57b
3927 {value: 0x0000, lo: 0x08},
3928 {value: 0x0008, lo: 0x80, hi: 0x9e},
3929 {value: 0x1308, lo: 0x9f, hi: 0x9f},
3930 {value: 0x1008, lo: 0xa0, hi: 0xa2},
3931 {value: 0x1308, lo: 0xa3, hi: 0xa9},
3932 {value: 0x1b08, lo: 0xaa, hi: 0xaa},
3933 {value: 0x0040, lo: 0xab, hi: 0xaf},
3934 {value: 0x0008, lo: 0xb0, hi: 0xb9},
3935 {value: 0x0040, lo: 0xba, hi: 0xbf},
3936 // Block 0xb5, offset 0x584
3937 {value: 0x0000, lo: 0x03},
3938 {value: 0x0008, lo: 0x80, hi: 0xb4},
3939 {value: 0x1008, lo: 0xb5, hi: 0xb7},
3940 {value: 0x1308, lo: 0xb8, hi: 0xbf},
3941 // Block 0xb6, offset 0x588
3942 {value: 0x0000, lo: 0x0d},
3943 {value: 0x1008, lo: 0x80, hi: 0x81},
3944 {value: 0x1b08, lo: 0x82, hi: 0x82},
3945 {value: 0x1308, lo: 0x83, hi: 0x84},
3946 {value: 0x1008, lo: 0x85, hi: 0x85},
3947 {value: 0x1308, lo: 0x86, hi: 0x86},
3948 {value: 0x0008, lo: 0x87, hi: 0x8a},
3949 {value: 0x0018, lo: 0x8b, hi: 0x8f},
3950 {value: 0x0008, lo: 0x90, hi: 0x99},
3951 {value: 0x0040, lo: 0x9a, hi: 0x9a},
3952 {value: 0x0018, lo: 0x9b, hi: 0x9b},
3953 {value: 0x0040, lo: 0x9c, hi: 0x9c},
3954 {value: 0x0018, lo: 0x9d, hi: 0x9d},
3955 {value: 0x0040, lo: 0x9e, hi: 0xbf},
3956 // Block 0xb7, offset 0x596
3957 {value: 0x0000, lo: 0x07},
3958 {value: 0x0008, lo: 0x80, hi: 0xaf},
3959 {value: 0x1008, lo: 0xb0, hi: 0xb2},
3960 {value: 0x1308, lo: 0xb3, hi: 0xb8},
3961 {value: 0x1008, lo: 0xb9, hi: 0xb9},
3962 {value: 0x1308, lo: 0xba, hi: 0xba},
3963 {value: 0x1008, lo: 0xbb, hi: 0xbe},
3964 {value: 0x1308, lo: 0xbf, hi: 0xbf},
3965 // Block 0xb8, offset 0x59e
3966 {value: 0x0000, lo: 0x0a},
3967 {value: 0x1308, lo: 0x80, hi: 0x80},
3968 {value: 0x1008, lo: 0x81, hi: 0x81},
3969 {value: 0x1b08, lo: 0x82, hi: 0x82},
3970 {value: 0x1308, lo: 0x83, hi: 0x83},
3971 {value: 0x0008, lo: 0x84, hi: 0x85},
3972 {value: 0x0018, lo: 0x86, hi: 0x86},
3973 {value: 0x0008, lo: 0x87, hi: 0x87},
3974 {value: 0x0040, lo: 0x88, hi: 0x8f},
3975 {value: 0x0008, lo: 0x90, hi: 0x99},
3976 {value: 0x0040, lo: 0x9a, hi: 0xbf},
3977 // Block 0xb9, offset 0x5a9
3978 {value: 0x0000, lo: 0x08},
3979 {value: 0x0008, lo: 0x80, hi: 0xae},
3980 {value: 0x1008, lo: 0xaf, hi: 0xb1},
3981 {value: 0x1308, lo: 0xb2, hi: 0xb5},
3982 {value: 0x0040, lo: 0xb6, hi: 0xb7},
3983 {value: 0x1008, lo: 0xb8, hi: 0xbb},
3984 {value: 0x1308, lo: 0xbc, hi: 0xbd},
3985 {value: 0x1008, lo: 0xbe, hi: 0xbe},
3986 {value: 0x1b08, lo: 0xbf, hi: 0xbf},
3987 // Block 0xba, offset 0x5b2
3988 {value: 0x0000, lo: 0x05},
3989 {value: 0x1308, lo: 0x80, hi: 0x80},
3990 {value: 0x0018, lo: 0x81, hi: 0x97},
3991 {value: 0x0008, lo: 0x98, hi: 0x9b},
3992 {value: 0x1308, lo: 0x9c, hi: 0x9d},
3993 {value: 0x0040, lo: 0x9e, hi: 0xbf},
3994 // Block 0xbb, offset 0x5b8
3995 {value: 0x0000, lo: 0x07},
3996 {value: 0x0008, lo: 0x80, hi: 0xaf},
3997 {value: 0x1008, lo: 0xb0, hi: 0xb2},
3998 {value: 0x1308, lo: 0xb3, hi: 0xba},
3999 {value: 0x1008, lo: 0xbb, hi: 0xbc},
4000 {value: 0x1308, lo: 0xbd, hi: 0xbd},
4001 {value: 0x1008, lo: 0xbe, hi: 0xbe},
4002 {value: 0x1b08, lo: 0xbf, hi: 0xbf},
4003 // Block 0xbc, offset 0x5c0
4004 {value: 0x0000, lo: 0x08},
4005 {value: 0x1308, lo: 0x80, hi: 0x80},
4006 {value: 0x0018, lo: 0x81, hi: 0x83},
4007 {value: 0x0008, lo: 0x84, hi: 0x84},
4008 {value: 0x0040, lo: 0x85, hi: 0x8f},
4009 {value: 0x0008, lo: 0x90, hi: 0x99},
4010 {value: 0x0040, lo: 0x9a, hi: 0x9f},
4011 {value: 0x0018, lo: 0xa0, hi: 0xac},
4012 {value: 0x0040, lo: 0xad, hi: 0xbf},
4013 // Block 0xbd, offset 0x5c9
4014 {value: 0x0000, lo: 0x09},
4015 {value: 0x0008, lo: 0x80, hi: 0xaa},
4016 {value: 0x1308, lo: 0xab, hi: 0xab},
4017 {value: 0x1008, lo: 0xac, hi: 0xac},
4018 {value: 0x1308, lo: 0xad, hi: 0xad},
4019 {value: 0x1008, lo: 0xae, hi: 0xaf},
4020 {value: 0x1308, lo: 0xb0, hi: 0xb5},
4021 {value: 0x1808, lo: 0xb6, hi: 0xb6},
4022 {value: 0x1308, lo: 0xb7, hi: 0xb7},
4023 {value: 0x0040, lo: 0xb8, hi: 0xbf},
4024 // Block 0xbe, offset 0x5d3
4025 {value: 0x0000, lo: 0x02},
4026 {value: 0x0008, lo: 0x80, hi: 0x89},
4027 {value: 0x0040, lo: 0x8a, hi: 0xbf},
4028 // Block 0xbf, offset 0x5d6
4029 {value: 0x0000, lo: 0x0b},
4030 {value: 0x0008, lo: 0x80, hi: 0x99},
4031 {value: 0x0040, lo: 0x9a, hi: 0x9c},
4032 {value: 0x1308, lo: 0x9d, hi: 0x9f},
4033 {value: 0x1008, lo: 0xa0, hi: 0xa1},
4034 {value: 0x1308, lo: 0xa2, hi: 0xa5},
4035 {value: 0x1008, lo: 0xa6, hi: 0xa6},
4036 {value: 0x1308, lo: 0xa7, hi: 0xaa},
4037 {value: 0x1b08, lo: 0xab, hi: 0xab},
4038 {value: 0x0040, lo: 0xac, hi: 0xaf},
4039 {value: 0x0008, lo: 0xb0, hi: 0xb9},
4040 {value: 0x0018, lo: 0xba, hi: 0xbf},
4041 // Block 0xc0, offset 0x5e2
4042 {value: 0x0000, lo: 0x02},
4043 {value: 0x0040, lo: 0x80, hi: 0x9f},
4044 {value: 0x049d, lo: 0xa0, hi: 0xbf},
4045 // Block 0xc1, offset 0x5e5
4046 {value: 0x0000, lo: 0x04},
4047 {value: 0x0008, lo: 0x80, hi: 0xa9},
4048 {value: 0x0018, lo: 0xaa, hi: 0xb2},
4049 {value: 0x0040, lo: 0xb3, hi: 0xbe},
4050 {value: 0x0008, lo: 0xbf, hi: 0xbf},
4051 // Block 0xc2, offset 0x5ea
4052 {value: 0x0000, lo: 0x02},
4053 {value: 0x0008, lo: 0x80, hi: 0xb8},
4054 {value: 0x0040, lo: 0xb9, hi: 0xbf},
4055 // Block 0xc3, offset 0x5ed
4056 {value: 0x0000, lo: 0x09},
4057 {value: 0x0008, lo: 0x80, hi: 0x88},
4058 {value: 0x0040, lo: 0x89, hi: 0x89},
4059 {value: 0x0008, lo: 0x8a, hi: 0xae},
4060 {value: 0x1008, lo: 0xaf, hi: 0xaf},
4061 {value: 0x1308, lo: 0xb0, hi: 0xb6},
4062 {value: 0x0040, lo: 0xb7, hi: 0xb7},
4063 {value: 0x1308, lo: 0xb8, hi: 0xbd},
4064 {value: 0x1008, lo: 0xbe, hi: 0xbe},
4065 {value: 0x1b08, lo: 0xbf, hi: 0xbf},
4066 // Block 0xc4, offset 0x5f7
4067 {value: 0x0000, lo: 0x08},
4068 {value: 0x0008, lo: 0x80, hi: 0x80},
4069 {value: 0x0018, lo: 0x81, hi: 0x85},
4070 {value: 0x0040, lo: 0x86, hi: 0x8f},
4071 {value: 0x0008, lo: 0x90, hi: 0x99},
4072 {value: 0x0018, lo: 0x9a, hi: 0xac},
4073 {value: 0x0040, lo: 0xad, hi: 0xaf},
4074 {value: 0x0018, lo: 0xb0, hi: 0xb1},
4075 {value: 0x0008, lo: 0xb2, hi: 0xbf},
4076 // Block 0xc5, offset 0x600
4077 {value: 0x0000, lo: 0x0b},
4078 {value: 0x0008, lo: 0x80, hi: 0x8f},
4079 {value: 0x0040, lo: 0x90, hi: 0x91},
4080 {value: 0x1308, lo: 0x92, hi: 0xa7},
4081 {value: 0x0040, lo: 0xa8, hi: 0xa8},
4082 {value: 0x1008, lo: 0xa9, hi: 0xa9},
4083 {value: 0x1308, lo: 0xaa, hi: 0xb0},
4084 {value: 0x1008, lo: 0xb1, hi: 0xb1},
4085 {value: 0x1308, lo: 0xb2, hi: 0xb3},
4086 {value: 0x1008, lo: 0xb4, hi: 0xb4},
4087 {value: 0x1308, lo: 0xb5, hi: 0xb6},
4088 {value: 0x0040, lo: 0xb7, hi: 0xbf},
4089 // Block 0xc6, offset 0x60c
4090 {value: 0x0000, lo: 0x02},
4091 {value: 0x0008, lo: 0x80, hi: 0x99},
4092 {value: 0x0040, lo: 0x9a, hi: 0xbf},
4093 // Block 0xc7, offset 0x60f
4094 {value: 0x0000, lo: 0x04},
4095 {value: 0x0018, lo: 0x80, hi: 0xae},
4096 {value: 0x0040, lo: 0xaf, hi: 0xaf},
4097 {value: 0x0018, lo: 0xb0, hi: 0xb4},
4098 {value: 0x0040, lo: 0xb5, hi: 0xbf},
4099 // Block 0xc8, offset 0x614
4100 {value: 0x0000, lo: 0x02},
4101 {value: 0x0008, lo: 0x80, hi: 0x83},
4102 {value: 0x0040, lo: 0x84, hi: 0xbf},
4103 // Block 0xc9, offset 0x617
4104 {value: 0x0000, lo: 0x02},
4105 {value: 0x0008, lo: 0x80, hi: 0xae},
4106 {value: 0x0040, lo: 0xaf, hi: 0xbf},
4107 // Block 0xca, offset 0x61a
4108 {value: 0x0000, lo: 0x02},
4109 {value: 0x0008, lo: 0x80, hi: 0x86},
4110 {value: 0x0040, lo: 0x87, hi: 0xbf},
4111 // Block 0xcb, offset 0x61d
4112 {value: 0x0000, lo: 0x06},
4113 {value: 0x0008, lo: 0x80, hi: 0x9e},
4114 {value: 0x0040, lo: 0x9f, hi: 0x9f},
4115 {value: 0x0008, lo: 0xa0, hi: 0xa9},
4116 {value: 0x0040, lo: 0xaa, hi: 0xad},
4117 {value: 0x0018, lo: 0xae, hi: 0xaf},
4118 {value: 0x0040, lo: 0xb0, hi: 0xbf},
4119 // Block 0xcc, offset 0x624
4120 {value: 0x0000, lo: 0x06},
4121 {value: 0x0040, lo: 0x80, hi: 0x8f},
4122 {value: 0x0008, lo: 0x90, hi: 0xad},
4123 {value: 0x0040, lo: 0xae, hi: 0xaf},
4124 {value: 0x1308, lo: 0xb0, hi: 0xb4},
4125 {value: 0x0018, lo: 0xb5, hi: 0xb5},
4126 {value: 0x0040, lo: 0xb6, hi: 0xbf},
4127 // Block 0xcd, offset 0x62b
4128 {value: 0x0000, lo: 0x03},
4129 {value: 0x0008, lo: 0x80, hi: 0xaf},
4130 {value: 0x1308, lo: 0xb0, hi: 0xb6},
4131 {value: 0x0018, lo: 0xb7, hi: 0xbf},
4132 // Block 0xce, offset 0x62f
4133 {value: 0x0000, lo: 0x0a},
4134 {value: 0x0008, lo: 0x80, hi: 0x83},
4135 {value: 0x0018, lo: 0x84, hi: 0x85},
4136 {value: 0x0040, lo: 0x86, hi: 0x8f},
4137 {value: 0x0008, lo: 0x90, hi: 0x99},
4138 {value: 0x0040, lo: 0x9a, hi: 0x9a},
4139 {value: 0x0018, lo: 0x9b, hi: 0xa1},
4140 {value: 0x0040, lo: 0xa2, hi: 0xa2},
4141 {value: 0x0008, lo: 0xa3, hi: 0xb7},
4142 {value: 0x0040, lo: 0xb8, hi: 0xbc},
4143 {value: 0x0008, lo: 0xbd, hi: 0xbf},
4144 // Block 0xcf, offset 0x63a
4145 {value: 0x0000, lo: 0x02},
4146 {value: 0x0008, lo: 0x80, hi: 0x8f},
4147 {value: 0x0040, lo: 0x90, hi: 0xbf},
4148 // Block 0xd0, offset 0x63d
4149 {value: 0x0000, lo: 0x05},
4150 {value: 0x0008, lo: 0x80, hi: 0x84},
4151 {value: 0x0040, lo: 0x85, hi: 0x8f},
4152 {value: 0x0008, lo: 0x90, hi: 0x90},
4153 {value: 0x1008, lo: 0x91, hi: 0xbe},
4154 {value: 0x0040, lo: 0xbf, hi: 0xbf},
4155 // Block 0xd1, offset 0x643
4156 {value: 0x0000, lo: 0x04},
4157 {value: 0x0040, lo: 0x80, hi: 0x8e},
4158 {value: 0x1308, lo: 0x8f, hi: 0x92},
4159 {value: 0x0008, lo: 0x93, hi: 0x9f},
4160 {value: 0x0040, lo: 0xa0, hi: 0xbf},
4161 // Block 0xd2, offset 0x648
4162 {value: 0x0000, lo: 0x03},
4163 {value: 0x0040, lo: 0x80, hi: 0x9f},
4164 {value: 0x0008, lo: 0xa0, hi: 0xa0},
4165 {value: 0x0040, lo: 0xa1, hi: 0xbf},
4166 // Block 0xd3, offset 0x64c
4167 {value: 0x0000, lo: 0x02},
4168 {value: 0x0008, lo: 0x80, hi: 0xac},
4169 {value: 0x0040, lo: 0xad, hi: 0xbf},
4170 // Block 0xd4, offset 0x64f
4171 {value: 0x0000, lo: 0x02},
4172 {value: 0x0008, lo: 0x80, hi: 0xb2},
4173 {value: 0x0040, lo: 0xb3, hi: 0xbf},
4174 // Block 0xd5, offset 0x652
4175 {value: 0x0000, lo: 0x02},
4176 {value: 0x0008, lo: 0x80, hi: 0x81},
4177 {value: 0x0040, lo: 0x82, hi: 0xbf},
4178 // Block 0xd6, offset 0x655
4179 {value: 0x0000, lo: 0x04},
4180 {value: 0x0008, lo: 0x80, hi: 0xaa},
4181 {value: 0x0040, lo: 0xab, hi: 0xaf},
4182 {value: 0x0008, lo: 0xb0, hi: 0xbc},
4183 {value: 0x0040, lo: 0xbd, hi: 0xbf},
4184 // Block 0xd7, offset 0x65a
4185 {value: 0x0000, lo: 0x09},
4186 {value: 0x0008, lo: 0x80, hi: 0x88},
4187 {value: 0x0040, lo: 0x89, hi: 0x8f},
4188 {value: 0x0008, lo: 0x90, hi: 0x99},
4189 {value: 0x0040, lo: 0x9a, hi: 0x9b},
4190 {value: 0x0018, lo: 0x9c, hi: 0x9c},
4191 {value: 0x1308, lo: 0x9d, hi: 0x9e},
4192 {value: 0x0018, lo: 0x9f, hi: 0x9f},
4193 {value: 0x03c0, lo: 0xa0, hi: 0xa3},
4194 {value: 0x0040, lo: 0xa4, hi: 0xbf},
4195 // Block 0xd8, offset 0x664
4196 {value: 0x0000, lo: 0x02},
4197 {value: 0x0018, lo: 0x80, hi: 0xb5},
4198 {value: 0x0040, lo: 0xb6, hi: 0xbf},
4199 // Block 0xd9, offset 0x667
4200 {value: 0x0000, lo: 0x03},
4201 {value: 0x0018, lo: 0x80, hi: 0xa6},
4202 {value: 0x0040, lo: 0xa7, hi: 0xa8},
4203 {value: 0x0018, lo: 0xa9, hi: 0xbf},
4204 // Block 0xda, offset 0x66b
4205 {value: 0x0000, lo: 0x0e},
4206 {value: 0x0018, lo: 0x80, hi: 0x9d},
4207 {value: 0xb5b9, lo: 0x9e, hi: 0x9e},
4208 {value: 0xb601, lo: 0x9f, hi: 0x9f},
4209 {value: 0xb649, lo: 0xa0, hi: 0xa0},
4210 {value: 0xb6b1, lo: 0xa1, hi: 0xa1},
4211 {value: 0xb719, lo: 0xa2, hi: 0xa2},
4212 {value: 0xb781, lo: 0xa3, hi: 0xa3},
4213 {value: 0xb7e9, lo: 0xa4, hi: 0xa4},
4214 {value: 0x1018, lo: 0xa5, hi: 0xa6},
4215 {value: 0x1318, lo: 0xa7, hi: 0xa9},
4216 {value: 0x0018, lo: 0xaa, hi: 0xac},
4217 {value: 0x1018, lo: 0xad, hi: 0xb2},
4218 {value: 0x0340, lo: 0xb3, hi: 0xba},
4219 {value: 0x1318, lo: 0xbb, hi: 0xbf},
4220 // Block 0xdb, offset 0x67a
4221 {value: 0x0000, lo: 0x0b},
4222 {value: 0x1318, lo: 0x80, hi: 0x82},
4223 {value: 0x0018, lo: 0x83, hi: 0x84},
4224 {value: 0x1318, lo: 0x85, hi: 0x8b},
4225 {value: 0x0018, lo: 0x8c, hi: 0xa9},
4226 {value: 0x1318, lo: 0xaa, hi: 0xad},
4227 {value: 0x0018, lo: 0xae, hi: 0xba},
4228 {value: 0xb851, lo: 0xbb, hi: 0xbb},
4229 {value: 0xb899, lo: 0xbc, hi: 0xbc},
4230 {value: 0xb8e1, lo: 0xbd, hi: 0xbd},
4231 {value: 0xb949, lo: 0xbe, hi: 0xbe},
4232 {value: 0xb9b1, lo: 0xbf, hi: 0xbf},
4233 // Block 0xdc, offset 0x686
4234 {value: 0x0000, lo: 0x03},
4235 {value: 0xba19, lo: 0x80, hi: 0x80},
4236 {value: 0x0018, lo: 0x81, hi: 0xa8},
4237 {value: 0x0040, lo: 0xa9, hi: 0xbf},
4238 // Block 0xdd, offset 0x68a
4239 {value: 0x0000, lo: 0x04},
4240 {value: 0x0018, lo: 0x80, hi: 0x81},
4241 {value: 0x1318, lo: 0x82, hi: 0x84},
4242 {value: 0x0018, lo: 0x85, hi: 0x85},
4243 {value: 0x0040, lo: 0x86, hi: 0xbf},
4244 // Block 0xde, offset 0x68f
4245 {value: 0x0000, lo: 0x04},
4246 {value: 0x0018, lo: 0x80, hi: 0x96},
4247 {value: 0x0040, lo: 0x97, hi: 0x9f},
4248 {value: 0x0018, lo: 0xa0, hi: 0xb1},
4249 {value: 0x0040, lo: 0xb2, hi: 0xbf},
4250 // Block 0xdf, offset 0x694
4251 {value: 0x0000, lo: 0x03},
4252 {value: 0x1308, lo: 0x80, hi: 0xb6},
4253 {value: 0x0018, lo: 0xb7, hi: 0xba},
4254 {value: 0x1308, lo: 0xbb, hi: 0xbf},
4255 // Block 0xe0, offset 0x698
4256 {value: 0x0000, lo: 0x04},
4257 {value: 0x1308, lo: 0x80, hi: 0xac},
4258 {value: 0x0018, lo: 0xad, hi: 0xb4},
4259 {value: 0x1308, lo: 0xb5, hi: 0xb5},
4260 {value: 0x0018, lo: 0xb6, hi: 0xbf},
4261 // Block 0xe1, offset 0x69d
4262 {value: 0x0000, lo: 0x08},
4263 {value: 0x0018, lo: 0x80, hi: 0x83},
4264 {value: 0x1308, lo: 0x84, hi: 0x84},
4265 {value: 0x0018, lo: 0x85, hi: 0x8b},
4266 {value: 0x0040, lo: 0x8c, hi: 0x9a},
4267 {value: 0x1308, lo: 0x9b, hi: 0x9f},
4268 {value: 0x0040, lo: 0xa0, hi: 0xa0},
4269 {value: 0x1308, lo: 0xa1, hi: 0xaf},
4270 {value: 0x0040, lo: 0xb0, hi: 0xbf},
4271 // Block 0xe2, offset 0x6a6
4272 {value: 0x0000, lo: 0x0a},
4273 {value: 0x1308, lo: 0x80, hi: 0x86},
4274 {value: 0x0040, lo: 0x87, hi: 0x87},
4275 {value: 0x1308, lo: 0x88, hi: 0x98},
4276 {value: 0x0040, lo: 0x99, hi: 0x9a},
4277 {value: 0x1308, lo: 0x9b, hi: 0xa1},
4278 {value: 0x0040, lo: 0xa2, hi: 0xa2},
4279 {value: 0x1308, lo: 0xa3, hi: 0xa4},
4280 {value: 0x0040, lo: 0xa5, hi: 0xa5},
4281 {value: 0x1308, lo: 0xa6, hi: 0xaa},
4282 {value: 0x0040, lo: 0xab, hi: 0xbf},
4283 // Block 0xe3, offset 0x6b1
4284 {value: 0x0000, lo: 0x05},
4285 {value: 0x0008, lo: 0x80, hi: 0x84},
4286 {value: 0x0040, lo: 0x85, hi: 0x86},
4287 {value: 0x0018, lo: 0x87, hi: 0x8f},
4288 {value: 0x1308, lo: 0x90, hi: 0x96},
4289 {value: 0x0040, lo: 0x97, hi: 0xbf},
4290 // Block 0xe4, offset 0x6b7
4291 {value: 0x0000, lo: 0x07},
4292 {value: 0x0208, lo: 0x80, hi: 0x83},
4293 {value: 0x1308, lo: 0x84, hi: 0x8a},
4294 {value: 0x0040, lo: 0x8b, hi: 0x8f},
4295 {value: 0x0008, lo: 0x90, hi: 0x99},
4296 {value: 0x0040, lo: 0x9a, hi: 0x9d},
4297 {value: 0x0018, lo: 0x9e, hi: 0x9f},
4298 {value: 0x0040, lo: 0xa0, hi: 0xbf},
4299 // Block 0xe5, offset 0x6bf
4300 {value: 0x0000, lo: 0x03},
4301 {value: 0x0040, lo: 0x80, hi: 0xaf},
4302 {value: 0x0018, lo: 0xb0, hi: 0xb1},
4303 {value: 0x0040, lo: 0xb2, hi: 0xbf},
4304 // Block 0xe6, offset 0x6c3
4305 {value: 0x0000, lo: 0x03},
4306 {value: 0x0018, lo: 0x80, hi: 0xab},
4307 {value: 0x0040, lo: 0xac, hi: 0xaf},
4308 {value: 0x0018, lo: 0xb0, hi: 0xbf},
4309 // Block 0xe7, offset 0x6c7
4310 {value: 0x0000, lo: 0x05},
4311 {value: 0x0018, lo: 0x80, hi: 0x93},
4312 {value: 0x0040, lo: 0x94, hi: 0x9f},
4313 {value: 0x0018, lo: 0xa0, hi: 0xae},
4314 {value: 0x0040, lo: 0xaf, hi: 0xb0},
4315 {value: 0x0018, lo: 0xb1, hi: 0xbf},
4316 // Block 0xe8, offset 0x6cd
4317 {value: 0x0000, lo: 0x05},
4318 {value: 0x0040, lo: 0x80, hi: 0x80},
4319 {value: 0x0018, lo: 0x81, hi: 0x8f},
4320 {value: 0x0040, lo: 0x90, hi: 0x90},
4321 {value: 0x0018, lo: 0x91, hi: 0xb5},
4322 {value: 0x0040, lo: 0xb6, hi: 0xbf},
4323 // Block 0xe9, offset 0x6d3
4324 {value: 0x0000, lo: 0x04},
4325 {value: 0x0018, lo: 0x80, hi: 0x8f},
4326 {value: 0xc1c1, lo: 0x90, hi: 0x90},
4327 {value: 0x0018, lo: 0x91, hi: 0xac},
4328 {value: 0x0040, lo: 0xad, hi: 0xbf},
4329 // Block 0xea, offset 0x6d8
4330 {value: 0x0000, lo: 0x02},
4331 {value: 0x0040, lo: 0x80, hi: 0xa5},
4332 {value: 0x0018, lo: 0xa6, hi: 0xbf},
4333 // Block 0xeb, offset 0x6db
4334 {value: 0x0000, lo: 0x0d},
4335 {value: 0xc7e9, lo: 0x80, hi: 0x80},
4336 {value: 0xc839, lo: 0x81, hi: 0x81},
4337 {value: 0xc889, lo: 0x82, hi: 0x82},
4338 {value: 0xc8d9, lo: 0x83, hi: 0x83},
4339 {value: 0xc929, lo: 0x84, hi: 0x84},
4340 {value: 0xc979, lo: 0x85, hi: 0x85},
4341 {value: 0xc9c9, lo: 0x86, hi: 0x86},
4342 {value: 0xca19, lo: 0x87, hi: 0x87},
4343 {value: 0xca69, lo: 0x88, hi: 0x88},
4344 {value: 0x0040, lo: 0x89, hi: 0x8f},
4345 {value: 0xcab9, lo: 0x90, hi: 0x90},
4346 {value: 0xcad9, lo: 0x91, hi: 0x91},
4347 {value: 0x0040, lo: 0x92, hi: 0xbf},
4348 // Block 0xec, offset 0x6e9
4349 {value: 0x0000, lo: 0x06},
4350 {value: 0x0018, lo: 0x80, hi: 0x92},
4351 {value: 0x0040, lo: 0x93, hi: 0x9f},
4352 {value: 0x0018, lo: 0xa0, hi: 0xac},
4353 {value: 0x0040, lo: 0xad, hi: 0xaf},
4354 {value: 0x0018, lo: 0xb0, hi: 0xb6},
4355 {value: 0x0040, lo: 0xb7, hi: 0xbf},
4356 // Block 0xed, offset 0x6f0
4357 {value: 0x0000, lo: 0x02},
4358 {value: 0x0018, lo: 0x80, hi: 0xb3},
4359 {value: 0x0040, lo: 0xb4, hi: 0xbf},
4360 // Block 0xee, offset 0x6f3
4361 {value: 0x0000, lo: 0x02},
4362 {value: 0x0018, lo: 0x80, hi: 0x94},
4363 {value: 0x0040, lo: 0x95, hi: 0xbf},
4364 // Block 0xef, offset 0x6f6
4365 {value: 0x0000, lo: 0x03},
4366 {value: 0x0018, lo: 0x80, hi: 0x8b},
4367 {value: 0x0040, lo: 0x8c, hi: 0x8f},
4368 {value: 0x0018, lo: 0x90, hi: 0xbf},
4369 // Block 0xf0, offset 0x6fa
4370 {value: 0x0000, lo: 0x05},
4371 {value: 0x0018, lo: 0x80, hi: 0x87},
4372 {value: 0x0040, lo: 0x88, hi: 0x8f},
4373 {value: 0x0018, lo: 0x90, hi: 0x99},
4374 {value: 0x0040, lo: 0x9a, hi: 0x9f},
4375 {value: 0x0018, lo: 0xa0, hi: 0xbf},
4376 // Block 0xf1, offset 0x700
4377 {value: 0x0000, lo: 0x04},
4378 {value: 0x0018, lo: 0x80, hi: 0x87},
4379 {value: 0x0040, lo: 0x88, hi: 0x8f},
4380 {value: 0x0018, lo: 0x90, hi: 0xad},
4381 {value: 0x0040, lo: 0xae, hi: 0xbf},
4382 // Block 0xf2, offset 0x705
4383 {value: 0x0000, lo: 0x09},
4384 {value: 0x0040, lo: 0x80, hi: 0x8f},
4385 {value: 0x0018, lo: 0x90, hi: 0x9e},
4386 {value: 0x0040, lo: 0x9f, hi: 0x9f},
4387 {value: 0x0018, lo: 0xa0, hi: 0xa7},
4388 {value: 0x0040, lo: 0xa8, hi: 0xaf},
4389 {value: 0x0018, lo: 0xb0, hi: 0xb0},
4390 {value: 0x0040, lo: 0xb1, hi: 0xb2},
4391 {value: 0x0018, lo: 0xb3, hi: 0xbe},
4392 {value: 0x0040, lo: 0xbf, hi: 0xbf},
4393 // Block 0xf3, offset 0x70f
4394 {value: 0x0000, lo: 0x04},
4395 {value: 0x0018, lo: 0x80, hi: 0x8b},
4396 {value: 0x0040, lo: 0x8c, hi: 0x8f},
4397 {value: 0x0018, lo: 0x90, hi: 0x9e},
4398 {value: 0x0040, lo: 0x9f, hi: 0xbf},
4399 // Block 0xf4, offset 0x714
4400 {value: 0x0000, lo: 0x02},
4401 {value: 0x0018, lo: 0x80, hi: 0x91},
4402 {value: 0x0040, lo: 0x92, hi: 0xbf},
4403 // Block 0xf5, offset 0x717
4404 {value: 0x0000, lo: 0x02},
4405 {value: 0x0018, lo: 0x80, hi: 0x80},
4406 {value: 0x0040, lo: 0x81, hi: 0xbf},
4407 // Block 0xf6, offset 0x71a
4408 {value: 0x0000, lo: 0x02},
4409 {value: 0x0008, lo: 0x80, hi: 0x96},
4410 {value: 0x0040, lo: 0x97, hi: 0xbf},
4411 // Block 0xf7, offset 0x71d
4412 {value: 0x0000, lo: 0x02},
4413 {value: 0x0008, lo: 0x80, hi: 0xb4},
4414 {value: 0x0040, lo: 0xb5, hi: 0xbf},
4415 // Block 0xf8, offset 0x720
4416 {value: 0x0000, lo: 0x03},
4417 {value: 0x0008, lo: 0x80, hi: 0x9d},
4418 {value: 0x0040, lo: 0x9e, hi: 0x9f},
4419 {value: 0x0008, lo: 0xa0, hi: 0xbf},
4420 // Block 0xf9, offset 0x724
4421 {value: 0x0000, lo: 0x02},
4422 {value: 0x0008, lo: 0x80, hi: 0xa1},
4423 {value: 0x0040, lo: 0xa2, hi: 0xbf},
4424 // Block 0xfa, offset 0x727
4425 {value: 0x0020, lo: 0x0f},
4426 {value: 0xdeb9, lo: 0x80, hi: 0x89},
4427 {value: 0x8dfd, lo: 0x8a, hi: 0x8a},
4428 {value: 0xdff9, lo: 0x8b, hi: 0x9c},
4429 {value: 0x8e1d, lo: 0x9d, hi: 0x9d},
4430 {value: 0xe239, lo: 0x9e, hi: 0xa2},
4431 {value: 0x8e3d, lo: 0xa3, hi: 0xa3},
4432 {value: 0xe2d9, lo: 0xa4, hi: 0xab},
4433 {value: 0x7ed5, lo: 0xac, hi: 0xac},
4434 {value: 0xe3d9, lo: 0xad, hi: 0xaf},
4435 {value: 0x8e5d, lo: 0xb0, hi: 0xb0},
4436 {value: 0xe439, lo: 0xb1, hi: 0xb6},
4437 {value: 0x8e7d, lo: 0xb7, hi: 0xb9},
4438 {value: 0xe4f9, lo: 0xba, hi: 0xba},
4439 {value: 0x8edd, lo: 0xbb, hi: 0xbb},
4440 {value: 0xe519, lo: 0xbc, hi: 0xbf},
4441 // Block 0xfb, offset 0x737
4442 {value: 0x0020, lo: 0x10},
4443 {value: 0x937d, lo: 0x80, hi: 0x80},
4444 {value: 0xf099, lo: 0x81, hi: 0x86},
4445 {value: 0x939d, lo: 0x87, hi: 0x8a},
4446 {value: 0xd9f9, lo: 0x8b, hi: 0x8b},
4447 {value: 0xf159, lo: 0x8c, hi: 0x96},
4448 {value: 0x941d, lo: 0x97, hi: 0x97},
4449 {value: 0xf2b9, lo: 0x98, hi: 0xa3},
4450 {value: 0x943d, lo: 0xa4, hi: 0xa6},
4451 {value: 0xf439, lo: 0xa7, hi: 0xaa},
4452 {value: 0x949d, lo: 0xab, hi: 0xab},
4453 {value: 0xf4b9, lo: 0xac, hi: 0xac},
4454 {value: 0x94bd, lo: 0xad, hi: 0xad},
4455 {value: 0xf4d9, lo: 0xae, hi: 0xaf},
4456 {value: 0x94dd, lo: 0xb0, hi: 0xb1},
4457 {value: 0xf519, lo: 0xb2, hi: 0xbe},
4458 {value: 0x0040, lo: 0xbf, hi: 0xbf},
4459 // Block 0xfc, offset 0x748
4460 {value: 0x0000, lo: 0x04},
4461 {value: 0x0040, lo: 0x80, hi: 0x80},
4462 {value: 0x0340, lo: 0x81, hi: 0x81},
4463 {value: 0x0040, lo: 0x82, hi: 0x9f},
4464 {value: 0x0340, lo: 0xa0, hi: 0xbf},
4465 // Block 0xfd, offset 0x74d
4466 {value: 0x0000, lo: 0x01},
4467 {value: 0x0340, lo: 0x80, hi: 0xbf},
4468 // Block 0xfe, offset 0x74f
4469 {value: 0x0000, lo: 0x01},
4470 {value: 0x13c0, lo: 0x80, hi: 0xbf},
4471 // Block 0xff, offset 0x751
4472 {value: 0x0000, lo: 0x02},
4473 {value: 0x13c0, lo: 0x80, hi: 0xaf},
4474 {value: 0x0040, lo: 0xb0, hi: 0xbf},
4475}
4476
4477// Total table size 41559 bytes (40KiB); checksum: F4A1FA4E
diff --git a/vendor/golang.org/x/net/idna/trie.go b/vendor/golang.org/x/net/idna/trie.go
new file mode 100644
index 0000000..c4ef847
--- /dev/null
+++ b/vendor/golang.org/x/net/idna/trie.go
@@ -0,0 +1,72 @@
1// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
2
3// Copyright 2016 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7package idna
8
9// appendMapping appends the mapping for the respective rune. isMapped must be
10// true. A mapping is a categorization of a rune as defined in UTS #46.
11func (c info) appendMapping(b []byte, s string) []byte {
12 index := int(c >> indexShift)
13 if c&xorBit == 0 {
14 s := mappings[index:]
15 return append(b, s[1:s[0]+1]...)
16 }
17 b = append(b, s...)
18 if c&inlineXOR == inlineXOR {
19 // TODO: support and handle two-byte inline masks
20 b[len(b)-1] ^= byte(index)
21 } else {
22 for p := len(b) - int(xorData[index]); p < len(b); p++ {
23 index++
24 b[p] ^= xorData[index]
25 }
26 }
27 return b
28}
29
30// Sparse block handling code.
31
32type valueRange struct {
33 value uint16 // header: value:stride
34 lo, hi byte // header: lo:n
35}
36
37type sparseBlocks struct {
38 values []valueRange
39 offset []uint16
40}
41
42var idnaSparse = sparseBlocks{
43 values: idnaSparseValues[:],
44 offset: idnaSparseOffset[:],
45}
46
47// Don't use newIdnaTrie to avoid unconditional linking in of the table.
48var trie = &idnaTrie{}
49
50// lookup determines the type of block n and looks up the value for b.
51// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
52// is a list of ranges with an accompanying value. Given a matching range r,
53// the value for b is by r.value + (b - r.lo) * stride.
54func (t *sparseBlocks) lookup(n uint32, b byte) uint16 {
55 offset := t.offset[n]
56 header := t.values[offset]
57 lo := offset + 1
58 hi := lo + uint16(header.lo)
59 for lo < hi {
60 m := lo + (hi-lo)/2
61 r := t.values[m]
62 if r.lo <= b && b <= r.hi {
63 return r.value + uint16(b-r.lo)*header.value
64 }
65 if b < r.lo {
66 hi = m
67 } else {
68 lo = m + 1
69 }
70 }
71 return 0
72}
diff --git a/vendor/golang.org/x/net/idna/trieval.go b/vendor/golang.org/x/net/idna/trieval.go
new file mode 100644
index 0000000..63cb03b
--- /dev/null
+++ b/vendor/golang.org/x/net/idna/trieval.go
@@ -0,0 +1,114 @@
1// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
2
3package idna
4
5// This file contains definitions for interpreting the trie value of the idna
6// trie generated by "go run gen*.go". It is shared by both the generator
7// program and the resultant package. Sharing is achieved by the generator
8// copying gen_trieval.go to trieval.go and changing what's above this comment.
9
10// info holds information from the IDNA mapping table for a single rune. It is
11// the value returned by a trie lookup. In most cases, all information fits in
12// a 16-bit value. For mappings, this value may contain an index into a slice
13// with the mapped string. Such mappings can consist of the actual mapped value
14// or an XOR pattern to be applied to the bytes of the UTF8 encoding of the
15// input rune. This technique is used by the cases packages and reduces the
16// table size significantly.
17//
18// The per-rune values have the following format:
19//
20// if mapped {
21// if inlinedXOR {
22// 15..13 inline XOR marker
23// 12..11 unused
24// 10..3 inline XOR mask
25// } else {
26// 15..3 index into xor or mapping table
27// }
28// } else {
29// 15..13 unused
30// 12 modifier (including virama)
31// 11 virama modifier
32// 10..8 joining type
33// 7..3 category type
34// }
35// 2 use xor pattern
36// 1..0 mapped category
37//
38// See the definitions below for a more detailed description of the various
39// bits.
40type info uint16
41
42const (
43 catSmallMask = 0x3
44 catBigMask = 0xF8
45 indexShift = 3
46 xorBit = 0x4 // interpret the index as an xor pattern
47 inlineXOR = 0xE000 // These bits are set if the XOR pattern is inlined.
48
49 joinShift = 8
50 joinMask = 0x07
51
52 viramaModifier = 0x0800
53 modifier = 0x1000
54)
55
56// A category corresponds to a category defined in the IDNA mapping table.
57type category uint16
58
59const (
60 unknown category = 0 // not defined currently in unicode.
61 mapped category = 1
62 disallowedSTD3Mapped category = 2
63 deviation category = 3
64)
65
66const (
67 valid category = 0x08
68 validNV8 category = 0x18
69 validXV8 category = 0x28
70 disallowed category = 0x40
71 disallowedSTD3Valid category = 0x80
72 ignored category = 0xC0
73)
74
75// join types and additional rune information
76const (
77 joiningL = (iota + 1)
78 joiningD
79 joiningT
80 joiningR
81
82 //the following types are derived during processing
83 joinZWJ
84 joinZWNJ
85 joinVirama
86 numJoinTypes
87)
88
89func (c info) isMapped() bool {
90 return c&0x3 != 0
91}
92
93func (c info) category() category {
94 small := c & catSmallMask
95 if small != 0 {
96 return category(small)
97 }
98 return category(c & catBigMask)
99}
100
101func (c info) joinType() info {
102 if c.isMapped() {
103 return 0
104 }
105 return (c >> joinShift) & joinMask
106}
107
108func (c info) isModifier() bool {
109 return c&(modifier|catSmallMask) == modifier
110}
111
112func (c info) isViramaModifier() bool {
113 return c&(viramaModifier|catSmallMask) == viramaModifier
114}
diff --git a/vendor/golang.org/x/net/internal/timeseries/timeseries.go b/vendor/golang.org/x/net/internal/timeseries/timeseries.go
new file mode 100644
index 0000000..685f0e7
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/timeseries/timeseries.go
@@ -0,0 +1,525 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package timeseries implements a time series structure for stats collection.
6package timeseries // import "golang.org/x/net/internal/timeseries"
7
8import (
9 "fmt"
10 "log"
11 "time"
12)
13
14const (
15 timeSeriesNumBuckets = 64
16 minuteHourSeriesNumBuckets = 60
17)
18
19var timeSeriesResolutions = []time.Duration{
20 1 * time.Second,
21 10 * time.Second,
22 1 * time.Minute,
23 10 * time.Minute,
24 1 * time.Hour,
25 6 * time.Hour,
26 24 * time.Hour, // 1 day
27 7 * 24 * time.Hour, // 1 week
28 4 * 7 * 24 * time.Hour, // 4 weeks
29 16 * 7 * 24 * time.Hour, // 16 weeks
30}
31
32var minuteHourSeriesResolutions = []time.Duration{
33 1 * time.Second,
34 1 * time.Minute,
35}
36
37// An Observable is a kind of data that can be aggregated in a time series.
38type Observable interface {
39 Multiply(ratio float64) // Multiplies the data in self by a given ratio
40 Add(other Observable) // Adds the data from a different observation to self
41 Clear() // Clears the observation so it can be reused.
42 CopyFrom(other Observable) // Copies the contents of a given observation to self
43}
44
45// Float attaches the methods of Observable to a float64.
46type Float float64
47
48// NewFloat returns a Float.
49func NewFloat() Observable {
50 f := Float(0)
51 return &f
52}
53
54// String returns the float as a string.
55func (f *Float) String() string { return fmt.Sprintf("%g", f.Value()) }
56
57// Value returns the float's value.
58func (f *Float) Value() float64 { return float64(*f) }
59
60func (f *Float) Multiply(ratio float64) { *f *= Float(ratio) }
61
62func (f *Float) Add(other Observable) {
63 o := other.(*Float)
64 *f += *o
65}
66
67func (f *Float) Clear() { *f = 0 }
68
69func (f *Float) CopyFrom(other Observable) {
70 o := other.(*Float)
71 *f = *o
72}
73
74// A Clock tells the current time.
75type Clock interface {
76 Time() time.Time
77}
78
79type defaultClock int
80
81var defaultClockInstance defaultClock
82
83func (defaultClock) Time() time.Time { return time.Now() }
84
85// Information kept per level. Each level consists of a circular list of
86// observations. The start of the level may be derived from end and the
87// len(buckets) * sizeInMillis.
88type tsLevel struct {
89 oldest int // index to oldest bucketed Observable
90 newest int // index to newest bucketed Observable
91 end time.Time // end timestamp for this level
92 size time.Duration // duration of the bucketed Observable
93 buckets []Observable // collections of observations
94 provider func() Observable // used for creating new Observable
95}
96
97func (l *tsLevel) Clear() {
98 l.oldest = 0
99 l.newest = len(l.buckets) - 1
100 l.end = time.Time{}
101 for i := range l.buckets {
102 if l.buckets[i] != nil {
103 l.buckets[i].Clear()
104 l.buckets[i] = nil
105 }
106 }
107}
108
109func (l *tsLevel) InitLevel(size time.Duration, numBuckets int, f func() Observable) {
110 l.size = size
111 l.provider = f
112 l.buckets = make([]Observable, numBuckets)
113}
114
115// Keeps a sequence of levels. Each level is responsible for storing data at
116// a given resolution. For example, the first level stores data at a one
117// minute resolution while the second level stores data at a one hour
118// resolution.
119
120// Each level is represented by a sequence of buckets. Each bucket spans an
121// interval equal to the resolution of the level. New observations are added
122// to the last bucket.
123type timeSeries struct {
124 provider func() Observable // make more Observable
125 numBuckets int // number of buckets in each level
126 levels []*tsLevel // levels of bucketed Observable
127 lastAdd time.Time // time of last Observable tracked
128 total Observable // convenient aggregation of all Observable
129 clock Clock // Clock for getting current time
130 pending Observable // observations not yet bucketed
131 pendingTime time.Time // what time are we keeping in pending
132 dirty bool // if there are pending observations
133}
134
135// init initializes a level according to the supplied criteria.
136func (ts *timeSeries) init(resolutions []time.Duration, f func() Observable, numBuckets int, clock Clock) {
137 ts.provider = f
138 ts.numBuckets = numBuckets
139 ts.clock = clock
140 ts.levels = make([]*tsLevel, len(resolutions))
141
142 for i := range resolutions {
143 if i > 0 && resolutions[i-1] >= resolutions[i] {
144 log.Print("timeseries: resolutions must be monotonically increasing")
145 break
146 }
147 newLevel := new(tsLevel)
148 newLevel.InitLevel(resolutions[i], ts.numBuckets, ts.provider)
149 ts.levels[i] = newLevel
150 }
151
152 ts.Clear()
153}
154
155// Clear removes all observations from the time series.
156func (ts *timeSeries) Clear() {
157 ts.lastAdd = time.Time{}
158 ts.total = ts.resetObservation(ts.total)
159 ts.pending = ts.resetObservation(ts.pending)
160 ts.pendingTime = time.Time{}
161 ts.dirty = false
162
163 for i := range ts.levels {
164 ts.levels[i].Clear()
165 }
166}
167
168// Add records an observation at the current time.
169func (ts *timeSeries) Add(observation Observable) {
170 ts.AddWithTime(observation, ts.clock.Time())
171}
172
173// AddWithTime records an observation at the specified time.
174func (ts *timeSeries) AddWithTime(observation Observable, t time.Time) {
175
176 smallBucketDuration := ts.levels[0].size
177
178 if t.After(ts.lastAdd) {
179 ts.lastAdd = t
180 }
181
182 if t.After(ts.pendingTime) {
183 ts.advance(t)
184 ts.mergePendingUpdates()
185 ts.pendingTime = ts.levels[0].end
186 ts.pending.CopyFrom(observation)
187 ts.dirty = true
188 } else if t.After(ts.pendingTime.Add(-1 * smallBucketDuration)) {
189 // The observation is close enough to go into the pending bucket.
190 // This compensates for clock skewing and small scheduling delays
191 // by letting the update stay in the fast path.
192 ts.pending.Add(observation)
193 ts.dirty = true
194 } else {
195 ts.mergeValue(observation, t)
196 }
197}
198
199// mergeValue inserts the observation at the specified time in the past into all levels.
200func (ts *timeSeries) mergeValue(observation Observable, t time.Time) {
201 for _, level := range ts.levels {
202 index := (ts.numBuckets - 1) - int(level.end.Sub(t)/level.size)
203 if 0 <= index && index < ts.numBuckets {
204 bucketNumber := (level.oldest + index) % ts.numBuckets
205 if level.buckets[bucketNumber] == nil {
206 level.buckets[bucketNumber] = level.provider()
207 }
208 level.buckets[bucketNumber].Add(observation)
209 }
210 }
211 ts.total.Add(observation)
212}
213
214// mergePendingUpdates applies the pending updates into all levels.
215func (ts *timeSeries) mergePendingUpdates() {
216 if ts.dirty {
217 ts.mergeValue(ts.pending, ts.pendingTime)
218 ts.pending = ts.resetObservation(ts.pending)
219 ts.dirty = false
220 }
221}
222
223// advance cycles the buckets at each level until the latest bucket in
224// each level can hold the time specified.
225func (ts *timeSeries) advance(t time.Time) {
226 if !t.After(ts.levels[0].end) {
227 return
228 }
229 for i := 0; i < len(ts.levels); i++ {
230 level := ts.levels[i]
231 if !level.end.Before(t) {
232 break
233 }
234
235 // If the time is sufficiently far, just clear the level and advance
236 // directly.
237 if !t.Before(level.end.Add(level.size * time.Duration(ts.numBuckets))) {
238 for _, b := range level.buckets {
239 ts.resetObservation(b)
240 }
241 level.end = time.Unix(0, (t.UnixNano()/level.size.Nanoseconds())*level.size.Nanoseconds())
242 }
243
244 for t.After(level.end) {
245 level.end = level.end.Add(level.size)
246 level.newest = level.oldest
247 level.oldest = (level.oldest + 1) % ts.numBuckets
248 ts.resetObservation(level.buckets[level.newest])
249 }
250
251 t = level.end
252 }
253}
254
255// Latest returns the sum of the num latest buckets from the level.
256func (ts *timeSeries) Latest(level, num int) Observable {
257 now := ts.clock.Time()
258 if ts.levels[0].end.Before(now) {
259 ts.advance(now)
260 }
261
262 ts.mergePendingUpdates()
263
264 result := ts.provider()
265 l := ts.levels[level]
266 index := l.newest
267
268 for i := 0; i < num; i++ {
269 if l.buckets[index] != nil {
270 result.Add(l.buckets[index])
271 }
272 if index == 0 {
273 index = ts.numBuckets
274 }
275 index--
276 }
277
278 return result
279}
280
281// LatestBuckets returns a copy of the num latest buckets from level.
282func (ts *timeSeries) LatestBuckets(level, num int) []Observable {
283 if level < 0 || level > len(ts.levels) {
284 log.Print("timeseries: bad level argument: ", level)
285 return nil
286 }
287 if num < 0 || num >= ts.numBuckets {
288 log.Print("timeseries: bad num argument: ", num)
289 return nil
290 }
291
292 results := make([]Observable, num)
293 now := ts.clock.Time()
294 if ts.levels[0].end.Before(now) {
295 ts.advance(now)
296 }
297
298 ts.mergePendingUpdates()
299
300 l := ts.levels[level]
301 index := l.newest
302
303 for i := 0; i < num; i++ {
304 result := ts.provider()
305 results[i] = result
306 if l.buckets[index] != nil {
307 result.CopyFrom(l.buckets[index])
308 }
309
310 if index == 0 {
311 index = ts.numBuckets
312 }
313 index -= 1
314 }
315 return results
316}
317
318// ScaleBy updates observations by scaling by factor.
319func (ts *timeSeries) ScaleBy(factor float64) {
320 for _, l := range ts.levels {
321 for i := 0; i < ts.numBuckets; i++ {
322 l.buckets[i].Multiply(factor)
323 }
324 }
325
326 ts.total.Multiply(factor)
327 ts.pending.Multiply(factor)
328}
329
330// Range returns the sum of observations added over the specified time range.
331// If start or finish times don't fall on bucket boundaries of the same
332// level, then return values are approximate answers.
333func (ts *timeSeries) Range(start, finish time.Time) Observable {
334 return ts.ComputeRange(start, finish, 1)[0]
335}
336
337// Recent returns the sum of observations from the last delta.
338func (ts *timeSeries) Recent(delta time.Duration) Observable {
339 now := ts.clock.Time()
340 return ts.Range(now.Add(-delta), now)
341}
342
343// Total returns the total of all observations.
344func (ts *timeSeries) Total() Observable {
345 ts.mergePendingUpdates()
346 return ts.total
347}
348
349// ComputeRange computes a specified number of values into a slice using
350// the observations recorded over the specified time period. The return
351// values are approximate if the start or finish times don't fall on the
352// bucket boundaries at the same level or if the number of buckets spanning
353// the range is not an integral multiple of num.
354func (ts *timeSeries) ComputeRange(start, finish time.Time, num int) []Observable {
355 if start.After(finish) {
356 log.Printf("timeseries: start > finish, %v>%v", start, finish)
357 return nil
358 }
359
360 if num < 0 {
361 log.Printf("timeseries: num < 0, %v", num)
362 return nil
363 }
364
365 results := make([]Observable, num)
366
367 for _, l := range ts.levels {
368 if !start.Before(l.end.Add(-l.size * time.Duration(ts.numBuckets))) {
369 ts.extract(l, start, finish, num, results)
370 return results
371 }
372 }
373
374 // Failed to find a level that covers the desired range. So just
375 // extract from the last level, even if it doesn't cover the entire
376 // desired range.
377 ts.extract(ts.levels[len(ts.levels)-1], start, finish, num, results)
378
379 return results
380}
381
382// RecentList returns the specified number of values in slice over the most
383// recent time period of the specified range.
384func (ts *timeSeries) RecentList(delta time.Duration, num int) []Observable {
385 if delta < 0 {
386 return nil
387 }
388 now := ts.clock.Time()
389 return ts.ComputeRange(now.Add(-delta), now, num)
390}
391
392// extract returns a slice of specified number of observations from a given
393// level over a given range.
394func (ts *timeSeries) extract(l *tsLevel, start, finish time.Time, num int, results []Observable) {
395 ts.mergePendingUpdates()
396
397 srcInterval := l.size
398 dstInterval := finish.Sub(start) / time.Duration(num)
399 dstStart := start
400 srcStart := l.end.Add(-srcInterval * time.Duration(ts.numBuckets))
401
402 srcIndex := 0
403
404 // Where should scanning start?
405 if dstStart.After(srcStart) {
406 advance := dstStart.Sub(srcStart) / srcInterval
407 srcIndex += int(advance)
408 srcStart = srcStart.Add(advance * srcInterval)
409 }
410
411 // The i'th value is computed as show below.
412 // interval = (finish/start)/num
413 // i'th value = sum of observation in range
414 // [ start + i * interval,
415 // start + (i + 1) * interval )
416 for i := 0; i < num; i++ {
417 results[i] = ts.resetObservation(results[i])
418 dstEnd := dstStart.Add(dstInterval)
419 for srcIndex < ts.numBuckets && srcStart.Before(dstEnd) {
420 srcEnd := srcStart.Add(srcInterval)
421 if srcEnd.After(ts.lastAdd) {
422 srcEnd = ts.lastAdd
423 }
424
425 if !srcEnd.Before(dstStart) {
426 srcValue := l.buckets[(srcIndex+l.oldest)%ts.numBuckets]
427 if !srcStart.Before(dstStart) && !srcEnd.After(dstEnd) {
428 // dst completely contains src.
429 if srcValue != nil {
430 results[i].Add(srcValue)
431 }
432 } else {
433 // dst partially overlaps src.
434 overlapStart := maxTime(srcStart, dstStart)
435 overlapEnd := minTime(srcEnd, dstEnd)
436 base := srcEnd.Sub(srcStart)
437 fraction := overlapEnd.Sub(overlapStart).Seconds() / base.Seconds()
438
439 used := ts.provider()
440 if srcValue != nil {
441 used.CopyFrom(srcValue)
442 }
443 used.Multiply(fraction)
444 results[i].Add(used)
445 }
446
447 if srcEnd.After(dstEnd) {
448 break
449 }
450 }
451 srcIndex++
452 srcStart = srcStart.Add(srcInterval)
453 }
454 dstStart = dstStart.Add(dstInterval)
455 }
456}
457
458// resetObservation clears the content so the struct may be reused.
459func (ts *timeSeries) resetObservation(observation Observable) Observable {
460 if observation == nil {
461 observation = ts.provider()
462 } else {
463 observation.Clear()
464 }
465 return observation
466}
467
468// TimeSeries tracks data at granularities from 1 second to 16 weeks.
469type TimeSeries struct {
470 timeSeries
471}
472
473// NewTimeSeries creates a new TimeSeries using the function provided for creating new Observable.
474func NewTimeSeries(f func() Observable) *TimeSeries {
475 return NewTimeSeriesWithClock(f, defaultClockInstance)
476}
477
478// NewTimeSeriesWithClock creates a new TimeSeries using the function provided for creating new Observable and the clock for
479// assigning timestamps.
480func NewTimeSeriesWithClock(f func() Observable, clock Clock) *TimeSeries {
481 ts := new(TimeSeries)
482 ts.timeSeries.init(timeSeriesResolutions, f, timeSeriesNumBuckets, clock)
483 return ts
484}
485
486// MinuteHourSeries tracks data at granularities of 1 minute and 1 hour.
487type MinuteHourSeries struct {
488 timeSeries
489}
490
491// NewMinuteHourSeries creates a new MinuteHourSeries using the function provided for creating new Observable.
492func NewMinuteHourSeries(f func() Observable) *MinuteHourSeries {
493 return NewMinuteHourSeriesWithClock(f, defaultClockInstance)
494}
495
496// NewMinuteHourSeriesWithClock creates a new MinuteHourSeries using the function provided for creating new Observable and the clock for
497// assigning timestamps.
498func NewMinuteHourSeriesWithClock(f func() Observable, clock Clock) *MinuteHourSeries {
499 ts := new(MinuteHourSeries)
500 ts.timeSeries.init(minuteHourSeriesResolutions, f,
501 minuteHourSeriesNumBuckets, clock)
502 return ts
503}
504
505func (ts *MinuteHourSeries) Minute() Observable {
506 return ts.timeSeries.Latest(0, 60)
507}
508
509func (ts *MinuteHourSeries) Hour() Observable {
510 return ts.timeSeries.Latest(1, 60)
511}
512
513func minTime(a, b time.Time) time.Time {
514 if a.Before(b) {
515 return a
516 }
517 return b
518}
519
520func maxTime(a, b time.Time) time.Time {
521 if a.After(b) {
522 return a
523 }
524 return b
525}
diff --git a/vendor/golang.org/x/net/lex/httplex/httplex.go b/vendor/golang.org/x/net/lex/httplex/httplex.go
new file mode 100644
index 0000000..20f2b89
--- /dev/null
+++ b/vendor/golang.org/x/net/lex/httplex/httplex.go
@@ -0,0 +1,351 @@
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package httplex contains rules around lexical matters of various
6// HTTP-related specifications.
7//
8// This package is shared by the standard library (which vendors it)
9// and x/net/http2. It comes with no API stability promise.
10package httplex
11
12import (
13 "net"
14 "strings"
15 "unicode/utf8"
16
17 "golang.org/x/net/idna"
18)
19
20var isTokenTable = [127]bool{
21 '!': true,
22 '#': true,
23 '$': true,
24 '%': true,
25 '&': true,
26 '\'': true,
27 '*': true,
28 '+': true,
29 '-': true,
30 '.': true,
31 '0': true,
32 '1': true,
33 '2': true,
34 '3': true,
35 '4': true,
36 '5': true,
37 '6': true,
38 '7': true,
39 '8': true,
40 '9': true,
41 'A': true,
42 'B': true,
43 'C': true,
44 'D': true,
45 'E': true,
46 'F': true,
47 'G': true,
48 'H': true,
49 'I': true,
50 'J': true,
51 'K': true,
52 'L': true,
53 'M': true,
54 'N': true,
55 'O': true,
56 'P': true,
57 'Q': true,
58 'R': true,
59 'S': true,
60 'T': true,
61 'U': true,
62 'W': true,
63 'V': true,
64 'X': true,
65 'Y': true,
66 'Z': true,
67 '^': true,
68 '_': true,
69 '`': true,
70 'a': true,
71 'b': true,
72 'c': true,
73 'd': true,
74 'e': true,
75 'f': true,
76 'g': true,
77 'h': true,
78 'i': true,
79 'j': true,
80 'k': true,
81 'l': true,
82 'm': true,
83 'n': true,
84 'o': true,
85 'p': true,
86 'q': true,
87 'r': true,
88 's': true,
89 't': true,
90 'u': true,
91 'v': true,
92 'w': true,
93 'x': true,
94 'y': true,
95 'z': true,
96 '|': true,
97 '~': true,
98}
99
100func IsTokenRune(r rune) bool {
101 i := int(r)
102 return i < len(isTokenTable) && isTokenTable[i]
103}
104
105func isNotToken(r rune) bool {
106 return !IsTokenRune(r)
107}
108
109// HeaderValuesContainsToken reports whether any string in values
110// contains the provided token, ASCII case-insensitively.
111func HeaderValuesContainsToken(values []string, token string) bool {
112 for _, v := range values {
113 if headerValueContainsToken(v, token) {
114 return true
115 }
116 }
117 return false
118}
119
120// isOWS reports whether b is an optional whitespace byte, as defined
121// by RFC 7230 section 3.2.3.
122func isOWS(b byte) bool { return b == ' ' || b == '\t' }
123
124// trimOWS returns x with all optional whitespace removes from the
125// beginning and end.
126func trimOWS(x string) string {
127 // TODO: consider using strings.Trim(x, " \t") instead,
128 // if and when it's fast enough. See issue 10292.
129 // But this ASCII-only code will probably always beat UTF-8
130 // aware code.
131 for len(x) > 0 && isOWS(x[0]) {
132 x = x[1:]
133 }
134 for len(x) > 0 && isOWS(x[len(x)-1]) {
135 x = x[:len(x)-1]
136 }
137 return x
138}
139
140// headerValueContainsToken reports whether v (assumed to be a
141// 0#element, in the ABNF extension described in RFC 7230 section 7)
142// contains token amongst its comma-separated tokens, ASCII
143// case-insensitively.
144func headerValueContainsToken(v string, token string) bool {
145 v = trimOWS(v)
146 if comma := strings.IndexByte(v, ','); comma != -1 {
147 return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
148 }
149 return tokenEqual(v, token)
150}
151
152// lowerASCII returns the ASCII lowercase version of b.
153func lowerASCII(b byte) byte {
154 if 'A' <= b && b <= 'Z' {
155 return b + ('a' - 'A')
156 }
157 return b
158}
159
160// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.
161func tokenEqual(t1, t2 string) bool {
162 if len(t1) != len(t2) {
163 return false
164 }
165 for i, b := range t1 {
166 if b >= utf8.RuneSelf {
167 // No UTF-8 or non-ASCII allowed in tokens.
168 return false
169 }
170 if lowerASCII(byte(b)) != lowerASCII(t2[i]) {
171 return false
172 }
173 }
174 return true
175}
176
177// isLWS reports whether b is linear white space, according
178// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
179// LWS = [CRLF] 1*( SP | HT )
180func isLWS(b byte) bool { return b == ' ' || b == '\t' }
181
182// isCTL reports whether b is a control byte, according
183// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
184// CTL = <any US-ASCII control character
185// (octets 0 - 31) and DEL (127)>
186func isCTL(b byte) bool {
187 const del = 0x7f // a CTL
188 return b < ' ' || b == del
189}
190
191// ValidHeaderFieldName reports whether v is a valid HTTP/1.x header name.
192// HTTP/2 imposes the additional restriction that uppercase ASCII
193// letters are not allowed.
194//
195// RFC 7230 says:
196// header-field = field-name ":" OWS field-value OWS
197// field-name = token
198// token = 1*tchar
199// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
200// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
201func ValidHeaderFieldName(v string) bool {
202 if len(v) == 0 {
203 return false
204 }
205 for _, r := range v {
206 if !IsTokenRune(r) {
207 return false
208 }
209 }
210 return true
211}
212
213// ValidHostHeader reports whether h is a valid host header.
214func ValidHostHeader(h string) bool {
215 // The latest spec is actually this:
216 //
217 // http://tools.ietf.org/html/rfc7230#section-5.4
218 // Host = uri-host [ ":" port ]
219 //
220 // Where uri-host is:
221 // http://tools.ietf.org/html/rfc3986#section-3.2.2
222 //
223 // But we're going to be much more lenient for now and just
224 // search for any byte that's not a valid byte in any of those
225 // expressions.
226 for i := 0; i < len(h); i++ {
227 if !validHostByte[h[i]] {
228 return false
229 }
230 }
231 return true
232}
233
234// See the validHostHeader comment.
235var validHostByte = [256]bool{
236 '0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true,
237 '8': true, '9': true,
238
239 'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true,
240 'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true,
241 'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true,
242 'y': true, 'z': true,
243
244 'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true,
245 'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true,
246 'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true,
247 'Y': true, 'Z': true,
248
249 '!': true, // sub-delims
250 '$': true, // sub-delims
251 '%': true, // pct-encoded (and used in IPv6 zones)
252 '&': true, // sub-delims
253 '(': true, // sub-delims
254 ')': true, // sub-delims
255 '*': true, // sub-delims
256 '+': true, // sub-delims
257 ',': true, // sub-delims
258 '-': true, // unreserved
259 '.': true, // unreserved
260 ':': true, // IPv6address + Host expression's optional port
261 ';': true, // sub-delims
262 '=': true, // sub-delims
263 '[': true,
264 '\'': true, // sub-delims
265 ']': true,
266 '_': true, // unreserved
267 '~': true, // unreserved
268}
269
270// ValidHeaderFieldValue reports whether v is a valid "field-value" according to
271// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
272//
273// message-header = field-name ":" [ field-value ]
274// field-value = *( field-content | LWS )
275// field-content = <the OCTETs making up the field-value
276// and consisting of either *TEXT or combinations
277// of token, separators, and quoted-string>
278//
279// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
280//
281// TEXT = <any OCTET except CTLs,
282// but including LWS>
283// LWS = [CRLF] 1*( SP | HT )
284// CTL = <any US-ASCII control character
285// (octets 0 - 31) and DEL (127)>
286//
287// RFC 7230 says:
288// field-value = *( field-content / obs-fold )
289// obj-fold = N/A to http2, and deprecated
290// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
291// field-vchar = VCHAR / obs-text
292// obs-text = %x80-FF
293// VCHAR = "any visible [USASCII] character"
294//
295// http2 further says: "Similarly, HTTP/2 allows header field values
296// that are not valid. While most of the values that can be encoded
297// will not alter header field parsing, carriage return (CR, ASCII
298// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
299// 0x0) might be exploited by an attacker if they are translated
300// verbatim. Any request or response that contains a character not
301// permitted in a header field value MUST be treated as malformed
302// (Section 8.1.2.6). Valid characters are defined by the
303// field-content ABNF rule in Section 3.2 of [RFC7230]."
304//
305// This function does not (yet?) properly handle the rejection of
306// strings that begin or end with SP or HTAB.
307func ValidHeaderFieldValue(v string) bool {
308 for i := 0; i < len(v); i++ {
309 b := v[i]
310 if isCTL(b) && !isLWS(b) {
311 return false
312 }
313 }
314 return true
315}
316
317func isASCII(s string) bool {
318 for i := 0; i < len(s); i++ {
319 if s[i] >= utf8.RuneSelf {
320 return false
321 }
322 }
323 return true
324}
325
326// PunycodeHostPort returns the IDNA Punycode version
327// of the provided "host" or "host:port" string.
328func PunycodeHostPort(v string) (string, error) {
329 if isASCII(v) {
330 return v, nil
331 }
332
333 host, port, err := net.SplitHostPort(v)
334 if err != nil {
335 // The input 'v' argument was just a "host" argument,
336 // without a port. This error should not be returned
337 // to the caller.
338 host = v
339 port = ""
340 }
341 host, err = idna.ToASCII(host)
342 if err != nil {
343 // Non-UTF-8? Not representable in Punycode, in any
344 // case.
345 return "", err
346 }
347 if port == "" {
348 return host, nil
349 }
350 return net.JoinHostPort(host, port), nil
351}
diff --git a/vendor/golang.org/x/net/trace/events.go b/vendor/golang.org/x/net/trace/events.go
new file mode 100644
index 0000000..c646a69
--- /dev/null
+++ b/vendor/golang.org/x/net/trace/events.go
@@ -0,0 +1,532 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package trace
6
7import (
8 "bytes"
9 "fmt"
10 "html/template"
11 "io"
12 "log"
13 "net/http"
14 "runtime"
15 "sort"
16 "strconv"
17 "strings"
18 "sync"
19 "sync/atomic"
20 "text/tabwriter"
21 "time"
22)
23
24const maxEventsPerLog = 100
25
26type bucket struct {
27 MaxErrAge time.Duration
28 String string
29}
30
31var buckets = []bucket{
32 {0, "total"},
33 {10 * time.Second, "errs<10s"},
34 {1 * time.Minute, "errs<1m"},
35 {10 * time.Minute, "errs<10m"},
36 {1 * time.Hour, "errs<1h"},
37 {10 * time.Hour, "errs<10h"},
38 {24000 * time.Hour, "errors"},
39}
40
41// RenderEvents renders the HTML page typically served at /debug/events.
42// It does not do any auth checking. The request may be nil.
43//
44// Most users will use the Events handler.
45func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) {
46 now := time.Now()
47 data := &struct {
48 Families []string // family names
49 Buckets []bucket
50 Counts [][]int // eventLog count per family/bucket
51
52 // Set when a bucket has been selected.
53 Family string
54 Bucket int
55 EventLogs eventLogs
56 Expanded bool
57 }{
58 Buckets: buckets,
59 }
60
61 data.Families = make([]string, 0, len(families))
62 famMu.RLock()
63 for name := range families {
64 data.Families = append(data.Families, name)
65 }
66 famMu.RUnlock()
67 sort.Strings(data.Families)
68
69 // Count the number of eventLogs in each family for each error age.
70 data.Counts = make([][]int, len(data.Families))
71 for i, name := range data.Families {
72 // TODO(sameer): move this loop under the family lock.
73 f := getEventFamily(name)
74 data.Counts[i] = make([]int, len(data.Buckets))
75 for j, b := range data.Buckets {
76 data.Counts[i][j] = f.Count(now, b.MaxErrAge)
77 }
78 }
79
80 if req != nil {
81 var ok bool
82 data.Family, data.Bucket, ok = parseEventsArgs(req)
83 if !ok {
84 // No-op
85 } else {
86 data.EventLogs = getEventFamily(data.Family).Copy(now, buckets[data.Bucket].MaxErrAge)
87 }
88 if data.EventLogs != nil {
89 defer data.EventLogs.Free()
90 sort.Sort(data.EventLogs)
91 }
92 if exp, err := strconv.ParseBool(req.FormValue("exp")); err == nil {
93 data.Expanded = exp
94 }
95 }
96
97 famMu.RLock()
98 defer famMu.RUnlock()
99 if err := eventsTmpl().Execute(w, data); err != nil {
100 log.Printf("net/trace: Failed executing template: %v", err)
101 }
102}
103
104func parseEventsArgs(req *http.Request) (fam string, b int, ok bool) {
105 fam, bStr := req.FormValue("fam"), req.FormValue("b")
106 if fam == "" || bStr == "" {
107 return "", 0, false
108 }
109 b, err := strconv.Atoi(bStr)
110 if err != nil || b < 0 || b >= len(buckets) {
111 return "", 0, false
112 }
113 return fam, b, true
114}
115
116// An EventLog provides a log of events associated with a specific object.
117type EventLog interface {
118 // Printf formats its arguments with fmt.Sprintf and adds the
119 // result to the event log.
120 Printf(format string, a ...interface{})
121
122 // Errorf is like Printf, but it marks this event as an error.
123 Errorf(format string, a ...interface{})
124
125 // Finish declares that this event log is complete.
126 // The event log should not be used after calling this method.
127 Finish()
128}
129
130// NewEventLog returns a new EventLog with the specified family name
131// and title.
132func NewEventLog(family, title string) EventLog {
133 el := newEventLog()
134 el.ref()
135 el.Family, el.Title = family, title
136 el.Start = time.Now()
137 el.events = make([]logEntry, 0, maxEventsPerLog)
138 el.stack = make([]uintptr, 32)
139 n := runtime.Callers(2, el.stack)
140 el.stack = el.stack[:n]
141
142 getEventFamily(family).add(el)
143 return el
144}
145
146func (el *eventLog) Finish() {
147 getEventFamily(el.Family).remove(el)
148 el.unref() // matches ref in New
149}
150
151var (
152 famMu sync.RWMutex
153 families = make(map[string]*eventFamily) // family name => family
154)
155
156func getEventFamily(fam string) *eventFamily {
157 famMu.Lock()
158 defer famMu.Unlock()
159 f := families[fam]
160 if f == nil {
161 f = &eventFamily{}
162 families[fam] = f
163 }
164 return f
165}
166
167type eventFamily struct {
168 mu sync.RWMutex
169 eventLogs eventLogs
170}
171
172func (f *eventFamily) add(el *eventLog) {
173 f.mu.Lock()
174 f.eventLogs = append(f.eventLogs, el)
175 f.mu.Unlock()
176}
177
178func (f *eventFamily) remove(el *eventLog) {
179 f.mu.Lock()
180 defer f.mu.Unlock()
181 for i, el0 := range f.eventLogs {
182 if el == el0 {
183 copy(f.eventLogs[i:], f.eventLogs[i+1:])
184 f.eventLogs = f.eventLogs[:len(f.eventLogs)-1]
185 return
186 }
187 }
188}
189
190func (f *eventFamily) Count(now time.Time, maxErrAge time.Duration) (n int) {
191 f.mu.RLock()
192 defer f.mu.RUnlock()
193 for _, el := range f.eventLogs {
194 if el.hasRecentError(now, maxErrAge) {
195 n++
196 }
197 }
198 return
199}
200
201func (f *eventFamily) Copy(now time.Time, maxErrAge time.Duration) (els eventLogs) {
202 f.mu.RLock()
203 defer f.mu.RUnlock()
204 els = make(eventLogs, 0, len(f.eventLogs))
205 for _, el := range f.eventLogs {
206 if el.hasRecentError(now, maxErrAge) {
207 el.ref()
208 els = append(els, el)
209 }
210 }
211 return
212}
213
214type eventLogs []*eventLog
215
216// Free calls unref on each element of the list.
217func (els eventLogs) Free() {
218 for _, el := range els {
219 el.unref()
220 }
221}
222
223// eventLogs may be sorted in reverse chronological order.
224func (els eventLogs) Len() int { return len(els) }
225func (els eventLogs) Less(i, j int) bool { return els[i].Start.After(els[j].Start) }
226func (els eventLogs) Swap(i, j int) { els[i], els[j] = els[j], els[i] }
227
228// A logEntry is a timestamped log entry in an event log.
229type logEntry struct {
230 When time.Time
231 Elapsed time.Duration // since previous event in log
232 NewDay bool // whether this event is on a different day to the previous event
233 What string
234 IsErr bool
235}
236
237// WhenString returns a string representation of the elapsed time of the event.
238// It will include the date if midnight was crossed.
239func (e logEntry) WhenString() string {
240 if e.NewDay {
241 return e.When.Format("2006/01/02 15:04:05.000000")
242 }
243 return e.When.Format("15:04:05.000000")
244}
245
246// An eventLog represents an active event log.
247type eventLog struct {
248 // Family is the top-level grouping of event logs to which this belongs.
249 Family string
250
251 // Title is the title of this event log.
252 Title string
253
254 // Timing information.
255 Start time.Time
256
257 // Call stack where this event log was created.
258 stack []uintptr
259
260 // Append-only sequence of events.
261 //
262 // TODO(sameer): change this to a ring buffer to avoid the array copy
263 // when we hit maxEventsPerLog.
264 mu sync.RWMutex
265 events []logEntry
266 LastErrorTime time.Time
267 discarded int
268
269 refs int32 // how many buckets this is in
270}
271
272func (el *eventLog) reset() {
273 // Clear all but the mutex. Mutexes may not be copied, even when unlocked.
274 el.Family = ""
275 el.Title = ""
276 el.Start = time.Time{}
277 el.stack = nil
278 el.events = nil
279 el.LastErrorTime = time.Time{}
280 el.discarded = 0
281 el.refs = 0
282}
283
284func (el *eventLog) hasRecentError(now time.Time, maxErrAge time.Duration) bool {
285 if maxErrAge == 0 {
286 return true
287 }
288 el.mu.RLock()
289 defer el.mu.RUnlock()
290 return now.Sub(el.LastErrorTime) < maxErrAge
291}
292
293// delta returns the elapsed time since the last event or the log start,
294// and whether it spans midnight.
295// L >= el.mu
296func (el *eventLog) delta(t time.Time) (time.Duration, bool) {
297 if len(el.events) == 0 {
298 return t.Sub(el.Start), false
299 }
300 prev := el.events[len(el.events)-1].When
301 return t.Sub(prev), prev.Day() != t.Day()
302
303}
304
305func (el *eventLog) Printf(format string, a ...interface{}) {
306 el.printf(false, format, a...)
307}
308
309func (el *eventLog) Errorf(format string, a ...interface{}) {
310 el.printf(true, format, a...)
311}
312
313func (el *eventLog) printf(isErr bool, format string, a ...interface{}) {
314 e := logEntry{When: time.Now(), IsErr: isErr, What: fmt.Sprintf(format, a...)}
315 el.mu.Lock()
316 e.Elapsed, e.NewDay = el.delta(e.When)
317 if len(el.events) < maxEventsPerLog {
318 el.events = append(el.events, e)
319 } else {
320 // Discard the oldest event.
321 if el.discarded == 0 {
322 // el.discarded starts at two to count for the event it
323 // is replacing, plus the next one that we are about to
324 // drop.
325 el.discarded = 2
326 } else {
327 el.discarded++
328 }
329 // TODO(sameer): if this causes allocations on a critical path,
330 // change eventLog.What to be a fmt.Stringer, as in trace.go.
331 el.events[0].What = fmt.Sprintf("(%d events discarded)", el.discarded)
332 // The timestamp of the discarded meta-event should be
333 // the time of the last event it is representing.
334 el.events[0].When = el.events[1].When
335 copy(el.events[1:], el.events[2:])
336 el.events[maxEventsPerLog-1] = e
337 }
338 if e.IsErr {
339 el.LastErrorTime = e.When
340 }
341 el.mu.Unlock()
342}
343
344func (el *eventLog) ref() {
345 atomic.AddInt32(&el.refs, 1)
346}
347
348func (el *eventLog) unref() {
349 if atomic.AddInt32(&el.refs, -1) == 0 {
350 freeEventLog(el)
351 }
352}
353
354func (el *eventLog) When() string {
355 return el.Start.Format("2006/01/02 15:04:05.000000")
356}
357
358func (el *eventLog) ElapsedTime() string {
359 elapsed := time.Since(el.Start)
360 return fmt.Sprintf("%.6f", elapsed.Seconds())
361}
362
363func (el *eventLog) Stack() string {
364 buf := new(bytes.Buffer)
365 tw := tabwriter.NewWriter(buf, 1, 8, 1, '\t', 0)
366 printStackRecord(tw, el.stack)
367 tw.Flush()
368 return buf.String()
369}
370
371// printStackRecord prints the function + source line information
372// for a single stack trace.
373// Adapted from runtime/pprof/pprof.go.
374func printStackRecord(w io.Writer, stk []uintptr) {
375 for _, pc := range stk {
376 f := runtime.FuncForPC(pc)
377 if f == nil {
378 continue
379 }
380 file, line := f.FileLine(pc)
381 name := f.Name()
382 // Hide runtime.goexit and any runtime functions at the beginning.
383 if strings.HasPrefix(name, "runtime.") {
384 continue
385 }
386 fmt.Fprintf(w, "# %s\t%s:%d\n", name, file, line)
387 }
388}
389
390func (el *eventLog) Events() []logEntry {
391 el.mu.RLock()
392 defer el.mu.RUnlock()
393 return el.events
394}
395
396// freeEventLogs is a freelist of *eventLog
397var freeEventLogs = make(chan *eventLog, 1000)
398
399// newEventLog returns a event log ready to use.
400func newEventLog() *eventLog {
401 select {
402 case el := <-freeEventLogs:
403 return el
404 default:
405 return new(eventLog)
406 }
407}
408
409// freeEventLog adds el to freeEventLogs if there's room.
410// This is non-blocking.
411func freeEventLog(el *eventLog) {
412 el.reset()
413 select {
414 case freeEventLogs <- el:
415 default:
416 }
417}
418
419var eventsTmplCache *template.Template
420var eventsTmplOnce sync.Once
421
422func eventsTmpl() *template.Template {
423 eventsTmplOnce.Do(func() {
424 eventsTmplCache = template.Must(template.New("events").Funcs(template.FuncMap{
425 "elapsed": elapsed,
426 "trimSpace": strings.TrimSpace,
427 }).Parse(eventsHTML))
428 })
429 return eventsTmplCache
430}
431
432const eventsHTML = `
433<html>
434 <head>
435 <title>events</title>
436 </head>
437 <style type="text/css">
438 body {
439 font-family: sans-serif;
440 }
441 table#req-status td.family {
442 padding-right: 2em;
443 }
444 table#req-status td.active {
445 padding-right: 1em;
446 }
447 table#req-status td.empty {
448 color: #aaa;
449 }
450 table#reqs {
451 margin-top: 1em;
452 }
453 table#reqs tr.first {
454 {{if $.Expanded}}font-weight: bold;{{end}}
455 }
456 table#reqs td {
457 font-family: monospace;
458 }
459 table#reqs td.when {
460 text-align: right;
461 white-space: nowrap;
462 }
463 table#reqs td.elapsed {
464 padding: 0 0.5em;
465 text-align: right;
466 white-space: pre;
467 width: 10em;
468 }
469 address {
470 font-size: smaller;
471 margin-top: 5em;
472 }
473 </style>
474 <body>
475
476<h1>/debug/events</h1>
477
478<table id="req-status">
479 {{range $i, $fam := .Families}}
480 <tr>
481 <td class="family">{{$fam}}</td>
482
483 {{range $j, $bucket := $.Buckets}}
484 {{$n := index $.Counts $i $j}}
485 <td class="{{if not $bucket.MaxErrAge}}active{{end}}{{if not $n}}empty{{end}}">
486 {{if $n}}<a href="?fam={{$fam}}&b={{$j}}{{if $.Expanded}}&exp=1{{end}}">{{end}}
487 [{{$n}} {{$bucket.String}}]
488 {{if $n}}</a>{{end}}
489 </td>
490 {{end}}
491
492 </tr>{{end}}
493</table>
494
495{{if $.EventLogs}}
496<hr />
497<h3>Family: {{$.Family}}</h3>
498
499{{if $.Expanded}}<a href="?fam={{$.Family}}&b={{$.Bucket}}">{{end}}
500[Summary]{{if $.Expanded}}</a>{{end}}
501
502{{if not $.Expanded}}<a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1">{{end}}
503[Expanded]{{if not $.Expanded}}</a>{{end}}
504
505<table id="reqs">
506 <tr><th>When</th><th>Elapsed</th></tr>
507 {{range $el := $.EventLogs}}
508 <tr class="first">
509 <td class="when">{{$el.When}}</td>
510 <td class="elapsed">{{$el.ElapsedTime}}</td>
511 <td>{{$el.Title}}
512 </tr>
513 {{if $.Expanded}}
514 <tr>
515 <td class="when"></td>
516 <td class="elapsed"></td>
517 <td><pre>{{$el.Stack|trimSpace}}</pre></td>
518 </tr>
519 {{range $el.Events}}
520 <tr>
521 <td class="when">{{.WhenString}}</td>
522 <td class="elapsed">{{elapsed .Elapsed}}</td>
523 <td>.{{if .IsErr}}E{{else}}.{{end}}. {{.What}}</td>
524 </tr>
525 {{end}}
526 {{end}}
527 {{end}}
528</table>
529{{end}}
530 </body>
531</html>
532`
diff --git a/vendor/golang.org/x/net/trace/histogram.go b/vendor/golang.org/x/net/trace/histogram.go
new file mode 100644
index 0000000..9bf4286
--- /dev/null
+++ b/vendor/golang.org/x/net/trace/histogram.go
@@ -0,0 +1,365 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package trace
6
7// This file implements histogramming for RPC statistics collection.
8
9import (
10 "bytes"
11 "fmt"
12 "html/template"
13 "log"
14 "math"
15 "sync"
16
17 "golang.org/x/net/internal/timeseries"
18)
19
20const (
21 bucketCount = 38
22)
23
24// histogram keeps counts of values in buckets that are spaced
25// out in powers of 2: 0-1, 2-3, 4-7...
26// histogram implements timeseries.Observable
27type histogram struct {
28 sum int64 // running total of measurements
29 sumOfSquares float64 // square of running total
30 buckets []int64 // bucketed values for histogram
31 value int // holds a single value as an optimization
32 valueCount int64 // number of values recorded for single value
33}
34
35// AddMeasurement records a value measurement observation to the histogram.
36func (h *histogram) addMeasurement(value int64) {
37 // TODO: assert invariant
38 h.sum += value
39 h.sumOfSquares += float64(value) * float64(value)
40
41 bucketIndex := getBucket(value)
42
43 if h.valueCount == 0 || (h.valueCount > 0 && h.value == bucketIndex) {
44 h.value = bucketIndex
45 h.valueCount++
46 } else {
47 h.allocateBuckets()
48 h.buckets[bucketIndex]++
49 }
50}
51
52func (h *histogram) allocateBuckets() {
53 if h.buckets == nil {
54 h.buckets = make([]int64, bucketCount)
55 h.buckets[h.value] = h.valueCount
56 h.value = 0
57 h.valueCount = -1
58 }
59}
60
61func log2(i int64) int {
62 n := 0
63 for ; i >= 0x100; i >>= 8 {
64 n += 8
65 }
66 for ; i > 0; i >>= 1 {
67 n += 1
68 }
69 return n
70}
71
72func getBucket(i int64) (index int) {
73 index = log2(i) - 1
74 if index < 0 {
75 index = 0
76 }
77 if index >= bucketCount {
78 index = bucketCount - 1
79 }
80 return
81}
82
83// Total returns the number of recorded observations.
84func (h *histogram) total() (total int64) {
85 if h.valueCount >= 0 {
86 total = h.valueCount
87 }
88 for _, val := range h.buckets {
89 total += int64(val)
90 }
91 return
92}
93
94// Average returns the average value of recorded observations.
95func (h *histogram) average() float64 {
96 t := h.total()
97 if t == 0 {
98 return 0
99 }
100 return float64(h.sum) / float64(t)
101}
102
103// Variance returns the variance of recorded observations.
104func (h *histogram) variance() float64 {
105 t := float64(h.total())
106 if t == 0 {
107 return 0
108 }
109 s := float64(h.sum) / t
110 return h.sumOfSquares/t - s*s
111}
112
113// StandardDeviation returns the standard deviation of recorded observations.
114func (h *histogram) standardDeviation() float64 {
115 return math.Sqrt(h.variance())
116}
117
118// PercentileBoundary estimates the value that the given fraction of recorded
119// observations are less than.
120func (h *histogram) percentileBoundary(percentile float64) int64 {
121 total := h.total()
122
123 // Corner cases (make sure result is strictly less than Total())
124 if total == 0 {
125 return 0
126 } else if total == 1 {
127 return int64(h.average())
128 }
129
130 percentOfTotal := round(float64(total) * percentile)
131 var runningTotal int64
132
133 for i := range h.buckets {
134 value := h.buckets[i]
135 runningTotal += value
136 if runningTotal == percentOfTotal {
137 // We hit an exact bucket boundary. If the next bucket has data, it is a
138 // good estimate of the value. If the bucket is empty, we interpolate the
139 // midpoint between the next bucket's boundary and the next non-zero
140 // bucket. If the remaining buckets are all empty, then we use the
141 // boundary for the next bucket as the estimate.
142 j := uint8(i + 1)
143 min := bucketBoundary(j)
144 if runningTotal < total {
145 for h.buckets[j] == 0 {
146 j++
147 }
148 }
149 max := bucketBoundary(j)
150 return min + round(float64(max-min)/2)
151 } else if runningTotal > percentOfTotal {
152 // The value is in this bucket. Interpolate the value.
153 delta := runningTotal - percentOfTotal
154 percentBucket := float64(value-delta) / float64(value)
155 bucketMin := bucketBoundary(uint8(i))
156 nextBucketMin := bucketBoundary(uint8(i + 1))
157 bucketSize := nextBucketMin - bucketMin
158 return bucketMin + round(percentBucket*float64(bucketSize))
159 }
160 }
161 return bucketBoundary(bucketCount - 1)
162}
163
164// Median returns the estimated median of the observed values.
165func (h *histogram) median() int64 {
166 return h.percentileBoundary(0.5)
167}
168
169// Add adds other to h.
170func (h *histogram) Add(other timeseries.Observable) {
171 o := other.(*histogram)
172 if o.valueCount == 0 {
173 // Other histogram is empty
174 } else if h.valueCount >= 0 && o.valueCount > 0 && h.value == o.value {
175 // Both have a single bucketed value, aggregate them
176 h.valueCount += o.valueCount
177 } else {
178 // Two different values necessitate buckets in this histogram
179 h.allocateBuckets()
180 if o.valueCount >= 0 {
181 h.buckets[o.value] += o.valueCount
182 } else {
183 for i := range h.buckets {
184 h.buckets[i] += o.buckets[i]
185 }
186 }
187 }
188 h.sumOfSquares += o.sumOfSquares
189 h.sum += o.sum
190}
191
192// Clear resets the histogram to an empty state, removing all observed values.
193func (h *histogram) Clear() {
194 h.buckets = nil
195 h.value = 0
196 h.valueCount = 0
197 h.sum = 0
198 h.sumOfSquares = 0
199}
200
201// CopyFrom copies from other, which must be a *histogram, into h.
202func (h *histogram) CopyFrom(other timeseries.Observable) {
203 o := other.(*histogram)
204 if o.valueCount == -1 {
205 h.allocateBuckets()
206 copy(h.buckets, o.buckets)
207 }
208 h.sum = o.sum
209 h.sumOfSquares = o.sumOfSquares
210 h.value = o.value
211 h.valueCount = o.valueCount
212}
213
214// Multiply scales the histogram by the specified ratio.
215func (h *histogram) Multiply(ratio float64) {
216 if h.valueCount == -1 {
217 for i := range h.buckets {
218 h.buckets[i] = int64(float64(h.buckets[i]) * ratio)
219 }
220 } else {
221 h.valueCount = int64(float64(h.valueCount) * ratio)
222 }
223 h.sum = int64(float64(h.sum) * ratio)
224 h.sumOfSquares = h.sumOfSquares * ratio
225}
226
227// New creates a new histogram.
228func (h *histogram) New() timeseries.Observable {
229 r := new(histogram)
230 r.Clear()
231 return r
232}
233
234func (h *histogram) String() string {
235 return fmt.Sprintf("%d, %f, %d, %d, %v",
236 h.sum, h.sumOfSquares, h.value, h.valueCount, h.buckets)
237}
238
239// round returns the closest int64 to the argument
240func round(in float64) int64 {
241 return int64(math.Floor(in + 0.5))
242}
243
244// bucketBoundary returns the first value in the bucket.
245func bucketBoundary(bucket uint8) int64 {
246 if bucket == 0 {
247 return 0
248 }
249 return 1 << bucket
250}
251
252// bucketData holds data about a specific bucket for use in distTmpl.
253type bucketData struct {
254 Lower, Upper int64
255 N int64
256 Pct, CumulativePct float64
257 GraphWidth int
258}
259
260// data holds data about a Distribution for use in distTmpl.
261type data struct {
262 Buckets []*bucketData
263 Count, Median int64
264 Mean, StandardDeviation float64
265}
266
267// maxHTMLBarWidth is the maximum width of the HTML bar for visualizing buckets.
268const maxHTMLBarWidth = 350.0
269
270// newData returns data representing h for use in distTmpl.
271func (h *histogram) newData() *data {
272 // Force the allocation of buckets to simplify the rendering implementation
273 h.allocateBuckets()
274 // We scale the bars on the right so that the largest bar is
275 // maxHTMLBarWidth pixels in width.
276 maxBucket := int64(0)
277 for _, n := range h.buckets {
278 if n > maxBucket {
279 maxBucket = n
280 }
281 }
282 total := h.total()
283 barsizeMult := maxHTMLBarWidth / float64(maxBucket)
284 var pctMult float64
285 if total == 0 {
286 pctMult = 1.0
287 } else {
288 pctMult = 100.0 / float64(total)
289 }
290
291 buckets := make([]*bucketData, len(h.buckets))
292 runningTotal := int64(0)
293 for i, n := range h.buckets {
294 if n == 0 {
295 continue
296 }
297 runningTotal += n
298 var upperBound int64
299 if i < bucketCount-1 {
300 upperBound = bucketBoundary(uint8(i + 1))
301 } else {
302 upperBound = math.MaxInt64
303 }
304 buckets[i] = &bucketData{
305 Lower: bucketBoundary(uint8(i)),
306 Upper: upperBound,
307 N: n,
308 Pct: float64(n) * pctMult,
309 CumulativePct: float64(runningTotal) * pctMult,
310 GraphWidth: int(float64(n) * barsizeMult),
311 }
312 }
313 return &data{
314 Buckets: buckets,
315 Count: total,
316 Median: h.median(),
317 Mean: h.average(),
318 StandardDeviation: h.standardDeviation(),
319 }
320}
321
322func (h *histogram) html() template.HTML {
323 buf := new(bytes.Buffer)
324 if err := distTmpl().Execute(buf, h.newData()); err != nil {
325 buf.Reset()
326 log.Printf("net/trace: couldn't execute template: %v", err)
327 }
328 return template.HTML(buf.String())
329}
330
331var distTmplCache *template.Template
332var distTmplOnce sync.Once
333
334func distTmpl() *template.Template {
335 distTmplOnce.Do(func() {
336 // Input: data
337 distTmplCache = template.Must(template.New("distTmpl").Parse(`
338<table>
339<tr>
340 <td style="padding:0.25em">Count: {{.Count}}</td>
341 <td style="padding:0.25em">Mean: {{printf "%.0f" .Mean}}</td>
342 <td style="padding:0.25em">StdDev: {{printf "%.0f" .StandardDeviation}}</td>
343 <td style="padding:0.25em">Median: {{.Median}}</td>
344</tr>
345</table>
346<hr>
347<table>
348{{range $b := .Buckets}}
349{{if $b}}
350 <tr>
351 <td style="padding:0 0 0 0.25em">[</td>
352 <td style="text-align:right;padding:0 0.25em">{{.Lower}},</td>
353 <td style="text-align:right;padding:0 0.25em">{{.Upper}})</td>
354 <td style="text-align:right;padding:0 0.25em">{{.N}}</td>
355 <td style="text-align:right;padding:0 0.25em">{{printf "%#.3f" .Pct}}%</td>
356 <td style="text-align:right;padding:0 0.25em">{{printf "%#.3f" .CumulativePct}}%</td>
357 <td><div style="background-color: blue; height: 1em; width: {{.GraphWidth}};"></div></td>
358 </tr>
359{{end}}
360{{end}}
361</table>
362`))
363 })
364 return distTmplCache
365}
diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go
new file mode 100644
index 0000000..bb72a52
--- /dev/null
+++ b/vendor/golang.org/x/net/trace/trace.go
@@ -0,0 +1,1082 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5/*
6Package trace implements tracing of requests and long-lived objects.
7It exports HTTP interfaces on /debug/requests and /debug/events.
8
9A trace.Trace provides tracing for short-lived objects, usually requests.
10A request handler might be implemented like this:
11
12 func fooHandler(w http.ResponseWriter, req *http.Request) {
13 tr := trace.New("mypkg.Foo", req.URL.Path)
14 defer tr.Finish()
15 ...
16 tr.LazyPrintf("some event %q happened", str)
17 ...
18 if err := somethingImportant(); err != nil {
19 tr.LazyPrintf("somethingImportant failed: %v", err)
20 tr.SetError()
21 }
22 }
23
24The /debug/requests HTTP endpoint organizes the traces by family,
25errors, and duration. It also provides histogram of request duration
26for each family.
27
28A trace.EventLog provides tracing for long-lived objects, such as RPC
29connections.
30
31 // A Fetcher fetches URL paths for a single domain.
32 type Fetcher struct {
33 domain string
34 events trace.EventLog
35 }
36
37 func NewFetcher(domain string) *Fetcher {
38 return &Fetcher{
39 domain,
40 trace.NewEventLog("mypkg.Fetcher", domain),
41 }
42 }
43
44 func (f *Fetcher) Fetch(path string) (string, error) {
45 resp, err := http.Get("http://" + f.domain + "/" + path)
46 if err != nil {
47 f.events.Errorf("Get(%q) = %v", path, err)
48 return "", err
49 }
50 f.events.Printf("Get(%q) = %s", path, resp.Status)
51 ...
52 }
53
54 func (f *Fetcher) Close() error {
55 f.events.Finish()
56 return nil
57 }
58
59The /debug/events HTTP endpoint organizes the event logs by family and
60by time since the last error. The expanded view displays recent log
61entries and the log's call stack.
62*/
63package trace // import "golang.org/x/net/trace"
64
65import (
66 "bytes"
67 "fmt"
68 "html/template"
69 "io"
70 "log"
71 "net"
72 "net/http"
73 "runtime"
74 "sort"
75 "strconv"
76 "sync"
77 "sync/atomic"
78 "time"
79
80 "golang.org/x/net/internal/timeseries"
81)
82
83// DebugUseAfterFinish controls whether to debug uses of Trace values after finishing.
84// FOR DEBUGGING ONLY. This will slow down the program.
85var DebugUseAfterFinish = false
86
87// AuthRequest determines whether a specific request is permitted to load the
88// /debug/requests or /debug/events pages.
89//
90// It returns two bools; the first indicates whether the page may be viewed at all,
91// and the second indicates whether sensitive events will be shown.
92//
93// AuthRequest may be replaced by a program to customize its authorization requirements.
94//
95// The default AuthRequest function returns (true, true) if and only if the request
96// comes from localhost/127.0.0.1/[::1].
97var AuthRequest = func(req *http.Request) (any, sensitive bool) {
98 // RemoteAddr is commonly in the form "IP" or "IP:port".
99 // If it is in the form "IP:port", split off the port.
100 host, _, err := net.SplitHostPort(req.RemoteAddr)
101 if err != nil {
102 host = req.RemoteAddr
103 }
104 switch host {
105 case "localhost", "127.0.0.1", "::1":
106 return true, true
107 default:
108 return false, false
109 }
110}
111
112func init() {
113 // TODO(jbd): Serve Traces from /debug/traces in the future?
114 // There is no requirement for a request to be present to have traces.
115 http.HandleFunc("/debug/requests", Traces)
116 http.HandleFunc("/debug/events", Events)
117}
118
119// Traces responds with traces from the program.
120// The package initialization registers it in http.DefaultServeMux
121// at /debug/requests.
122//
123// It performs authorization by running AuthRequest.
124func Traces(w http.ResponseWriter, req *http.Request) {
125 any, sensitive := AuthRequest(req)
126 if !any {
127 http.Error(w, "not allowed", http.StatusUnauthorized)
128 return
129 }
130 w.Header().Set("Content-Type", "text/html; charset=utf-8")
131 Render(w, req, sensitive)
132}
133
134// Events responds with a page of events collected by EventLogs.
135// The package initialization registers it in http.DefaultServeMux
136// at /debug/events.
137//
138// It performs authorization by running AuthRequest.
139func Events(w http.ResponseWriter, req *http.Request) {
140 any, sensitive := AuthRequest(req)
141 if !any {
142 http.Error(w, "not allowed", http.StatusUnauthorized)
143 return
144 }
145 w.Header().Set("Content-Type", "text/html; charset=utf-8")
146 RenderEvents(w, req, sensitive)
147}
148
149// Render renders the HTML page typically served at /debug/requests.
150// It does not do any auth checking. The request may be nil.
151//
152// Most users will use the Traces handler.
153func Render(w io.Writer, req *http.Request, sensitive bool) {
154 data := &struct {
155 Families []string
156 ActiveTraceCount map[string]int
157 CompletedTraces map[string]*family
158
159 // Set when a bucket has been selected.
160 Traces traceList
161 Family string
162 Bucket int
163 Expanded bool
164 Traced bool
165 Active bool
166 ShowSensitive bool // whether to show sensitive events
167
168 Histogram template.HTML
169 HistogramWindow string // e.g. "last minute", "last hour", "all time"
170
171 // If non-zero, the set of traces is a partial set,
172 // and this is the total number.
173 Total int
174 }{
175 CompletedTraces: completedTraces,
176 }
177
178 data.ShowSensitive = sensitive
179 if req != nil {
180 // Allow show_sensitive=0 to force hiding of sensitive data for testing.
181 // This only goes one way; you can't use show_sensitive=1 to see things.
182 if req.FormValue("show_sensitive") == "0" {
183 data.ShowSensitive = false
184 }
185
186 if exp, err := strconv.ParseBool(req.FormValue("exp")); err == nil {
187 data.Expanded = exp
188 }
189 if exp, err := strconv.ParseBool(req.FormValue("rtraced")); err == nil {
190 data.Traced = exp
191 }
192 }
193
194 completedMu.RLock()
195 data.Families = make([]string, 0, len(completedTraces))
196 for fam := range completedTraces {
197 data.Families = append(data.Families, fam)
198 }
199 completedMu.RUnlock()
200 sort.Strings(data.Families)
201
202 // We are careful here to minimize the time spent locking activeMu,
203 // since that lock is required every time an RPC starts and finishes.
204 data.ActiveTraceCount = make(map[string]int, len(data.Families))
205 activeMu.RLock()
206 for fam, s := range activeTraces {
207 data.ActiveTraceCount[fam] = s.Len()
208 }
209 activeMu.RUnlock()
210
211 var ok bool
212 data.Family, data.Bucket, ok = parseArgs(req)
213 switch {
214 case !ok:
215 // No-op
216 case data.Bucket == -1:
217 data.Active = true
218 n := data.ActiveTraceCount[data.Family]
219 data.Traces = getActiveTraces(data.Family)
220 if len(data.Traces) < n {
221 data.Total = n
222 }
223 case data.Bucket < bucketsPerFamily:
224 if b := lookupBucket(data.Family, data.Bucket); b != nil {
225 data.Traces = b.Copy(data.Traced)
226 }
227 default:
228 if f := getFamily(data.Family, false); f != nil {
229 var obs timeseries.Observable
230 f.LatencyMu.RLock()
231 switch o := data.Bucket - bucketsPerFamily; o {
232 case 0:
233 obs = f.Latency.Minute()
234 data.HistogramWindow = "last minute"
235 case 1:
236 obs = f.Latency.Hour()
237 data.HistogramWindow = "last hour"
238 case 2:
239 obs = f.Latency.Total()
240 data.HistogramWindow = "all time"
241 }
242 f.LatencyMu.RUnlock()
243 if obs != nil {
244 data.Histogram = obs.(*histogram).html()
245 }
246 }
247 }
248
249 if data.Traces != nil {
250 defer data.Traces.Free()
251 sort.Sort(data.Traces)
252 }
253
254 completedMu.RLock()
255 defer completedMu.RUnlock()
256 if err := pageTmpl().ExecuteTemplate(w, "Page", data); err != nil {
257 log.Printf("net/trace: Failed executing template: %v", err)
258 }
259}
260
261func parseArgs(req *http.Request) (fam string, b int, ok bool) {
262 if req == nil {
263 return "", 0, false
264 }
265 fam, bStr := req.FormValue("fam"), req.FormValue("b")
266 if fam == "" || bStr == "" {
267 return "", 0, false
268 }
269 b, err := strconv.Atoi(bStr)
270 if err != nil || b < -1 {
271 return "", 0, false
272 }
273
274 return fam, b, true
275}
276
277func lookupBucket(fam string, b int) *traceBucket {
278 f := getFamily(fam, false)
279 if f == nil || b < 0 || b >= len(f.Buckets) {
280 return nil
281 }
282 return f.Buckets[b]
283}
284
285type contextKeyT string
286
287var contextKey = contextKeyT("golang.org/x/net/trace.Trace")
288
289// Trace represents an active request.
290type Trace interface {
291 // LazyLog adds x to the event log. It will be evaluated each time the
292 // /debug/requests page is rendered. Any memory referenced by x will be
293 // pinned until the trace is finished and later discarded.
294 LazyLog(x fmt.Stringer, sensitive bool)
295
296 // LazyPrintf evaluates its arguments with fmt.Sprintf each time the
297 // /debug/requests page is rendered. Any memory referenced by a will be
298 // pinned until the trace is finished and later discarded.
299 LazyPrintf(format string, a ...interface{})
300
301 // SetError declares that this trace resulted in an error.
302 SetError()
303
304 // SetRecycler sets a recycler for the trace.
305 // f will be called for each event passed to LazyLog at a time when
306 // it is no longer required, whether while the trace is still active
307 // and the event is discarded, or when a completed trace is discarded.
308 SetRecycler(f func(interface{}))
309
310 // SetTraceInfo sets the trace info for the trace.
311 // This is currently unused.
312 SetTraceInfo(traceID, spanID uint64)
313
314 // SetMaxEvents sets the maximum number of events that will be stored
315 // in the trace. This has no effect if any events have already been
316 // added to the trace.
317 SetMaxEvents(m int)
318
319 // Finish declares that this trace is complete.
320 // The trace should not be used after calling this method.
321 Finish()
322}
323
324type lazySprintf struct {
325 format string
326 a []interface{}
327}
328
329func (l *lazySprintf) String() string {
330 return fmt.Sprintf(l.format, l.a...)
331}
332
333// New returns a new Trace with the specified family and title.
334func New(family, title string) Trace {
335 tr := newTrace()
336 tr.ref()
337 tr.Family, tr.Title = family, title
338 tr.Start = time.Now()
339 tr.maxEvents = maxEventsPerTrace
340 tr.events = tr.eventsBuf[:0]
341
342 activeMu.RLock()
343 s := activeTraces[tr.Family]
344 activeMu.RUnlock()
345 if s == nil {
346 activeMu.Lock()
347 s = activeTraces[tr.Family] // check again
348 if s == nil {
349 s = new(traceSet)
350 activeTraces[tr.Family] = s
351 }
352 activeMu.Unlock()
353 }
354 s.Add(tr)
355
356 // Trigger allocation of the completed trace structure for this family.
357 // This will cause the family to be present in the request page during
358 // the first trace of this family. We don't care about the return value,
359 // nor is there any need for this to run inline, so we execute it in its
360 // own goroutine, but only if the family isn't allocated yet.
361 completedMu.RLock()
362 if _, ok := completedTraces[tr.Family]; !ok {
363 go allocFamily(tr.Family)
364 }
365 completedMu.RUnlock()
366
367 return tr
368}
369
370func (tr *trace) Finish() {
371 tr.Elapsed = time.Now().Sub(tr.Start)
372 if DebugUseAfterFinish {
373 buf := make([]byte, 4<<10) // 4 KB should be enough
374 n := runtime.Stack(buf, false)
375 tr.finishStack = buf[:n]
376 }
377
378 activeMu.RLock()
379 m := activeTraces[tr.Family]
380 activeMu.RUnlock()
381 m.Remove(tr)
382
383 f := getFamily(tr.Family, true)
384 for _, b := range f.Buckets {
385 if b.Cond.match(tr) {
386 b.Add(tr)
387 }
388 }
389 // Add a sample of elapsed time as microseconds to the family's timeseries
390 h := new(histogram)
391 h.addMeasurement(tr.Elapsed.Nanoseconds() / 1e3)
392 f.LatencyMu.Lock()
393 f.Latency.Add(h)
394 f.LatencyMu.Unlock()
395
396 tr.unref() // matches ref in New
397}
398
399const (
400 bucketsPerFamily = 9
401 tracesPerBucket = 10
402 maxActiveTraces = 20 // Maximum number of active traces to show.
403 maxEventsPerTrace = 10
404 numHistogramBuckets = 38
405)
406
407var (
408 // The active traces.
409 activeMu sync.RWMutex
410 activeTraces = make(map[string]*traceSet) // family -> traces
411
412 // Families of completed traces.
413 completedMu sync.RWMutex
414 completedTraces = make(map[string]*family) // family -> traces
415)
416
417type traceSet struct {
418 mu sync.RWMutex
419 m map[*trace]bool
420
421 // We could avoid the entire map scan in FirstN by having a slice of all the traces
422 // ordered by start time, and an index into that from the trace struct, with a periodic
423 // repack of the slice after enough traces finish; we could also use a skip list or similar.
424 // However, that would shift some of the expense from /debug/requests time to RPC time,
425 // which is probably the wrong trade-off.
426}
427
428func (ts *traceSet) Len() int {
429 ts.mu.RLock()
430 defer ts.mu.RUnlock()
431 return len(ts.m)
432}
433
434func (ts *traceSet) Add(tr *trace) {
435 ts.mu.Lock()
436 if ts.m == nil {
437 ts.m = make(map[*trace]bool)
438 }
439 ts.m[tr] = true
440 ts.mu.Unlock()
441}
442
443func (ts *traceSet) Remove(tr *trace) {
444 ts.mu.Lock()
445 delete(ts.m, tr)
446 ts.mu.Unlock()
447}
448
449// FirstN returns the first n traces ordered by time.
450func (ts *traceSet) FirstN(n int) traceList {
451 ts.mu.RLock()
452 defer ts.mu.RUnlock()
453
454 if n > len(ts.m) {
455 n = len(ts.m)
456 }
457 trl := make(traceList, 0, n)
458
459 // Fast path for when no selectivity is needed.
460 if n == len(ts.m) {
461 for tr := range ts.m {
462 tr.ref()
463 trl = append(trl, tr)
464 }
465 sort.Sort(trl)
466 return trl
467 }
468
469 // Pick the oldest n traces.
470 // This is inefficient. See the comment in the traceSet struct.
471 for tr := range ts.m {
472 // Put the first n traces into trl in the order they occur.
473 // When we have n, sort trl, and thereafter maintain its order.
474 if len(trl) < n {
475 tr.ref()
476 trl = append(trl, tr)
477 if len(trl) == n {
478 // This is guaranteed to happen exactly once during this loop.
479 sort.Sort(trl)
480 }
481 continue
482 }
483 if tr.Start.After(trl[n-1].Start) {
484 continue
485 }
486
487 // Find where to insert this one.
488 tr.ref()
489 i := sort.Search(n, func(i int) bool { return trl[i].Start.After(tr.Start) })
490 trl[n-1].unref()
491 copy(trl[i+1:], trl[i:])
492 trl[i] = tr
493 }
494
495 return trl
496}
497
498func getActiveTraces(fam string) traceList {
499 activeMu.RLock()
500 s := activeTraces[fam]
501 activeMu.RUnlock()
502 if s == nil {
503 return nil
504 }
505 return s.FirstN(maxActiveTraces)
506}
507
508func getFamily(fam string, allocNew bool) *family {
509 completedMu.RLock()
510 f := completedTraces[fam]
511 completedMu.RUnlock()
512 if f == nil && allocNew {
513 f = allocFamily(fam)
514 }
515 return f
516}
517
518func allocFamily(fam string) *family {
519 completedMu.Lock()
520 defer completedMu.Unlock()
521 f := completedTraces[fam]
522 if f == nil {
523 f = newFamily()
524 completedTraces[fam] = f
525 }
526 return f
527}
528
529// family represents a set of trace buckets and associated latency information.
530type family struct {
531 // traces may occur in multiple buckets.
532 Buckets [bucketsPerFamily]*traceBucket
533
534 // latency time series
535 LatencyMu sync.RWMutex
536 Latency *timeseries.MinuteHourSeries
537}
538
539func newFamily() *family {
540 return &family{
541 Buckets: [bucketsPerFamily]*traceBucket{
542 {Cond: minCond(0)},
543 {Cond: minCond(50 * time.Millisecond)},
544 {Cond: minCond(100 * time.Millisecond)},
545 {Cond: minCond(200 * time.Millisecond)},
546 {Cond: minCond(500 * time.Millisecond)},
547 {Cond: minCond(1 * time.Second)},
548 {Cond: minCond(10 * time.Second)},
549 {Cond: minCond(100 * time.Second)},
550 {Cond: errorCond{}},
551 },
552 Latency: timeseries.NewMinuteHourSeries(func() timeseries.Observable { return new(histogram) }),
553 }
554}
555
556// traceBucket represents a size-capped bucket of historic traces,
557// along with a condition for a trace to belong to the bucket.
558type traceBucket struct {
559 Cond cond
560
561 // Ring buffer implementation of a fixed-size FIFO queue.
562 mu sync.RWMutex
563 buf [tracesPerBucket]*trace
564 start int // < tracesPerBucket
565 length int // <= tracesPerBucket
566}
567
568func (b *traceBucket) Add(tr *trace) {
569 b.mu.Lock()
570 defer b.mu.Unlock()
571
572 i := b.start + b.length
573 if i >= tracesPerBucket {
574 i -= tracesPerBucket
575 }
576 if b.length == tracesPerBucket {
577 // "Remove" an element from the bucket.
578 b.buf[i].unref()
579 b.start++
580 if b.start == tracesPerBucket {
581 b.start = 0
582 }
583 }
584 b.buf[i] = tr
585 if b.length < tracesPerBucket {
586 b.length++
587 }
588 tr.ref()
589}
590
591// Copy returns a copy of the traces in the bucket.
592// If tracedOnly is true, only the traces with trace information will be returned.
593// The logs will be ref'd before returning; the caller should call
594// the Free method when it is done with them.
595// TODO(dsymonds): keep track of traced requests in separate buckets.
596func (b *traceBucket) Copy(tracedOnly bool) traceList {
597 b.mu.RLock()
598 defer b.mu.RUnlock()
599
600 trl := make(traceList, 0, b.length)
601 for i, x := 0, b.start; i < b.length; i++ {
602 tr := b.buf[x]
603 if !tracedOnly || tr.spanID != 0 {
604 tr.ref()
605 trl = append(trl, tr)
606 }
607 x++
608 if x == b.length {
609 x = 0
610 }
611 }
612 return trl
613}
614
615func (b *traceBucket) Empty() bool {
616 b.mu.RLock()
617 defer b.mu.RUnlock()
618 return b.length == 0
619}
620
621// cond represents a condition on a trace.
622type cond interface {
623 match(t *trace) bool
624 String() string
625}
626
627type minCond time.Duration
628
629func (m minCond) match(t *trace) bool { return t.Elapsed >= time.Duration(m) }
630func (m minCond) String() string { return fmt.Sprintf("≥%gs", time.Duration(m).Seconds()) }
631
632type errorCond struct{}
633
634func (e errorCond) match(t *trace) bool { return t.IsError }
635func (e errorCond) String() string { return "errors" }
636
637type traceList []*trace
638
639// Free calls unref on each element of the list.
640func (trl traceList) Free() {
641 for _, t := range trl {
642 t.unref()
643 }
644}
645
646// traceList may be sorted in reverse chronological order.
647func (trl traceList) Len() int { return len(trl) }
648func (trl traceList) Less(i, j int) bool { return trl[i].Start.After(trl[j].Start) }
649func (trl traceList) Swap(i, j int) { trl[i], trl[j] = trl[j], trl[i] }
650
651// An event is a timestamped log entry in a trace.
652type event struct {
653 When time.Time
654 Elapsed time.Duration // since previous event in trace
655 NewDay bool // whether this event is on a different day to the previous event
656 Recyclable bool // whether this event was passed via LazyLog
657 Sensitive bool // whether this event contains sensitive information
658 What interface{} // string or fmt.Stringer
659}
660
661// WhenString returns a string representation of the elapsed time of the event.
662// It will include the date if midnight was crossed.
663func (e event) WhenString() string {
664 if e.NewDay {
665 return e.When.Format("2006/01/02 15:04:05.000000")
666 }
667 return e.When.Format("15:04:05.000000")
668}
669
670// discarded represents a number of discarded events.
671// It is stored as *discarded to make it easier to update in-place.
672type discarded int
673
674func (d *discarded) String() string {
675 return fmt.Sprintf("(%d events discarded)", int(*d))
676}
677
678// trace represents an active or complete request,
679// either sent or received by this program.
680type trace struct {
681 // Family is the top-level grouping of traces to which this belongs.
682 Family string
683
684 // Title is the title of this trace.
685 Title string
686
687 // Timing information.
688 Start time.Time
689 Elapsed time.Duration // zero while active
690
691 // Trace information if non-zero.
692 traceID uint64
693 spanID uint64
694
695 // Whether this trace resulted in an error.
696 IsError bool
697
698 // Append-only sequence of events (modulo discards).
699 mu sync.RWMutex
700 events []event
701 maxEvents int
702
703 refs int32 // how many buckets this is in
704 recycler func(interface{})
705 disc discarded // scratch space to avoid allocation
706
707 finishStack []byte // where finish was called, if DebugUseAfterFinish is set
708
709 eventsBuf [4]event // preallocated buffer in case we only log a few events
710}
711
712func (tr *trace) reset() {
713 // Clear all but the mutex. Mutexes may not be copied, even when unlocked.
714 tr.Family = ""
715 tr.Title = ""
716 tr.Start = time.Time{}
717 tr.Elapsed = 0
718 tr.traceID = 0
719 tr.spanID = 0
720 tr.IsError = false
721 tr.maxEvents = 0
722 tr.events = nil
723 tr.refs = 0
724 tr.recycler = nil
725 tr.disc = 0
726 tr.finishStack = nil
727 for i := range tr.eventsBuf {
728 tr.eventsBuf[i] = event{}
729 }
730}
731
732// delta returns the elapsed time since the last event or the trace start,
733// and whether it spans midnight.
734// L >= tr.mu
735func (tr *trace) delta(t time.Time) (time.Duration, bool) {
736 if len(tr.events) == 0 {
737 return t.Sub(tr.Start), false
738 }
739 prev := tr.events[len(tr.events)-1].When
740 return t.Sub(prev), prev.Day() != t.Day()
741}
742
743func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) {
744 if DebugUseAfterFinish && tr.finishStack != nil {
745 buf := make([]byte, 4<<10) // 4 KB should be enough
746 n := runtime.Stack(buf, false)
747 log.Printf("net/trace: trace used after finish:\nFinished at:\n%s\nUsed at:\n%s", tr.finishStack, buf[:n])
748 }
749
750 /*
751 NOTE TO DEBUGGERS
752
753 If you are here because your program panicked in this code,
754 it is almost definitely the fault of code using this package,
755 and very unlikely to be the fault of this code.
756
757 The most likely scenario is that some code elsewhere is using
758 a trace.Trace after its Finish method is called.
759 You can temporarily set the DebugUseAfterFinish var
760 to help discover where that is; do not leave that var set,
761 since it makes this package much less efficient.
762 */
763
764 e := event{When: time.Now(), What: x, Recyclable: recyclable, Sensitive: sensitive}
765 tr.mu.Lock()
766 e.Elapsed, e.NewDay = tr.delta(e.When)
767 if len(tr.events) < tr.maxEvents {
768 tr.events = append(tr.events, e)
769 } else {
770 // Discard the middle events.
771 di := int((tr.maxEvents - 1) / 2)
772 if d, ok := tr.events[di].What.(*discarded); ok {
773 (*d)++
774 } else {
775 // disc starts at two to count for the event it is replacing,
776 // plus the next one that we are about to drop.
777 tr.disc = 2
778 if tr.recycler != nil && tr.events[di].Recyclable {
779 go tr.recycler(tr.events[di].What)
780 }
781 tr.events[di].What = &tr.disc
782 }
783 // The timestamp of the discarded meta-event should be
784 // the time of the last event it is representing.
785 tr.events[di].When = tr.events[di+1].When
786
787 if tr.recycler != nil && tr.events[di+1].Recyclable {
788 go tr.recycler(tr.events[di+1].What)
789 }
790 copy(tr.events[di+1:], tr.events[di+2:])
791 tr.events[tr.maxEvents-1] = e
792 }
793 tr.mu.Unlock()
794}
795
796func (tr *trace) LazyLog(x fmt.Stringer, sensitive bool) {
797 tr.addEvent(x, true, sensitive)
798}
799
800func (tr *trace) LazyPrintf(format string, a ...interface{}) {
801 tr.addEvent(&lazySprintf{format, a}, false, false)
802}
803
804func (tr *trace) SetError() { tr.IsError = true }
805
806func (tr *trace) SetRecycler(f func(interface{})) {
807 tr.recycler = f
808}
809
810func (tr *trace) SetTraceInfo(traceID, spanID uint64) {
811 tr.traceID, tr.spanID = traceID, spanID
812}
813
814func (tr *trace) SetMaxEvents(m int) {
815 // Always keep at least three events: first, discarded count, last.
816 if len(tr.events) == 0 && m > 3 {
817 tr.maxEvents = m
818 }
819}
820
821func (tr *trace) ref() {
822 atomic.AddInt32(&tr.refs, 1)
823}
824
825func (tr *trace) unref() {
826 if atomic.AddInt32(&tr.refs, -1) == 0 {
827 if tr.recycler != nil {
828 // freeTrace clears tr, so we hold tr.recycler and tr.events here.
829 go func(f func(interface{}), es []event) {
830 for _, e := range es {
831 if e.Recyclable {
832 f(e.What)
833 }
834 }
835 }(tr.recycler, tr.events)
836 }
837
838 freeTrace(tr)
839 }
840}
841
842func (tr *trace) When() string {
843 return tr.Start.Format("2006/01/02 15:04:05.000000")
844}
845
846func (tr *trace) ElapsedTime() string {
847 t := tr.Elapsed
848 if t == 0 {
849 // Active trace.
850 t = time.Since(tr.Start)
851 }
852 return fmt.Sprintf("%.6f", t.Seconds())
853}
854
855func (tr *trace) Events() []event {
856 tr.mu.RLock()
857 defer tr.mu.RUnlock()
858 return tr.events
859}
860
861var traceFreeList = make(chan *trace, 1000) // TODO(dsymonds): Use sync.Pool?
862
863// newTrace returns a trace ready to use.
864func newTrace() *trace {
865 select {
866 case tr := <-traceFreeList:
867 return tr
868 default:
869 return new(trace)
870 }
871}
872
873// freeTrace adds tr to traceFreeList if there's room.
874// This is non-blocking.
875func freeTrace(tr *trace) {
876 if DebugUseAfterFinish {
877 return // never reuse
878 }
879 tr.reset()
880 select {
881 case traceFreeList <- tr:
882 default:
883 }
884}
885
886func elapsed(d time.Duration) string {
887 b := []byte(fmt.Sprintf("%.6f", d.Seconds()))
888
889 // For subsecond durations, blank all zeros before decimal point,
890 // and all zeros between the decimal point and the first non-zero digit.
891 if d < time.Second {
892 dot := bytes.IndexByte(b, '.')
893 for i := 0; i < dot; i++ {
894 b[i] = ' '
895 }
896 for i := dot + 1; i < len(b); i++ {
897 if b[i] == '0' {
898 b[i] = ' '
899 } else {
900 break
901 }
902 }
903 }
904
905 return string(b)
906}
907
908var pageTmplCache *template.Template
909var pageTmplOnce sync.Once
910
911func pageTmpl() *template.Template {
912 pageTmplOnce.Do(func() {
913 pageTmplCache = template.Must(template.New("Page").Funcs(template.FuncMap{
914 "elapsed": elapsed,
915 "add": func(a, b int) int { return a + b },
916 }).Parse(pageHTML))
917 })
918 return pageTmplCache
919}
920
921const pageHTML = `
922{{template "Prolog" .}}
923{{template "StatusTable" .}}
924{{template "Epilog" .}}
925
926{{define "Prolog"}}
927<html>
928 <head>
929 <title>/debug/requests</title>
930 <style type="text/css">
931 body {
932 font-family: sans-serif;
933 }
934 table#tr-status td.family {
935 padding-right: 2em;
936 }
937 table#tr-status td.active {
938 padding-right: 1em;
939 }
940 table#tr-status td.latency-first {
941 padding-left: 1em;
942 }
943 table#tr-status td.empty {
944 color: #aaa;
945 }
946 table#reqs {
947 margin-top: 1em;
948 }
949 table#reqs tr.first {
950 {{if $.Expanded}}font-weight: bold;{{end}}
951 }
952 table#reqs td {
953 font-family: monospace;
954 }
955 table#reqs td.when {
956 text-align: right;
957 white-space: nowrap;
958 }
959 table#reqs td.elapsed {
960 padding: 0 0.5em;
961 text-align: right;
962 white-space: pre;
963 width: 10em;
964 }
965 address {
966 font-size: smaller;
967 margin-top: 5em;
968 }
969 </style>
970 </head>
971 <body>
972
973<h1>/debug/requests</h1>
974{{end}} {{/* end of Prolog */}}
975
976{{define "StatusTable"}}
977<table id="tr-status">
978 {{range $fam := .Families}}
979 <tr>
980 <td class="family">{{$fam}}</td>
981
982 {{$n := index $.ActiveTraceCount $fam}}
983 <td class="active {{if not $n}}empty{{end}}">
984 {{if $n}}<a href="?fam={{$fam}}&b=-1{{if $.Expanded}}&exp=1{{end}}">{{end}}
985 [{{$n}} active]
986 {{if $n}}</a>{{end}}
987 </td>
988
989 {{$f := index $.CompletedTraces $fam}}
990 {{range $i, $b := $f.Buckets}}
991 {{$empty := $b.Empty}}
992 <td {{if $empty}}class="empty"{{end}}>
993 {{if not $empty}}<a href="?fam={{$fam}}&b={{$i}}{{if $.Expanded}}&exp=1{{end}}">{{end}}
994 [{{.Cond}}]
995 {{if not $empty}}</a>{{end}}
996 </td>
997 {{end}}
998
999 {{$nb := len $f.Buckets}}
1000 <td class="latency-first">
1001 <a href="?fam={{$fam}}&b={{$nb}}">[minute]</a>
1002 </td>
1003 <td>
1004 <a href="?fam={{$fam}}&b={{add $nb 1}}">[hour]</a>
1005 </td>
1006 <td>
1007 <a href="?fam={{$fam}}&b={{add $nb 2}}">[total]</a>
1008 </td>
1009
1010 </tr>
1011 {{end}}
1012</table>
1013{{end}} {{/* end of StatusTable */}}
1014
1015{{define "Epilog"}}
1016{{if $.Traces}}
1017<hr />
1018<h3>Family: {{$.Family}}</h3>
1019
1020{{if or $.Expanded $.Traced}}
1021 <a href="?fam={{$.Family}}&b={{$.Bucket}}">[Normal/Summary]</a>
1022{{else}}
1023 [Normal/Summary]
1024{{end}}
1025
1026{{if or (not $.Expanded) $.Traced}}
1027 <a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1">[Normal/Expanded]</a>
1028{{else}}
1029 [Normal/Expanded]
1030{{end}}
1031
1032{{if not $.Active}}
1033 {{if or $.Expanded (not $.Traced)}}
1034 <a href="?fam={{$.Family}}&b={{$.Bucket}}&rtraced=1">[Traced/Summary]</a>
1035 {{else}}
1036 [Traced/Summary]
1037 {{end}}
1038 {{if or (not $.Expanded) (not $.Traced)}}
1039 <a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1&rtraced=1">[Traced/Expanded]</a>
1040 {{else}}
1041 [Traced/Expanded]
1042 {{end}}
1043{{end}}
1044
1045{{if $.Total}}
1046<p><em>Showing <b>{{len $.Traces}}</b> of <b>{{$.Total}}</b> traces.</em></p>
1047{{end}}
1048
1049<table id="reqs">
1050 <caption>
1051 {{if $.Active}}Active{{else}}Completed{{end}} Requests
1052 </caption>
1053 <tr><th>When</th><th>Elapsed&nbsp;(s)</th></tr>
1054 {{range $tr := $.Traces}}
1055 <tr class="first">
1056 <td class="when">{{$tr.When}}</td>
1057 <td class="elapsed">{{$tr.ElapsedTime}}</td>
1058 <td>{{$tr.Title}}</td>
1059 {{/* TODO: include traceID/spanID */}}
1060 </tr>
1061 {{if $.Expanded}}
1062 {{range $tr.Events}}
1063 <tr>
1064 <td class="when">{{.WhenString}}</td>
1065 <td class="elapsed">{{elapsed .Elapsed}}</td>
1066 <td>{{if or $.ShowSensitive (not .Sensitive)}}... {{.What}}{{else}}<em>[redacted]</em>{{end}}</td>
1067 </tr>
1068 {{end}}
1069 {{end}}
1070 {{end}}
1071</table>
1072{{end}} {{/* if $.Traces */}}
1073
1074{{if $.Histogram}}
1075<h4>Latency (&micro;s) of {{$.Family}} over {{$.HistogramWindow}}</h4>
1076{{$.Histogram}}
1077{{end}} {{/* if $.Histogram */}}
1078
1079 </body>
1080</html>
1081{{end}} {{/* end of Epilog */}}
1082`
diff --git a/vendor/golang.org/x/net/trace/trace_go16.go b/vendor/golang.org/x/net/trace/trace_go16.go
new file mode 100644
index 0000000..d608191
--- /dev/null
+++ b/vendor/golang.org/x/net/trace/trace_go16.go
@@ -0,0 +1,21 @@
1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build !go1.7
6
7package trace
8
9import "golang.org/x/net/context"
10
11// NewContext returns a copy of the parent context
12// and associates it with a Trace.
13func NewContext(ctx context.Context, tr Trace) context.Context {
14 return context.WithValue(ctx, contextKey, tr)
15}
16
17// FromContext returns the Trace bound to the context, if any.
18func FromContext(ctx context.Context) (tr Trace, ok bool) {
19 tr, ok = ctx.Value(contextKey).(Trace)
20 return
21}
diff --git a/vendor/golang.org/x/net/trace/trace_go17.go b/vendor/golang.org/x/net/trace/trace_go17.go
new file mode 100644
index 0000000..df6e1fb
--- /dev/null
+++ b/vendor/golang.org/x/net/trace/trace_go17.go
@@ -0,0 +1,21 @@
1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build go1.7
6
7package trace
8
9import "context"
10
11// NewContext returns a copy of the parent context
12// and associates it with a Trace.
13func NewContext(ctx context.Context, tr Trace) context.Context {
14 return context.WithValue(ctx, contextKey, tr)
15}
16
17// FromContext returns the Trace bound to the context, if any.
18func FromContext(ctx context.Context) (tr Trace, ok bool) {
19 tr, ok = ctx.Value(contextKey).(Trace)
20 return
21}