diff --git a/go.mod b/go.mod index 4c2b1aaa5a35752e66fbe60393d2dc410a819044..ce5374d5a4fa1c3ed97e4223eb1e6860ffc31c28 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/lpar/gzipped v1.1.1-0.20190413023519-5d9a18ea7f47 github.com/miekg/dns v1.1.38 github.com/prometheus/client_golang v1.9.0 + github.com/prometheus/common v0.15.0 go.etcd.io/etcd v0.5.0-alpha.5.0.20190401205724-a621d807f061 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/sync v0.0.0-20201207232520-09787c993a3a diff --git a/go.sum b/go.sum index 2c5c8c35cc8fe0d7e13eca1d2f26a612e5685844..fb30c311a4d7a062df8ddb7e0b47d2059900c8ae 100644 --- a/go.sum +++ b/go.sum @@ -167,6 +167,7 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -207,8 +208,10 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= diff --git a/node/Makefile b/node/Makefile index 3985b0a4d815e598a3c31fadd2bbad60b879dd56..be2ea26c442d1a99ae360f3e1e5852a7607c8411 100644 --- a/node/Makefile +++ b/node/Makefile @@ -2,10 +2,12 @@ SOURCES = \ static/css/style.css \ static/css/player.css \ static/css/bootstrap.min.css \ + static/css/uPlot.min.css \ static/js/bootstrap.bundle.min.js \ static/js/jquery-3.5.1.slim.min.js \ static/js/autoradio.js \ static/js/player.js \ + static/js/uPlot.iife.min.js \ static/autoradio.svg \ static/speaker.svg @@ -15,6 +17,7 @@ COMPRESSED = \ %.br: % brotli --best --output=$@ --force $^ + touch $@ %.gz: % zopfli $^ diff --git a/node/bindata.go b/node/bindata.go index 5050cd98889e50eb093aaf5ef58821f7abcafb0a..483599a03886a389a136b3b56e81664cc1796921 100644 --- a/node/bindata.go +++ b/node/bindata.go @@ -12,6 +12,9 @@ // static/css/style.css // static/css/style.css.br // static/css/style.css.gz +// static/css/uPlot.min.css +// static/css/uPlot.min.css.br +// static/css/uPlot.min.css.gz // static/favicon.ico // static/js/autoradio.js // static/js/autoradio.js.br @@ -25,6 +28,9 @@ // static/js/player.js // static/js/player.js.br // static/js/player.js.gz +// static/js/uPlot.iife.min.js +// static/js/uPlot.iife.min.js.br +// static/js/uPlot.iife.min.js.gz // static/radio52.png // static/speaker.svg // static/speaker.svg.br @@ -380,7 +386,7 @@ func staticCssPlayerCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/css/player.css", size: 3355, mode: os.FileMode(420), modTime: time.Unix(1612343832, 0)} + info := bindataFileInfo{name: "static/css/player.css", size: 3355, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -397,7 +403,7 @@ func staticCssPlayerCssBr() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/css/player.css.br", size: 695, mode: os.FileMode(420), modTime: time.Unix(1612345238, 0)} + info := bindataFileInfo{name: "static/css/player.css.br", size: 695, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -414,7 +420,7 @@ func staticCssPlayerCssGz() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/css/player.css.gz", size: 815, mode: os.FileMode(420), modTime: time.Unix(1612344943, 0)} + info := bindataFileInfo{name: "static/css/player.css.gz", size: 815, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -527,6 +533,57 @@ func staticCssStyleCssGz() (*asset, error) { return a, nil } +var _staticCssUplotMinCss = []byte(`.uplot, .uplot *, .uplot *::before, .uplot *::after {box-sizing: border-box;}.uplot {font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";line-height: 1.5;width: min-content;}.u-title {text-align: center;font-size: 18px;font-weight: bold;}.u-wrap {position: relative;user-select: none;}.u-over, .u-under {position: absolute;}.u-under {overflow: hidden;}.uplot canvas {display: block;position: relative;width: 100%;height: 100%;}.u-legend {font-size: 14px;margin: auto;text-align: center;}.u-inline {display: block;}.u-inline * {display: inline-block;}.u-inline tr {margin-right: 16px;}.u-legend th {font-weight: 600;}.u-legend th > * {vertical-align: middle;display: inline-block;}.u-legend .u-marker {width: 1em;height: 1em;margin-right: 4px;background-clip: content-box !important;}.u-inline.u-live th::after {content: ":";vertical-align: middle;}.u-inline:not(.u-live) .u-value {display: none;}.u-series > * {padding: 4px;}.u-series th {cursor: pointer;}.u-legend .u-off > * {opacity: 0.3;}.u-select {background: rgba(0,0,0,0.07);position: absolute;pointer-events: none;}.u-cursor-x, .u-cursor-y {position: absolute;left: 0;top: 0;pointer-events: none;will-change: transform;z-index: 100;}.u-hz .u-cursor-x, .u-vt .u-cursor-y {height: 100%;border-right: 1px dashed #607D8B;}.u-hz .u-cursor-y, .u-vt .u-cursor-x {width: 100%;border-bottom: 1px dashed #607D8B;}.u-cursor-pt {position: absolute;top: 0;left: 0;border-radius: 50%;pointer-events: none;will-change: transform;z-index: 100;/*this has to be !important since we set inline "background" shorthand */background-clip: content-box !important;}.u-select.u-off, .u-cursor-x.u-off, .u-cursor-y.u-off, .u-cursor-pt.u-off {display: none;}`) + +func staticCssUplotMinCssBytes() ([]byte, error) { + return _staticCssUplotMinCss, nil +} + +func staticCssUplotMinCss() (*asset, error) { + bytes, err := staticCssUplotMinCssBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "static/css/uPlot.min.css", size: 1823, mode: os.FileMode(420), modTime: time.Unix(1612357228, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _staticCssUplotMinCssBr = []byte("\xb1\xf08\x00`\xa4t\xf9\xa0\xed\\\xae^\xdf\xc9\xec\x9d3k\x02'\xa2\xf9W\xa8\x18\xa4\xa5J\x82\xb8\xf5\xf9}kj\xa3}\xac\xba?s\xb7a\xb2\x80*y~!\xcc*\xd1TT\xb5\xf5\x02\x8d\xa9\x8a:7\xfe\n\xe88\xaa\xa5t\x04\xb1q\xfd\xa0N\xae\x16\xe0\xe4\x9c\xe0<\x03\xcaPJ\xb9\x06\xd6U]`5\xe2\"\xe4\x12\xf1\xd21)\x9ex\xc8J\v'\xd6Bu\xcc\x10n\x01\xda}\xce\xe0\xaf\f\x95\x84\xffgd/\xf7\xecU\xe7\xff\xf1$\xb3F\x9a\xd8s\xe0C\xd6\x12\x19\\\x97\xb1\x931\xf8\xa1\x8c\x82_\xa7\xa8\x90\xc1\xe3Xcxm\x98\x1e\n\xfd\xec}\xae\x92\x18\u035b\x86\xf2\x1f3\xc26\xab\xce<$4\xb18\x1b\xafD\x01V\xcc\xe3\x82@CV\xfd$\xb0\xe3,\x92\xcaB\x02\x11\f\xc8\xc3\xc63m\xe9h\xb0\xd4\x12\xc1\x83%\x1b\xa0p\x8aq\x81N\xb3\xe0\xc1\x9bV\x0f\x15\x06\xe3\xec\xf2\x1cx\nQ\xa4q\x80\x89\x85\xf3!\xcf)\x1a\xa7\x02\x1b-&W$-\v\xed\x13\x87\a )\xf1\xa4\xf6\xf2\xda1)\xa0x\x88\f1\xcb\x04\x0f\xe6g\xdek\xddPF\x0f\x9e\x9cUF\xc8\xd3]\x9a\x12\xac\xa6\xf9f\x9c\x97\x1d\xbc4\x11X\xf8O\xad\xa7\xd3i|\x17\xc9\u9900\xe9;^x\xa1\u0630\xfa\xc05@\xee\xe0\x95\x96\xf9\x01\xfd\x1a\x1f\x87\x97\xbc\xf4Q\x89\x12\xe2\xaa\n\x02)\xf4\x942k\xf5\xa0\xf4N\x9b\x88\u007f\xf6|\xef\xc0!G\x91\x03\xd9H\x93\xa7\u0311%\u07f1\xe3$\x02\x02e9\xccXF\x18\x18GF\xe1\xb92\x01\x80\xd5=j\u07b9\xc1X\x83KA\x05A\x1dPEC\x9d\x9b\x8e\x17\xd3q\\+\x97\xb6Z\xcb\xd0u\x8e\xa6\xacym<\xdd\x1c\x8b\u0636\xd3\n\x90b\xc9N\xb33g\xd41\x03\xc6\xf7\xf4\xa0\xf5\xbb\xdaT\x18\xa5;\xcdV\xa1\xbb\x01R\xc84'\xab!!\x9c \x00\x1dNF\x03\xa4\xbf\xa21^\xa8\x9ca\x89\x14\x91\xfa7\xba\x03\u07e9\"\xe9\xc3h=\xdd\xdcmo\f\xbb\xe9]\x9dBJ\x8d\x8c\x9b\xb7\xd2\xfc\xeb\xb5\xc1\x85\xf1\x10\xf08\xae~A\x8e\x1f\xd7\x15\xb7\x9a\xeeC\x15\x9b\x9c\xac\xb3\x0eG/\xfc\xb3\xe8\xca\xf0\xa6\v\xd4m\xad\x84J\x9a\x9b\x00\x060,\xfcx\x036\xd6iwv2\xe1\f\x87\x18G\xe1\x10\x83o\xf4x\xb0\x9b>\xa8\xe7\u0593\x03") + +func staticCssUplotMinCssBrBytes() ([]byte, error) { + return _staticCssUplotMinCssBr, nil +} + +func staticCssUplotMinCssBr() (*asset, error) { + bytes, err := staticCssUplotMinCssBrBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "static/css/uPlot.min.css.br", size: 597, mode: os.FileMode(420), modTime: time.Unix(1612357325, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _staticCssUplotMinCssGz = []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x02\x03\xd2+\x05tR\x1d\u06ad\xdb0\xf4W\u0437\x87\x99\xb7G\xa4\xee\xbdw?\x80\x92 \x89\rE\xe8\x90\xf0\x8aO\xff\xbd`\xc4\xc4\xf4\xeax\x89'\xe6\xc5\u0145GK<\x83\xe9\x1d\x1em?\x15E\x85-y\xcc-\xbae\xf4\xb0\xa9h\xa5\x82\xb94\xae+\xa0\"\u07e0Wb*\xffJ\x81\x9b\x96\x1c\xabV\x0f\u01ae\v\b\xeb\xc08\xa8\xb9\x99\x81\xd2\xe3hQM\x96\x19\xdc\xfa\r;B\xf8\xe3\x9b[3\xf8\x95*b\x12\xdb\xd7h\x17\u0226\xd6\xf0#\xceQ<\x9fx\xa3\xad8~\x14?\xfc\xa6]\x10[\x907\x15\u041bV\x1c\x9f\u0122\xf0\x19Y\xf2\xf0\xc5@\u007f\x9a[Y\xe9#\x96\xdf\xd6CE\xf6\xd6u\xc9<\xb1\xb4\u01a1\xea\xd1t=\x17\xf0\xec\xecU\xb94\r\xf7\x05\f\u01a9Z\xa6B\xc7qL\u0146\xa5\xe7\x86q\xc5J[\u04f9\x02j\xf1\xa1/\xe3\xec\x91\x1c\x94\xfc\xb7\xe3j\xfa\xbeL\x15\xa5os\x95\xbf\xf4z\x84\xcdH\xc1\xb0!I\xf6h5\x9b\x05\x96s\x99J&\xb3XK\xb8#\x87W\xe1\xb4@\x1f\xf7\xa0\xe6N\xc8\xce\x13u\x15\xc8\xceY\u00b6\xde\x18\xddZZ\x16\u041b\xa6Aw\xb3\x98Z\xbb\x85\x0e\xb0iL\x18\xad^\v\x1eK\xf5Ey\x04F\x1a\xfb\xd9\u04e7w\u02c9\x8e\xf4%\xb6\xb1\u0621k`\x93\x8f\xfaRF\x1d\xb4\xefL\xc44g*\x8fP\x13s\x8d\x8b\x14\x1f@\xc8\\\x8f2\xe7dR\a1,SN\u0754O\xe0^\x8f\xab\x1c\x1c\xf7\xb0\u0661\xfe\xf5\u04e7{\xfe\x0fc+\xa1*\x8a\xcd^C\x1d\x841\x8b\xe5i\x04)_>\t\x80\x8bH\xf75W8l\xa9\x92\u03fb\xf8\"?\x95\xae/:O\xb2%U[3\x16\x90\x14\x15\x8f\a\xde3\xc3H\x9e\xb5\xe3l\xd0\xd8\xcf,P\xd0\xde\xdc^\xca)\xe0Vq\xab<\x8e>+P8\xe2\a\xa9\xca\xc3\bz\xa1\xed|K\u007f&\xb1xM\x18&RF\xdd4r\xdc\x13\xea\xcc\x19I\xad\xe7>\x90/`$\x93\x96\x9asBm;\x95\xa0Q\u05c6\xa5\xc1\u04f3\x171&i\x1a6[\x12Dn]\xa5\x1f<\x9d]\xfd\x9f=}\xf3\xb0<\xa2\xeb\xd4G\xe1\x02\x1d\x87\f\xf0\x04D\xadf\xb0\xfd\xb2>z\x1a\x16[\x16 %\xd3(o\xc7+.\x8d\xb5\xaa\xee\xb5\xeb\xb0\x00\xf6\u0685\x96\xfcP^\n\x8f\r\xaed\xa3I>\xfd%\xec\xf7^\xf0.\x82\x9d{I?\x8f>\x99\xc6\x154:\xf4\xd8\xc0\xed\xd7O\xdf|\xfe\xf6\xd3\u00e2\xeb\u00e2\xab\xad\u0232\x9a\x151\xd3p\xb2h\xca\x1d\xf9('\x89\x8bD\xcd\rL\u0758\xb9P\xf2J\xba\xbc3MO\x1eqo\x02\xf4:\x00\x13T\x98I\x1b\x82q5\xc2\x12! C:\xe6[[I\u0702\xd0K\xa4\xd4o\xe0\u0453\xffq/I^\x93\x02g9u\x87\xa6\xf5\xa1iL\x99\a\x87\xf17\x1a\xd76\xe4\x1f\a\x00\x00") + +func staticCssUplotMinCssGzBytes() ([]byte, error) { + return _staticCssUplotMinCssGz, nil +} + +func staticCssUplotMinCssGz() (*asset, error) { + bytes, err := staticCssUplotMinCssGzBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "static/css/uPlot.min.css.gz", size: 740, mode: os.FileMode(420), modTime: time.Unix(1612357306, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _staticFaviconIco = []byte("\x00\x00\x01\x00\x01\x00@@\x00\x00\x01\x00 \x00(B\x00\x00\x16\x00\x00\x00(\x00\x00\x00@\x00\x00\x00\x80\x00\x00\x00\x01\x00 \x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\u007f\xff\x01\x00z\xff\x06T\xa8\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x9f\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00x\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xff\x02\x00v\xff\x06\x05\u007f\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00|\xff\x06\x00\x00\x00\x00\x1d\x89\xff\x06\x00z\xff\x89^\xad\xffE\xff\xff\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\xd6\xff\a\x00\x00\x00\x00\x00\x00\x00\x00\x01}\xff\x05\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffu\x01}\xff\xd6\x00z\xff\xff-\x93\xff\xb47\x98\xff\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00v\xff\x06\x00\x00\x00\x00\x17\x88\xff\x9a\x05~\xff\xbe\x00z\xff,\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x05\x00\x00\x00\x00\x00|\xffB\x00|\xff\xcc\x00|\xff\xfe\x00|\xff\xff\x00{\xff\xfc\x0e\x83\xff\xffr\xb6\xff&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Q\xa5\xff\x03\x00\x00\x00\x00l\xb3\xff6\r\x83\xff\xe3\x00{\xff\xff\x00|\xff\xf1\x00|\xff\x8e\x00|\xff\t\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x01\x00|\xff\x01\x00|\xff|\x00|\xff\xf0\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfc\x01|\xff\xf7\x00{\xff\xff.\x94\xff\x95n\xb5\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xff\x05\x00\x00\x00\x00,\x93\xff\x9f\b\x80\xff\xff\x00{\xff\xfe\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xcb\x00|\xff+\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xff\x06\x00|\xff\x9b\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xf9\x00|\xff\x85\x1b\x8a\xff\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\xbc\xff\x01\x00\x00\x00\x00\xff\xff\xff\n\x0f\x84\xff\xb4\x00{\xff\xff\x00|\xff\xfe\x00|\xff\xfc\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xee\x00|\xff<\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xff\x18\x00|\xff\xb7\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xfd\x00|\xff\xfc\x00|\xff\xff\x00|\xff\x9c\x00|\xff\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x92\xff\x04\x00\x00\x00\x00\x00|\xffM\x00|\xff\xe0\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xff\x00|\xff\\\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xff\x18\x00|\xff\xb6\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xfc\x00|\xff\xff\x00|\xff\xd9\x00|\xff4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xff\x8d\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xff\x00|\xff\\\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff\x18\x00|\xff\xb5\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xfc\x00|\xff\xff\x00|\xff\xa8\x00|\xff\x11\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xffO\x00|\xff\xf0\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xff\x00|\xff\\\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x89\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xff\x00|\xff\x88\x00|\xff\a\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00|\xff3\x00|\xff\xda\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xee\x00|\xff-\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffl\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xfd\x00|\xff\xff\x00|\xff}\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00|\xff\x01\x00|\xff\x14\x00|\xff\xec\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xed\x00|\xff\v\x00|\xff\x01\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff@\x00|\xff\xf8\x00|\xff\xfc\x00|\xff\xfc\x00|\xff\xff\x00|\xff\xa3\x00|\xff\x0e\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xff@\x00|\xff\xf5\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xbc\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff\x15\x00|\xff\xb2\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xc7\x00|\xff#\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xd7\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00|\xffm\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xff\x00|\xff\xf7\x00|\xffa\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\\\x00|\xff\xff\x00|\xff\xf5\x00|\xff\xff\x00|\xff\xf5\x00|\xffM\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04~\xff\x0e\x00|\xffLK\xa3\xffX\x00\x00\x00\x00Q\xa6\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\xb2\xff\x01\x00\x00\x00\x00m\xb4\xff\x199\x99\xff6\x00e\xff\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xff\xb6\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xff\x00|\xff\xe2\x00|\xff\x06\x00|\xff\x03\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff\x1c\x00|\xff\xcc\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\x99\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff2\x00|\xff\xa4\x00|\xff\xff\x1c\x8b\xff\xd2\x00\x00\x00\x00\x04~\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x82\xff\x03\x00\x00\x00\x00-\x93\xffP\x0e\x83\xff\xfa\x00z\xff\xb4\x02}\xff0\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00|\xff&\x00|\xff\xf8\x00|\xff\xfc\x00|\xff\xff\x00|\xff\xf7\x00|\xff\u007f\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffU\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xff\xd9\x00|\xff0\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xffU\x00|\xff\xe9\x00|\xff\xff\x00|\xff\xf7\x03}\xff\xfek\xb3\xffH\x00\x00\x00\x00^\xac\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xae\xff\x01\x00\x00\x00\x00\xff\xff\xff\a#\x8e\xff\xa3\x02}\xff\xff\x00|\xff\xff\x00|\xff\xe9\x00|\xffQ\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff~\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xd9\x00|\xff\x06\x00|\xff\x03\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x13\x00|\xff\xc0\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\x91\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00|\xffU\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x01|\xff\xff/\x95\xff\x9f\x00\x00\x00\x00,\x93\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x94\xff\x03\x00\x00\x00\x00B\x9d\xffK\x18\x88\xff\xfd\x00y\xff\xff\x01}\xff\xf4\x00|\xff\xff\x00|\xff\xf7\x00|\xff]\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x12\x00|\xff\xf6\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xf4\x00|\xffp\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff4\x00|\xff\xff\x00|\xff\xf7\x00|\xff\xff\x00|\xff\xdb\x00|\xff4\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00|\xffU\x00|\xff\xfe\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xf3\x01|\xff\xa4\x1c\x8a\xffE\x00\x00\x00\x00\x1a\x89\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x88\xff\x02\x00\x00\x00\x00$\x8e\xff+\f\x82\xff\xa9\x00{\xff\xf5\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xf7\x00|\xffQ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x80\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xc4\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00|\xffw\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xa6\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xff-\x00|\xff\xf3\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xd4\x00|\xff`\x00\x00\x00\x00\x00\x00\x00\x00\x19\x89\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x85\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x01|\xff`\x00|\xff\xdd\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xe9\x00|\xff2\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff!\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xe0\x00|\xff)\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x13\x00|\xff\xbe\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf1\x00|\xff`\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x05\x00\x00\x00\x00\x00|\xff\xc4\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xfe\x00|\xff\xe5\x00|\xff4\x00\x00\x00\x00\x01}\xff\x03\"\x8e\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x88\xff\x03!\x8c\xff\x03\x00\x00\x00\x00\x00|\xff4\x00|\xff\xdd\x00|\xff\xff\x00|\xff\xf5\x00|\xff\xff\x00|\xff\xb0\x00|\xff\t\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00|\xff\xb8\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf4\x00|\xffm\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x1a\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xd0\x00|\xff\x1d\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xffk\x00|\xff\xf7\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x00|\xffK\x00\x00\x00\x00\x00|\xff\x04\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\a\x00\x00\x00\x00\x00|\xff_\x00|\xff\xf7\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xffQ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00|\xffb\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xa7\x00\x00\x00\x00\x00|\xff\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff<\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xff\xb5\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xff\xc6\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xa1\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x03\x00\x00\x00\x00\x00|\xff\x9f\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xb0\x00|\xff\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff(\x00|\xff\xff\x00|\xff\xf7\x00|\xff\xff\x00|\xff\xcc\x00\x00\x00\x00\x00|\xff\x04\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffY\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\x92\x00\x00\x00\x00\x00|\xff\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xff:\x00|\xff\xe3\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xffA\x00|\xff\xe3\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x00|\xff%\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x10\x00|\xff\xf0\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xd1\x00|\xff\x12\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00|\xff{\x00|\xff\xff\x00|\xff\xff\x00|\xff\xed\x00|\xffY\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xffw\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xff\x00|\xff\xaf\x00|\xff\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00|\xff\xb6\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xffN\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\v\x00|\xff\xab\x00|\xff\xff\x00|\xff\xff\x00|\xff\xdd\x00|\xff0\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\t\x00|\xff\x9b\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe8\x00|\xffM\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\a\x00\x00\x00\x00\x00|\xff\x9e\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xffR\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00|\xffv\x00|\xff\xfb\x00|\xff\xfd\x00|\xff\xff\x00|\xff\x82\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\t\x00|\xff\x9d\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe8\x00|\xffK\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\t\x00|\xff\x9d\x00|\xff\xff\x00|\xff\xff\x00|\xff\xd9\x00|\xff&\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\b\x00\x00\x00\x00\x00|\xff\xb6\x00|\xff\xff\x00|\xff\xf5\x00|\xff\xff\x00|\xff$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00|\xffS\x00|\xff\xea\x00|\xff\xff\x00|\xff\xff\x00|\xff\x9c\x00|\xff\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00|\xffo\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe9\x00|\xffM\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\t\x00|\xff\x9c\x00|\xff\xff\x00|\xff\xff\x00|\xff\xd2\x00|\xff\x15\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\b\x00\x00\x00\x00\x00|\xff\xb8\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xe7\x00|\xff\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xff\x1f\x00|\xff\xd5\x00|\xff\xff\x00|\xff\xff\x00|\xff\x9e\x00|\xff\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\\\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe8\x00|\xffL\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\t\x00|\xff\x9c\x00|\xff\xff\x00|\xff\xff\x00|\xff\xd1\x00|\xff\x12\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\b\x00\x00\x00\x00\x00|\xff\xb6\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xec\x00|\xff\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xff(\x00|\xff\xd8\x00|\xff\xff\x00|\xff\xff\x00|\xff\x9c\x00|\xff\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffX\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe8\x00|\xffL\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\t\x00|\xff\x9c\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe5\x00|\xffD\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\b\x00\x00\x00\x00\x00|\xff\xba\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xff\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xffC\x00|\xff\xe4\x00|\xff\xff\x00|\xff\xff\x00|\xff\xa0\x00|\xff\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\a\x00|\xff\x93\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe8\x00|\xffL\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\b\x00|\xff\x92\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe7\x00|\xffJ\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00|\xff\x94\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff_\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00|\xff\x80\x00|\xff\xfd\x00|\xff\xfc\x00|\xff\xff\x00|\xffv\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\b\x00|\xff\x99\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe5\x00|\xffC\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xffc\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xfa\x00|\xffy\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xffy\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xff\x00|\xff\xaf\x00|\xff\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x04\x00\x00\x00\x00\x00|\xff\xb9\x00|\xff\xff\x00|\xff\xf7\x00|\xff\xff\x00|\xffV\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x10\x00|\xff\xd0\x00|\xff\xff\x00|\xff\xff\x00|\xff\xd5\x00|\xff\x1a\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffR\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xa3\x00\x00\x00\x00\x00|\xff\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xff9\x00|\xff\xe0\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xff=\x00|\xff\xdf\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xfd\x00|\xff!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x15\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xcf\x00|\xff\f\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff$\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xff\xc4\x00|\xff\x06\x00|\xff\x01\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x05\x00\x00\x00\x00\x00|\xff\xc8\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\x9e\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x03\x00\x00\x00\x00\x00|\xff\xa4\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xb5\x00|\xff\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffE\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xc1\x00\x00\x00\x00\x00|\xff\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x18\x00|\xff\xdd\x00|\xff\xff\x00|\xff\xff\x00|\xff\xdd\x00|\xff9\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xffo\x00|\xff\xf5\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00|\xff`\x00|\xff\xf3\x00|\xff\xff\x00|\xff\xf7\x00|\xff\xff\x00|\xffK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00|\xff\x85\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xfd\x00|\xff\x89\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\f\x00|\xff\xa0\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xff\x00|\xff\x85\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00|\xff\xbe\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xee\x00|\xff\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff4\x00|\xff\xd4\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xa4\x00|\xff\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\r\x00|\xff\xe4\x00|\xff\xfd\x00|\xff\xff\x00|\xff\xec\x00|\xffP\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffT\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xff\xc0\x00|\xff\t\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xff3\x00|\xff\xe5\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xee\x00|\xff?\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffK\x00|\xff\xe5\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xe9\x00|\xff2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffF\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xd6\x00|\xff\t\x00|\xff\x02\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff\"\x00|\xff\xf5\x00|\xff\xfc\x00|\xff\xff\x00|\xff\xf2\x00|\xffa\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00|\xffj\x00|\xff\xf2\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xff\x00|\xff\x9e\x00|\xff\x1f\x00|\xff\f\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\a\x00|\xff\x1f\x00|\xff\xa1\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xff\x00|\xffU\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00|\xff\xbc\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xff\x00|\xff\xa5\x00\x00\x00\x00\x00|\xff\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\t\x00|\xff\x8a\x00|\xff\xff\x00|\xff\xf7\x00|\xff\xff\x00|\xff\xb6\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\a\x00\x00\x00\x00\x00|\xffi\x00|\xff\xf2\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xff\x00|\xff\xaf\x00|\xff_\x00|\xff\x1a\x00|\xff\x1b\x00|\xff\x16\x00|\xff$\x00|\xffR\x00|\xff\xaf\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xfd\x00|\xff\xff\x00|\xff\xfe\x00|\xffU\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff7\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xea\x00|\xff9\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff5\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xf4\x00|\xffc\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\t\x00\x00\x00\x00\x00|\xffj\x00|\xff\xe5\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xec\x00|\xff\xe7\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf3\x00|\xffU\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x05\x00|\xff\xc1\x00|\xff\xfd\x00|\xff\xfe\x00|\xff\xff\x00|\xff\xba\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\f\x00|\xff\x95\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xff\xc8\x00|\xff\x1a\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\a\x00\x00\x00\x00\x00|\xff3\x00|\xff\xbe\x00|\xff\xf5\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xf6\x00|\xff\xfc\x00|\xff\xfc\x00|\xff\xf5\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf7\x00|\xff\xc4\x00|\xff-\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xffb\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xff\x00|\xff\xf2\x00|\xffA\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff5\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xfa\x00|\xff\xff\x00|\xff\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffo\x00|\xff\xc8\x00|\xff\xe0\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xe3\x00|\xff\xc6\x00|\xffk\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00|\xff\x17\x00|\xff\xea\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xff\x00|\xff\xb3\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xffv\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xf4\x00|\xff\\\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff9\x00|\xffy\x00|\xff\x94\x00|\xff\xba\x00|\xff\xb6\x00|\xff\xb8\x00|\xff\xb6\x00|\xff\x9e\x00|\xffw\x00|\xff:\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x01\x00|\xff\b\x00|\xff\xbc\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xff\x00|\xff\xe9\x00|\xff\x1f\x00|\xff\x02\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xff\x15\x00|\xff\xc0\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xff\x00|\xff\xe3\x00|\xff8\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00|\xff\x05\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x94\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xff\x00|\xff\xff\x00|\xffi\x00\x00\x00\x00\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xff+\x00|\xff\xe4\x00|\xff\xff\x00|\xff\xf3\x00|\xff\xff\x00|\xff\xc7\x00|\xff+\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x03\x00|\xff\x05\x00|\xff\x06\x00|\xff\b\x00|\xff\b\x00|\xff\b\x00|\xff\b\x00|\xff\a\x00|\xff\x05\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00|\xff\x06\x00|\xffk\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xfd\x00|\xff\xff\x00|\xff\x9a\x00\x00\x00\x00\x00|\xff\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00|\xffE\x00|\xff\xf6\x00|\xff\xff\x00|\xff\xf3\x00|\xff\xff\x00|\xff\xd9\x00|\xffH\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x06\x00\x00\x00\x00\x00|\xff\x10\x00|\xff\x8e\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xb2\x00\x00\x00\x00\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffc\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xf3\x00|\xff\xff\x00|\xff\xe7\x00|\xffn\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x04\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff/\x00|\xff\xab\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xbd\x00|\xff\x1e\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffb\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xf3\x00|\xff\xff\x00|\xff\xff\x00|\xff\xa1\x00|\xff<\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00|\xff\x04\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x06\x00|\xff\x02\x00\x00\x00\x00\x00|\xff\x10\x00|\xffi\x00|\xff\xd9\x00|\xff\xff\x00|\xff\xfd\x00|\xff\xf8\x00|\xff\xff\x00|\xff\xbc\x00|\xff\x1c\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xffU\x00|\xff\xea\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xfd\x00|\xff\xff\x00|\xff\xe0\x00|\xff\x8a\x00|\xff0\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00|\xff\x06\x00|\xff\x04\x00|\xff\x02\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x03\x00|\xff\x05\x00|\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x05\x00|\xff]\x00|\xff\xb4\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf9\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xa5\x00|\xff\x1c\x00\x00\x00\x00\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff@\x00|\xff\xd3\x00|\xff\xff\x00|\xff\xfc\x00|\xff\xf7\x00|\xff\xff\x00|\xff\xff\x00|\xff\xd5\x00|\xff\x8b\x00|\xffE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x03\x00|\xff\b\x00|\xff\x06\x00|\xff\x06\x00|\xff\x06\x00|\xff\a\x00|\xff\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x1c\x00|\xffh\x00|\xff\xaf\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf5\x00|\xff\xff\x00|\xff\xff\x00|\xff\x8e\x00|\xff\v\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x01\x00\x00\x00\x00\x00|\xff&\x00|\xff\x9d\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf7\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe2\x00|\xff\xb7\x00|\xff\x82\x00|\xffP\x00|\xff\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\b\x00|\xff4\x00|\xffh\x00|\xff\x9c\x00|\xff\xcc\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf7\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xdc\x00|\xff_\x00|\xff\x03\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00|\xff\r\x00|\xffT\x00|\xff\xcc\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe9\x00|\xff\xd0\x00|\xff\xbe\x00|\xff\xb0\x00|\xff\x93\x00|\xff|\x00|\xff\x84\x00|\xff\xa2\x00|\xff\xb7\x00|\xff\xc4\x00|\xff\xdb\x00|\xff\xf5\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf6\x00|\xff\xf9\x00|\xff\xff\x00|\xff\xfd\x00|\xff\x8d\x00|\xff-\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x1d\x00|\xffb\x00|\xff\xd2\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xf6\x00|\xff\xfb\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfb\x00|\xff\xfe\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xf8\x00|\xff\xf7\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\x98\x00|\xff;\x00|\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x1f\x00|\xffI\x00|\xff\xab\x00|\xff\xfa\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xfe\x00|\xff\xfb\x00|\xff\xf5\x00|\xff\xf8\x00|\xff\xfa\x00|\xff\xf9\x00|\xff\xf6\x00|\xff\xf7\x00|\xff\xfd\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xdb\x00|\xffu\x00|\xff0\x00|\xff\v\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x11\x00|\xff$\x00|\xffH\x00|\xff\x85\x00|\xff\xb2\x00|\xff\xde\x00|\xff\xef\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xff\x00|\xff\xe4\x00|\xff\xce\x00|\xff\x9e\x00|\xffg\x00|\xff2\x00|\xff\x1b\x00|\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\a\x00|\xff\x0f\x00|\xff\x18\x00|\xff\x1b\x00|\xff$\x00|\xff#\x00|\xff#\x00|\xff#\x00|\xff$\x00|\xff \x00|\xff\x19\x00|\xff\x15\x00|\xff\v\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe3\xff\xff\xef\xff\xff\xff\xff\xcf\xff\xff\xe3\xff\xff\xff\xff!\xff\xff\xec\xff\xff\xff\xfe\xc1\xff\xff\xa2\u007f\xff\xff\xf9\x01\xff\xff@\xbf\xff\xff\xf0\x00\xff\xff@_\xff\xff\xe8\x01\xff\xfe\x80/\xff\xff\xd0\a\xff\xff\xa0\x17\xff\xff\xa0\x1f\xff\xff\xe8\v\xff\xff@/\xff\xff\xf4\x05\xff\xfe\x80_\xff\xff\xfa\x02\xff\xff\x81?\xff\xff\xfc\x00\u007f\xfd\x01\u007f\xff\xff\xfe\x81\u007f\xfa\x02\xff\xdf\xfb\xff@\xbf\xfe\x05\xff\x17\xe8\u07e0\x1f\xf4\v\xf6\x17\xe8o\xc0_\xfc\v\xf4\v\xd07\xd0\x0f\xf8\x17\xe8\v\xd0\x1b\xe0/\xf8\x17\xd0\v\xd0\x0f\xf0/\xf0/\xa07\xec\x05\xf8\x17\xf0/ O\xf2\x02\xf8\x17\xf0/@\x9f\xf9\x03\xf8\x17\xf0_A\u007f\xfc\x81\xfc\x13\xf0^\x81\xff\xfe\x81\xfc\v\xe0^\x81\xff\xffA\xfc\v\xe0^\x83\xff\xff@\xfc\v\xe0^\x83\xff\xff@\xfc\v\xe0^\x83\xff\xff@\xfe\v\xe0^\x83\xff\xff@\xfe\v\xe0^\x83\xff\xff@\xfc\v\xe0^\x81\xff\xff@\xfc\v\xe0^\x81\xff\xfeA\xfc\v\xf0^\x81\xff\xfe\x81\xfc\v\xf0\x0e@\xff\xfc\x81\xfc\x17\xf0/@\xff\xfd\x03\xf8\x17\xf0/\xa0\u007f\xfa\x03\xf8\x17\xf8\x17\xa0\x1f\xfc\a\xf8\a\xe8\x17\xd0\x03\xe0\x0f\xf0/\xf8\x1b\xe8\x00\x00\x1f\xf0/\xfc\v\xf4\x00\x00'\xc0_\xfc\x05\xfa\x00\x00_\xa0_\xfa\x06\xfd\x80\x01\xbf@\xbf\xfe\x02~`\x06~\x00?\xfd\x01?\x9f\xf8\xfd\x81\u007f\xfe\x80\xdf\xc0\a\xfa\x02\xff\xff@o\xff\xff\xe4\x05\xff\xff`3\xff\xff\x98\x05\xff\xff\xb0\f\u007f\xfe \v\xff\xff\xd8\x03\a\xe1\x80\x17\xff\xff\xec\x00\xf0\x1e\x00/\xff\xff\xf2\x00\x0f\xe0\x00_\xff\xff\xfd\x00\x00\x00\x01\xbf\xff\xff\xfe\xc0\x00\x00\x03\u007f\xff\xff\xff0\x00\x00\r\xff\xff\xff\xff\xdc\x00\x003\xff\xff\xff\xff\xf7\x80\x01\xdf\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") func staticFaviconIcoBytes() ([]byte, error) { @@ -545,7 +602,35 @@ func staticFaviconIco() (*asset, error) { } var _staticJsAutoradioJs = []byte(`$(function() { - $('[data-toggle="tooltip"]').tooltip(); + $('[data-toggle="tooltip"]').tooltip(); + + $('.chart').each(function(idx, el) { + let queryName = el.attr('chart-query'); + let queryArg = el.attr('chart-arg'); + let title = el.attr('chart-title'); + $.ajax({ + url: '/timeseries_query?query=' + encodeURIComponent(queryName) + '&arg=' + encodeURIComponent(queryArg), + dataType: 'json', + success: function(data) { + // Build the uPlot metadata. + let opts = { + title: title, + width: 500, + height: 200, + series: [ + {}, + ], + }; + for (var i = 0; i < data.labels.length; i++) { + opts.series.push({ + show: true, + label: data.labels[i], + }); + } + let uplot = new uPlot(opts, data.data, el); + }, + }); + }); }); `) @@ -559,12 +644,12 @@ func staticJsAutoradioJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/js/autoradio.js", size: 61, mode: os.FileMode(420), modTime: time.Unix(1581689120, 0)} + info := bindataFileInfo{name: "static/js/autoradio.js", size: 1040, mode: os.FileMode(420), modTime: time.Unix(1612367118, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _staticJsAutoradioJsBr = []byte("\xa1\xe0\x01\xc0\xe4H\xb0q\xa4\xcf8\xb7R\tB\x82\xd2\n)[]\xea\xc4\x05\x1cr\xe0\xf2\xed\x94`@\t\x05\x0e\xb9\xf9\x19n\x1cx\xea\xa9\xf5\xf9B+\x9bG\x18W\xa33\xb9\x10") +var _staticJsAutoradioJsBr = []byte("\xb1x \x00`\x9c.\xa1!\xdf\u0101Es)\x9b\xe2\u0736\xcfh4\xb2\"*\x85>\xa3.\x15{\x94g\xf9\u07fd\xd2,\x96\t\xb5\xf1\u048b\xe5\x02\x16\rP\xb2D\xb77\xab\u075c\xb4\x1f\xc2\x18\x06\x10:\x8d\xe4[\xfc)a\xf4\xa36j\x13Y\xae\u034e\x90\xb4\xf1}!\xe4\xfb\x01x\xe6$;\x0f\xebW\x86\xcd\xf9\x94\x87\x00\u039b\x1bl\xa1\xd4\xff\xeb\xb29\xe7\x16\xb7\xdb\xc5\xe9T|vwD\xd6>Ndx\xd9e/\x17\x97]A\xbc\x97T\xdc5\u05fb\xf0\x1b\u0618\t\xdd/\x80\xfb\xe5\xdcBy\xb2\b\x9a\xfa\x19|\xdf\x1f>uE\n\t5JuF\x8a\xe2a\xd5C\x13\x99{\xcb@\x06\xb5!-\xc5\x16\xd2\xf2\x03:\x84d\u05ac\x00\xe38\xb3t\xd5C!\x9f\u007fH\xf9\x827\u0740k\xea\xf8\xb8\x1b\x94\xfb\xb9#Hz\xe1\xf2\u0371\uea55\x00b\x86\xd6\xe2\xf1\u0321\xa4g\u007f\xa3Z(\x14\xca\f\x9dT\xca\x05\x9d\xe3-F\xc3\x17\x00\xbe\x8f}d\xb2\xeb\u1ffd\x99\x1f\xa2\x14\xda<\xe3\xfdI\x11\xaa\x91\xf6\xcb\xc2h-\x05F2\x85\\X\xe5\xdb#O-\x03\xe8\x94\xf4\x03\xab\x1d\x8e\xc0\xf7Z\x01y6:\xe0C\x9c\x8eX~\xfc\xcfJw7\xca\xd2\x06\x91\xf5\xce=r\x9d%\x16\xa8\x88\vH\x04\xda.\x00\xc6e\xcc\x01") func staticJsAutoradioJsBrBytes() ([]byte, error) { return _staticJsAutoradioJsBr, nil @@ -576,12 +661,12 @@ func staticJsAutoradioJsBr() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/js/autoradio.js.br", size: 55, mode: os.FileMode(420), modTime: time.Unix(1581689120, 0)} + info := bindataFileInfo{name: "static/js/autoradio.js.br", size: 341, mode: os.FileMode(420), modTime: time.Unix(1612367204, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _staticJsAutoradioJsGz = []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x02\x03S\xd1H+\xcdK.\xc9\xcc\xcf\xd3\xd0T\xa8\xe6RPP\xd1P\x8fNI,I\xd4-\xc9OO\xcfI\xb5U*\xc9\xcf\xcf)\xc9,P\x8aU\xd7\u0503\xb254\xad\xb9j\x81\x18\x00\xfe\xec\xd6\xe8=\x00\x00\x00") +var _staticJsAutoradioJsGz = []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x02\x03uS\xc7v\xdb0\x10\xbc\xfb+6\x95\xa0\v\xa5\xf4\x84J\xcf%\xbd\u748e\x90k\x02~\x10\xc1\x00\vw\xff\xbbQ\xdc\t\x8d\xc4:\xb3m\xf6\xf1*[w}CR\xf7\xac\x84\xbd%\xf0\xb8\u028a\x1f-'\xbeF\xba\xeb\x14>\xbaLZ+\x92\xc3\xe5_EY\x1d\u0773r\xb6t,\xae\x1a\xc1\ry\x0ey#N\xd3\xc9v{\x15P\xa5\xac\t\n\t\xfe;4;\xef\xf9\x1c\xe1\x91g+NdX\x113\xacE\xaa(gc\xfd3\u04cd\xe5\xdct\x17\xc5$Ie\x12\xc7\xd7g\xb5W+\xbe\xc1\xb7Y\xe8\xec\x14\u03a8\x1a\x8a\t\xc99Z4\x12\xed\x9fX\xfbI<?*`\x05\xb0ot\x8b\xdf>\xbfz\xa1\xe7\x83\xee\xb1'v2N\xe9\xf9\xe2\xba\xefi\xb12\rR\xae\x9e\xab\x1a\x9c\xfe\xba3\xa0/\xbdau_\x9cg\xadk\x1a\xb4\xb6\x86\x13[\x83>yz\x1e\x93\t<wR\xb5@\x02\xc1}T\x9a`\x8e\u0103\xbc\x1a\x89\x83Wz \v\x8fb\xa61\xa2cu\xba\xacf\x15[\xb2%Q\u00dd\xe94\xcf\v\x94\x9d\xa0\x1an.\x12$\x8fk\xf8\x11\xd9\x1c\xf6\x0e\xf2\x91\xbf\u01af\x0ff\xa3W\xeb\xda\x00\xdb\xe4\x06$<\x82\xe9\xcc_\x1eBtC\xf1\u007f\xa8l\xa5\xb0\xefH\xf8\xf7++e\u0785hQ\x95\xfa\xac\x06g\x05\v\xb2<\xac\xd0[5\x90q\u046e<b\xe1\xfal\x13?\u4bfc\xfc\xa0\x1c\x0ft\x90]\xa3\x1b\u00aa\x1fA\x8f[i\xed,t\xbd\x9a\xaa\x84S\xfc\b\xcfg\v\xbe\x9e/\x14\xaf\xe18\x04$\xffV\xf4\x10\x04\x00\x00") func staticJsAutoradioJsGzBytes() ([]byte, error) { return _staticJsAutoradioJsGz, nil @@ -593,7 +678,7 @@ func staticJsAutoradioJsGz() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/js/autoradio.js.gz", size: 74, mode: os.FileMode(420), modTime: time.Unix(1581689120, 0)} + info := bindataFileInfo{name: "static/js/autoradio.js.gz", size: 415, mode: os.FileMode(420), modTime: time.Unix(1612367204, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -759,7 +844,7 @@ func staticJsPlayerJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/js/player.js", size: 1240, mode: os.FileMode(420), modTime: time.Unix(1612344201, 0)} + info := bindataFileInfo{name: "static/js/player.js", size: 1240, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -776,7 +861,7 @@ func staticJsPlayerJsBr() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/js/player.js.br", size: 370, mode: os.FileMode(420), modTime: time.Unix(1612345238, 0)} + info := bindataFileInfo{name: "static/js/player.js.br", size: 370, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -793,7 +878,60 @@ func staticJsPlayerJsGz() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/js/player.js.gz", size: 502, mode: os.FileMode(420), modTime: time.Unix(1612344943, 0)} + info := bindataFileInfo{name: "static/js/player.js.gz", size: 502, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _staticJsUplotIifeMinJs = []byte(`/*! https://github.com/leeoniya/uPlot (v1.6.4) */ +var uPlot=function(){"use strict";function n(n,e,r,t){var l;r=r||0;for(var i=2147483647>=(t=t||e.length-1);t-r>1;)n>e[l=i?r+t>>1:h((r+t)/2)]?r=l:t=l;return n-e[r]>e[t]-n?t:r}function e(n,e,r,t){for(var l=1==t?e:r;l>=e&&r>=l;l+=t)if(null!=n[l])return l;return-1}var r=[0,0];function t(n,e,t,l){return r[0]=0>t?A(n,-t):n,r[1]=0>l?A(e,-l):e,r}function l(n,e,r,l){var i,a,o,s=10==r?b:k;return n==e&&(n/=r,e*=r),l?(i=h(s(n)),a=m(s(e)),n=(o=t(w(r,i),w(r,a),i,a))[0],e=o[1]):(i=h(s(n)),a=h(s(e)),n=P(n,(o=t(w(r,i),w(r,a),i,a))[0]),e=E(e,o[1])),[n,e]}var i={pad:0,soft:null,mode:0},a={min:i,max:i};function o(n,e,r,t){return I(r)?u(n,e,r):(i.pad=r,i.soft=t?0:null,i.mode=t?3:0,u(n,e,a))}function s(n,e){return null==n?e:n}function u(n,e,r){var t=r.min,l=r.max,i=s(t.pad,0),a=s(l.pad,0),o=s(t.hard,-y),u=s(l.hard,y),f=s(t.soft,y),c=s(l.soft,-y),d=s(t.mode,0),m=s(l.mode,0),x=e-n,k=x||v(e)||1e3,_=b(k),M=w(10,h(_)),S=A(P(n-k*(0==x?0==n?.1:1:i),M/10),6),z=f>n||1!=d&&(3!=d||S>f)&&(2!=d||f>S)?y:f,T=g(o,z>S&&n>=z?z:p(z,S)),D=A(E(e+k*(0==x?0==e?.1:1:a),M/10),6),W=e>c||1!=m&&(3!=m||c>D)&&(2!=m||D>c)?-y:c,Y=p(u,D>W&&W>=e?W:g(W,D));return T==Y&&0==T&&(Y=100),[T,Y]}var f=new Intl.NumberFormat(navigator.language).format,c=Math,v=c.abs,h=c.floor,d=c.round,m=c.ceil,p=c.min,g=c.max,w=c.pow,x=c.sqrt,b=c.log10,k=c.log2,_=c.PI,y=1/0;function M(n,e){return d(n/e)*e}function S(n,e,r){return p(g(n,e),r)}function z(n){return"function"==typeof n?n:()=>n}var T=(n,e)=>e,D=()=>null;function E(n,e){return m(n/e)*e}function P(n,e){return h(n/e)*e}function A(n,e){return d(n*(e=Math.pow(10,e)))/e}var W=new Map;function Y(n){return((""+n).split(".")[1]||"").length}function C(n,e,r,t){for(var l=[],i=t.map(Y),a=e;r>a;a++)for(var o=v(a),s=A(w(n,a),o),u=0;t.length>u;u++){var f=t[u]*s,c=(0>f||0>a?o:0)+(i[u]>a?i[u]:0),h=A(f,c);l.push(h),W.set(h,c)}return l}var H={},F=Array.isArray;function N(n){return"string"==typeof n}function I(n){var e=!1;if(null!=n){var r=n.constructor;e=null==r||r==Object}return e}function L(n){var e;if(F(n))e=n.map(L);else if(I(n))for(var r in e={},n)e[r]=L(n[r]);else e=n;return e}function V(n){for(var e=arguments,r=1;e.length>r;r++){var t=e[r];for(var l in t)I(n[l])?V(n[l],L(t[l])):n[l]=L(t[l])}return n}function O(n,e,r){for(var t=0,l=void 0,i=-1;e.length>t;t++){var a=e[t];if(a>i){for(l=a-1;l>=0&&null==n[l];)n[l--]=null;for(l=a+1;r>l&&null==n[l];)n[i=l++]=null}}}var j="undefined"==typeof queueMicrotask?n=>Promise.resolve().then(n):queueMicrotask,G="width",B="height",R="top",U="bottom",J="left",q="right",Z="#000",X="#0000",K="mousemove",Q="mousedown",$="mouseup",nn="mouseenter",en="mouseleave",rn="dblclick",tn="resize",ln="scroll",an="u-off",on="u-label",sn=document,un=window,fn=devicePixelRatio;function cn(n,e){null!=e&&n.classList.add(e)}function vn(n,e){n.classList.remove(e)}function hn(n,e,r){n.style[e]=r+"px"}function dn(n,e,r,t){var l=sn.createElement(n);return null!=e&&cn(l,e),null!=r&&r.insertBefore(l,t),l}function mn(n,e){return dn("div",n,e)}function pn(n,e,r,t,l){n.style.transform="translate("+e+"px,"+r+"px)",0>e||0>r||e>t||r>l?cn(n,an):vn(n,an)}var gn={passive:!0};function wn(n,e,r){e.addEventListener(n,r,gn)}function xn(n,e,r){e.removeEventListener(n,r,gn)}var bn=["January","February","March","April","May","June","July","August","September","October","November","December"],kn=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];function _n(n){return n.slice(0,3)}var yn=kn.map(_n),Mn=bn.map(_n),Sn={MMMM:bn,MMM:Mn,WWWW:kn,WWW:yn};function zn(n){return(10>n?"0":"")+n}var Tn={YYYY:n=>n.getFullYear(),YY:n=>(n.getFullYear()+"").slice(2),MMMM:(n,e)=>e.MMMM[n.getMonth()],MMM:(n,e)=>e.MMM[n.getMonth()],MM:n=>zn(n.getMonth()+1),M:n=>n.getMonth()+1,DD:n=>zn(n.getDate()),D:n=>n.getDate(),WWWW:(n,e)=>e.WWWW[n.getDay()],WWW:(n,e)=>e.WWW[n.getDay()],HH:n=>zn(n.getHours()),H:n=>n.getHours(),h:n=>{var e=n.getHours();return 0==e?12:e>12?e-12:e},AA:n=>12>n.getHours()?"AM":"PM",aa:n=>12>n.getHours()?"am":"pm",a:n=>12>n.getHours()?"a":"p",mm:n=>zn(n.getMinutes()),m:n=>n.getMinutes(),ss:n=>zn(n.getSeconds()),s:n=>n.getSeconds(),fff:n=>function(n){return(10>n?"00":100>n?"0":"")+n}(n.getMilliseconds())};function Dn(n,e){e=e||Sn;for(var r,t=[],l=/\{([a-z]+)\}|[^{]+/gi;r=l.exec(n);)t.push("{"==r[0][0]?Tn[r[1]]:r[0]);return n=>{for(var r="",l=0;t.length>l;l++)r+="string"==typeof t[l]?t[l]:t[l](n,e);return r}}var En=(new Intl.DateTimeFormat).resolvedOptions().timeZone,Pn=n=>n%1==0,An=[1,2,2.5,5],Wn=C(10,-16,0,An),Yn=C(10,0,16,An),Cn=Yn.filter(Pn),Hn=Wn.concat(Yn),Fn="{YYYY}",Nn="\n"+Fn,In="{M}/{D}",Ln="\n"+In,Vn=Ln+"/{YY}",On="{aa}",jn="{h}:{mm}"+On,Gn="\n"+jn,Bn=":{ss}",Rn=null;function Un(n){var e=1e3*n,r=60*e,t=60*r,l=24*t,i=30*l,a=365*l;return[(1==n?C(10,0,3,An).filter(Pn):C(10,-3,0,An)).concat([e,5*e,10*e,15*e,30*e,r,5*r,10*r,15*r,30*r,t,2*t,3*t,4*t,6*t,8*t,12*t,l,2*l,3*l,4*l,5*l,6*l,7*l,8*l,9*l,10*l,15*l,i,2*i,3*i,4*i,6*i,a,2*a,5*a,10*a,25*a,50*a,100*a]),[[a,Fn,Rn,Rn,Rn,Rn,Rn,Rn,1],[28*l,"{MMM}",Nn,Rn,Rn,Rn,Rn,Rn,1],[l,In,Nn,Rn,Rn,Rn,Rn,Rn,1],[t,"{h}"+On,Vn,Rn,Ln,Rn,Rn,Rn,1],[r,jn,Vn,Rn,Ln,Rn,Rn,Rn,1],[e,Bn,Vn+" "+jn,Rn,Ln+" "+jn,Rn,Gn,Rn,1],[n,Bn+".{fff}",Vn+" "+jn,Rn,Ln+" "+jn,Rn,Gn,Rn,1]],function(e){return(o,s,u,f,c,v)=>{var d=[],m=c>=a,p=c>=i&&a>c,g=e(u),w=g*n,x=te(g.getFullYear(),m?0:g.getMonth(),p||m?1:g.getDate()),b=x*n;if(p||m)for(var k=p?c/i:0,_=m?c/a:0,y=w==b?w:te(x.getFullYear()+_,x.getMonth()+k,1)*n,M=new Date(y/n),S=M.getFullYear(),z=M.getMonth(),T=0;f>=y;T++){var D=te(S+_*T,z+k*T,1);(y=(+D+(D-e(D*n)))*n)>f||d.push(y)}else{var P=l>c?c:l,W=b+(h(u)-h(w))+E(w-b,P);d.push(W);for(var Y=e(W),C=Y.getHours()+Y.getMinutes()/r+Y.getSeconds()/t,H=c/t,F=v/o.axes[s]._space;(W=A(W+c,1==n?0:3))<=f;)if(H>1){var N=h(A(C+H,6))%24,I=e(W).getHours()-N;I>1&&(I=-1),C=(C+H)%24,.7>A(((W-=I*t)-d[d.length-1])/c,3)*F||d.push(W)}else d.push(W)}return d}}]}var Jn=Un(1),qn=Jn[0],Zn=Jn[1],Xn=Jn[2],Kn=Un(.001),Qn=Kn[0],$n=Kn[1],ne=Kn[2];function ee(n,e){return n.map((n=>n.map(((r,t)=>0==t||8==t||null==r?r:e(1==t||0==n[8]?r:n[1]+r)))))}function re(n,e){return(r,t,l,i,a)=>{var o,s,u,f,c,v,h=e.find((n=>a>=n[0]))||e[e.length-1];return t.map((e=>{var r=n(e),t=r.getFullYear(),l=r.getMonth(),i=r.getDate(),a=r.getHours(),d=r.getMinutes(),m=r.getSeconds(),p=t!=o&&h[2]||l!=s&&h[3]||i!=u&&h[4]||a!=f&&h[5]||d!=c&&h[6]||m!=v&&h[7]||h[1];return o=t,s=l,u=i,f=a,c=d,v=m,p(r)}))}}function te(n,e,r){return new Date(n,e,r)}function le(n,e){return e(n)}function ie(n,e){return(r,t)=>e(n(t))}function ae(n,e){var r=n.series[e];return r.width?r.stroke(n,e):r.points.width?r.points.stroke(n,e):null}function oe(n,e){return n.series[e].fill(n,e)}C(2,-53,53,[1]);var se=[0,0];function ue(n,e,r){return n=>{0==n.button&&r(n)}}function fe(n,e,r){return r}var ce={show:!0,x:!0,y:!0,lock:!1,move:function(n,e,r){return se[0]=e,se[1]=r,se},points:{show:function(n,e){var r=n.cursor.points,t=mn(),l=r.stroke(n,e),i=r.fill(n,e);t.style.background=i||l;var a=r.size(n,e),o=r.width(n,e,a);o&&(t.style.border=o+"px solid "+l);var s=a/-2;return hn(t,G,a),hn(t,B,a),hn(t,"marginLeft",s),hn(t,"marginTop",s),t},size:function(n,e){return De(n.series[e].width,1)},width:0,stroke:function(n,e){return n.series[e].stroke(n,e)},fill:function(n,e){return n.series[e].stroke(n,e)}},bind:{mousedown:ue,mouseup:ue,click:ue,dblclick:ue,mousemove:fe,mouseleave:fe,mouseenter:fe},drag:{setScale:!0,x:!0,y:!1,dist:0,uni:null,_x:!1,_y:!1},focus:{prox:-1},left:-10,top:-10,idx:null,dataIdx:function(n,e,r){return r}},ve={show:!0,stroke:"rgba(0,0,0,0.07)",width:2,filter:T},he=V({},ve,{size:10}),de='12px system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',me="bold "+de,pe={show:!0,scale:"x",stroke:Z,space:50,gap:5,size:50,labelSize:30,labelFont:me,side:2,grid:ve,ticks:he,font:de,rotate:0},ge={show:!0,scale:"x",auto:!1,sorted:1,min:y,max:-y,idxs:[]};function we(n,e){return e.map((n=>null==n?"":f(n)))}function xe(n,e,r,t,l,i,a){for(var o=[],s=W.get(l)||0,u=r=a?r:A(E(r,l),s);t>=u;u=A(u+l,s))o.push(Object.is(u,-0)?0:u);return o}function be(n,e,r,t,l){var i=[],a=n.scales[n.axes[e].scale].log,o=h((10==a?b:k)(r));l=w(a,o),0>o&&(l=A(l,-o));var s=r;do{i.push(s),l*a>(s=A(s+l,W.get(l)))||(l=s)}while(t>=s);return i}var ke=/./,_e=/[12357]/,ye=/[125]/,Me=/1/;function Se(n,e,r){var t=n.axes[r],l=t.scale;if(2==n.scales[l].log)return e;var i=n.valToPos,a=t._space,o=i(10,l),s=i(9,l)-o<a?i(7,l)-o<a?i(5,l)-o<a?Me:ye:_e:ke;return e.map((n=>s.test(n)?n:null))}function ze(n,e){return null==e?"":f(e)}var Te={show:!0,scale:"y",stroke:Z,space:30,gap:5,size:50,labelSize:30,labelFont:me,side:3,grid:ve,ticks:he,font:de,rotate:0};function De(n,e){return A((3+2*(n||1))*e,3)}function Ee(n,e){var r=n.scales[n.series[e].scale],t=n.bands&&n.bands.some((n=>n.series[0]==e));return 3==r.distr||t?r.min:0}var Pe={scale:"y",auto:!0,sorted:0,show:!0,band:!1,spanGaps:!1,alpha:1,points:{show:function(n,e){var r=n.series[0].idxs;return(0==n.scales[n.series[0].scale].ori?n.bbox.width:n.bbox.height)/(n.series[e].points.space*fn)>=r[1]-r[0]}},values:null,min:y,max:-y,idxs:[],path:null,clip:null};function Ae(n,e,r){return r/10}var We={time:!0,auto:!0,distr:1,log:10,min:null,max:null,dir:1,ori:0},Ye=V({},We,{time:!1,ori:1}),Ce={};function He(){var n=[];return{sub:function(e){n.push(e)},unsub:function(e){n=n.filter((n=>n!=e))},pub:function(e,r,t,l,i,a,o){n.length>1&&n.forEach((n=>{n!=r&&n.pub(e,r,t,l,i,a,o)}))}}}function Fe(n,e,r){var t=n.series[e],l=n.scales,i=n.bbox,a=n._data[0],o=n._data[e],s=l[n.series[0].scale],u=l[t.scale],f=i.left,c=i.top,v=i.width,h=i.height,d=n.valToPosH,m=n.valToPosV;return 0==s.ori?r(t,a,o,s,u,d,m,f,c,v,h,Ve,je,Be,Ue,qe):r(t,a,o,s,u,m,d,c,f,h,v,Oe,Ge,Re,Je,Ze)}function Ne(n,e,r,t,l){return Fe(n,e,((n,e,i,a,o,s,u,f,c,v,h)=>{var d,m,p=0==a.ori?je:Ge;1==a.dir*(0==a.ori?1:-1)?(d=r,m=t):(d=t,m=r);var g=M(s(e[d],a,v,f),.5),w=M(u(i[d],o,h,c),.5),x=M(s(e[m],a,v,f),.5),b=M(u(o.max,o,h,c),.5),k=new Path2D(l);return p(k,x,b),p(k,g,b),p(k,g,w),k}))}function Ie(n,e,r,t,l,i){var a=null;if(n.length>0){a=new Path2D;for(var o=0==e?Be:Re,s=r,u=0;n.length>u;u++){var f=n[u];o(a,s,t,f[0]-s,t+i),s=f[1]}o(a,s,t,r+l-s,t+i)}return a}function Le(n,e,r){if(r>e){var t=n[n.length-1];t&&t[0]==e?t[1]=r:n.push([e,r])}}function Ve(n,e,r){n.moveTo(e,r)}function Oe(n,e,r){n.moveTo(r,e)}function je(n,e,r){n.lineTo(e,r)}function Ge(n,e,r){n.lineTo(r,e)}function Be(n,e,r,t,l){n.rect(e,r,t,l)}function Re(n,e,r,t,l){n.rect(r,e,l,t)}function Ue(n,e,r,t,l,i){n.arc(e,r,t,l,i)}function Je(n,e,r,t,l,i){n.arc(r,e,t,l,i)}function qe(n,e,r,t,l,i,a){n.bezierCurveTo(e,r,t,l,i,a)}function Ze(n,e,r,t,l,i,a){n.bezierCurveTo(r,e,l,t,a,i)}function Xe(n){return(e,r,t,l,i)=>{t!=l&&(n(e,r,t),n(e,r,l),n(e,r,i))}}var Ke=Xe(je),Qe=Xe(Ge);function $e(){return(n,r,t,l)=>Fe(n,r,((i,a,o,s,u,f,c,v,h,m,w)=>{var x,b;0==s.ori?(x=je,b=Ke):(x=Ge,b=Qe);var k,_,S,z=s.dir*(0==s.ori?1:-1),T={stroke:new Path2D,fill:null,clip:null,band:null},D=T.stroke,E=y,P=-y,A=[],W=d(f(a[1==z?t:l],s,m,v)),Y=!1,C=e(o,t,l,1*z),H=e(o,t,l,-1*z),F=M(f(a[C],s,m,v),.5),N=M(f(a[H],s,m,v),.5);F>v&&Le(A,v,F);for(var I=1==z?t:l;I>=t&&l>=I;I+=z){var L=d(f(a[I],s,m,v));if(L==W)null!=o[I]?(k=d(c(o[I],u,w,h)),E==y&&x(D,L,k),E=p(k,E),P=g(k,P)):Y||null!==o[I]||(Y=!0);else{var V=!1;E!=y?(b(D,W,E,P,k),_=S=W):Y&&(V=!0,Y=!1),null!=o[I]?(x(D,L,k=d(c(o[I],u,w,h))),E=P=k,L-W>1&&null===o[I-z]&&(V=!0)):(E=y,P=-y,Y||null!==o[I]||(Y=!0)),V&&Le(A,_,L),W=L}}if(E!=y&&E!=P&&S!=W&&b(D,W,E,P,k),v+m>N&&Le(A,N,v+m),null!=i.fill){var O=T.fill=new Path2D(D),j=d(c(i.fillTo(n,r,i.min,i.max),u,w,h));x(O,N,j),x(O,F,j)}return i.spanGaps||(T.clip=Ie(A,s.ori,v,h,m,w)),n.bands.length>0&&(T.band=Ne(n,r,t,l,D)),T}))}function nr(n,e,r,t,l){var i,a,o,s,u,f,c,v,h,m,p,g,b,k,_,y,M,S,z,T,D,E,P,A,W,Y=new Path2D,C=n.length;t(Y,d(n[0]),d(e[0]));for(var H=0;C-1>H;H++){var F=0==H?0:H-1;a=e[F],s=e[H],u=n[H+1],f=e[H+1],C>H+2?(c=n[H+2],v=e[H+2]):(c=u,v=f),b=x(w((i=n[F])-(o=n[H]),2)+w(a-s,2)),k=x(w(o-u,2)+w(s-f,2)),_=x(w(u-c,2)+w(f-v,2)),T=w(_,r),E=w(_,2*r),D=w(k,r),P=w(k,2*r),(S=3*(W=w(b,r))*(W+D))>0&&(S=1/S),(z=3*T*(T+D))>0&&(z=1/z),m=(-P*a+(y=2*(A=w(b,2*r))+3*W*D+P)*s+A*f)*S,g=(E*s+(M=2*E+3*T*D+P)*f-P*v)*z,0==(h=(-P*i+y*o+A*u)*S)&&0==m&&(h=o,m=s),0==(p=(E*o+M*u-P*c)*z)&&0==g&&(p=u,g=f),l(Y,h,m,p,g,u,f)}return Y}var er=$e();function rr(n,e,r,t){return(t?[n[0],n[1]].concat(n.slice(2)):[n[0]].concat(n.slice(1))).map(((n,t)=>tr(n,t,e,r)))}function tr(n,e,r,t){return V({},0==e?r:t,n)}var lr=[null,null];function ir(n,e,r){return null==e?lr:[e,r]}var ar=ir;function or(n,e,r){return null==e?lr:o(e,r,.1,!0)}function sr(n,e,r,t){return null==e?lr:l(e,r,n.scales[t].log,!1)}var ur=sr;function fr(n){var e;return[n=n.replace(/(\d+)px/,((n,r)=>(e=d(r*fn))+"px")),e]}function cr(e,r,t){var i={};function a(n,e){return 3==e.distr?b((n>0?n:e.clamp(i,n,e.min,e.max,e.key))/e.min)/b(e.max/e.min):(n-e.min)/(e.max-e.min)}function u(n,e,r,t){var l=a(n,e);return t+r*(-1==e.dir?1-l:l)}function f(n,e,r,t){var l=a(n,e);return t+r*(-1==e.dir?l:1-l)}function c(n,e,r,t){return 0==e.ori?u(n,e,r,t):f(n,e,r,t)}i.valToPosH=u,i.valToPosV=f;var x=!1;i.status=0;var k=i.root=mn("uplot");null!=e.id&&(k.id=e.id),cn(k,e.class),e.title&&(mn("u-title",k).textContent=e.title);var P=dn("canvas"),Y=i.ctx=P.getContext("2d"),C=mn("u-wrap",k),O=mn("u-under",C);C.appendChild(P);var Z=mn("u-over",C),gn=s((e=L(e)).pxAlign,!0);(e.plugins||[]).forEach((n=>{n.opts&&(e=n.opts(i,e)||e)}));var bn=e.ms||.001,kn=i.series=rr(e.series||[],ge,Pe,!1),_n=i.axes=rr(e.axes||[],pe,Te,!0),yn=i.scales={},Mn=i.bands=e.bands||[];Mn.forEach((n=>{n.fill=z(n.fill||null)}));var Sn=kn[0].scale,zn={axes:function(){_n.forEach(((n,e)=>{if(n.show&&n._show){var r=yn[n.scale],t=n.side,l=t%2,a=0==l?Ge:Be,o=0==l?Le:je,s=d(n.gap*fn),u=n.ticks,f=u.show?d(u.size*fn):0,v=n._found,h=v[0],m=v[1],p=n._splits,g=2==r.distr?p.map((n=>Mr[n])):p,w=2==r.distr?Mr[p[1]]-Mr[p[0]]:h,x=n._rotate*-_/180,b=d(n._pos*fn),k=b+(f+s)*(0==l&&0==t||1==l&&3==t?-1:1),y=0==l?k:0,M=1==l?k:0;Y.font=n.font[0],Y.fillStyle=n.stroke(i,e),Y.textAlign=1==n.align?J:2==n.align?q:x>0?J:0>x?q:0==l?"center":3==t?q:J,Y.textBaseline=x||1==l?"middle":2==t?R:U;var S=1.5*n.font[1],z=p.map((n=>d(c(n,r,a,o))));if(n._values.forEach(((n,e)=>{null!=n&&(0==l?M=z[e]:y=z[e],(""+n).split(/\n/gm).forEach(((n,e)=>{x?(Y.save(),Y.translate(M,y+e*S),Y.rotate(x),Y.fillText(n,0,0),Y.restore()):Y.fillText(n,M,y+e*S)})))})),n.label){Y.save();var T=d(n._lpos*fn);1==l?(M=y=0,Y.translate(T,d(je+Be/2)),Y.rotate((3==t?-_:_)/2)):(M=d(Le+Ge/2),y=T),Y.font=n.labelFont[0],Y.textAlign="center",Y.textBaseline=2==t?R:U,Y.fillText(n.label,M,y),Y.restore()}u.show&&Pr(z,u.filter(i,g,e,m,w),l,t,b,f,A(u.width*fn,3),u.stroke(i,e),u.dash,u.cap);var D=n.grid;D.show&&Pr(z,D.filter(i,g,e,m,w),l,0==l?2:1,0==l?je:Le,0==l?Be:Ge,A(D.width*fn,3),D.stroke(i,e),D.dash,D.cap)}})),Tt("drawAxes")},series:function(){wr>0&&(kn.forEach(((n,e)=>{if(e>0&&n.show&&null==n._paths){var t=function(n){for(var e=S(kr-1,0,wr-1),r=S(_r+1,0,wr-1);null==n[e]&&e>0;)e--;for(;null==n[r]&&wr-1>r;)r++;return[e,r]}(r[e]);n._paths=n.paths(i,e,t[0],t[1])}})),kn.forEach(((n,e)=>{e>0&&n.show&&(n._paths&&function(n){var e=kn[n],r=e._paths,t=r.stroke,l=r.fill,a=r.clip,o=A(e.width*fn,3),s=o%2/2,u=e._stroke=e.stroke(i,n),f=e._fill=e.fill(i,n);Y.globalAlpha=e.alpha;var c=gn&&e.pxAlign;c&&Y.translate(s,s),Y.save();var v=Le,h=je,d=Ge,m=Be,p=o*fn/2;0==e.min&&(m+=p),0==e.max&&(h-=p,m+=p),Y.beginPath(),Y.rect(v,h,d,m),Y.clip(),a&&Y.clip(a),function(n,e,r,t,l,a,o,s){var u=!1;Mn.forEach(((f,c)=>{if(f.series[0]==n){var v=kn[f.series[1]],h=(v._paths||H).band;Y.save();var d=null;v.show&&h&&(d=f.fill(i,c)||a,Y.clip(h)),Er(e,r,t,l,d,o,s),Y.restore(),u=!0}})),u||Er(e,r,t,l,a,o,s)}(n,u,o,e.dash,e.cap,f,t,l),Y.restore(),c&&Y.translate(-s,-s),Y.globalAlpha=1}(e),n.points.show(i,e,kr,_r)&&function(n){var e=kn[n],t=e.points,l=A(t.width*fn,3),a=l%2/2,o=t.width>0,s=(t.size-t.width)/2*fn,u=A(2*s,3),f=gn&&e.pxAlign;f&&Y.translate(a,a),Y.save(),Y.beginPath(),Y.rect(Le-u,je-u,Ge+2*u,Be+2*u),Y.clip(),Y.globalAlpha=e.alpha;var c,v,h,m,p=new Path2D,g=yn[e.scale];0==Nn.ori?(c=Ge,v=Le,h=Be,m=je):(c=Be,v=je,h=Ge,m=Le);for(var w=kr;_r>=w;w++)if(null!=r[n][w]){var x=d(An(r[0][w],Nn,c,v)),b=d(Wn(r[n][w],g,h,m));Yn(p,x+s,b),Fn(p,x,b,s,0,2*_)}var k=t._stroke=t.stroke(i,n),y=t._fill=t.fill(i,n);Dr(k,l,t.dash,t.cap,y||(o?"#fff":e._stroke)),Y.fill(p),o&&Y.stroke(p),Y.globalAlpha=1,Y.restore(),f&&Y.translate(-a,-a)}(e),Tt("drawSeries",e))})))}},Tn=(e.drawOrder||["axes","series"]).map((n=>zn[n]));function En(n){var r=yn[n];if(null==r){var t=(e.scales||H)[n]||H;if(null!=t.from)En(t.from),yn[n]=V({},yn[t.from],t);else{(r=yn[n]=V({},n==Sn?We:Ye,t)).key=n;var l=r.time,i=3==r.distr,a=r.range;if(n!=Sn&&!F(a)&&I(a)){var s=a;a=(n,e,r)=>null==e?lr:o(e,r,s)}r.range=z(a||(l?ar:n==Sn?i?ur:ir:i?sr:or)),r.auto=z(r.auto),r.clamp=z(r.clamp||Ae)}}}for(var Pn in En("x"),En("y"),kn.forEach((n=>{En(n.scale)})),_n.forEach((n=>{En(n.scale)})),e.scales)En(Pn);var An,Wn,Yn,Fn,Nn=yn[Sn],In=Nn.distr;0==Nn.ori?(cn(k,"u-hz"),An=u,Wn=f,Yn=Ve,Fn=Ue):(cn(k,"u-vt"),An=f,Wn=u,Yn=Oe,Fn=Je);var Ln={};for(var Vn in yn){var On=yn[Vn];null==On.min&&null==On.max||(Ln[Vn]={min:On.min,max:On.max})}var jn,Gn=e.tzDate||(n=>new Date(n/bn)),Bn=e.fmtDate||Dn,Rn=1==bn?Xn(Gn):ne(Gn),Un=re(Gn,ee(1==bn?Zn:$n,Bn)),Jn=ie(Gn,le("{YYYY}-{MM}-{DD} {h}:{mm}{aa}",Bn)),Kn=V({show:!0,live:!0},e.legend),te=Kn.show;Kn.width=z(s(Kn.width,2)),Kn.dash=z(Kn.dash||"solid"),Kn.stroke=z(Kn.stroke||ae),Kn.fill=z(Kn.fill||oe);var se,ue=[],fe=!1;if(te){jn=dn("table","u-legend",k);var ve=kn[1]?kn[1].values:null;if(fe=null!=ve){var he=dn("tr","u-thead",jn);for(var de in dn("th",null,he),se=ve(i,1,0))dn("th",on,he).textContent=de}else se={_:0},cn(jn,"u-inline"),Kn.live&&cn(jn,"u-live")}var me=new Map;function ke(n,e,r){var t=me.get(e)||{},l=nr.bind[n](i,e,r);l&&(wn(n,e,t[n]=l),me.set(e,t))}var _e=0,ye=0,Me=0,Fe=0,Ne=0,Ie=0,Le=0,je=0,Ge=0,Be=0;i.bbox={};var Re=!1,qe=!1,Ze=!1,Xe=!1,Ke=!1;function Qe(n,e){n==i.width&&e==i.height||$e(n,e),Yr(!1),Ze=!0,qe=!0,Xe=!0,Ke=!0,Jr()}function $e(n,e){i.width=_e=Me=n,i.height=ye=Fe=e,Ne=Ie=0,function(){var n=!1,e=!1,r=!1,t=!1;_n.forEach((l=>{if(l.show&&l._show){var i=l.side,a=i%2,o=l._size+(l.labelSize=null!=l.label?l.labelSize||30:0);o>0&&(a?(Me-=o,3==i?(Ne+=o,t=!0):r=!0):(Fe-=o,0==i?(Ie+=o,n=!0):e=!0))}})),pr[0]=n,pr[1]=r,pr[2]=e,pr[3]=t,Me-=br[1]+br[3],Ne+=br[3],Fe-=br[2]+br[0],Ie+=br[0]}(),function(){var n=Ne+Me,e=Ie+Fe,r=Ne,t=Ie;function l(l,i){switch(l){case 1:return(n+=i)-i;case 2:return(e+=i)-i;case 3:return(r-=i)+i;case 0:return(t-=i)+i}}_n.forEach((n=>{if(n.show&&n._show){var e=n.side;n._pos=l(e,n._size),null!=n.label&&(n._lpos=l(e,n.labelSize))}}))}();var r=i.bbox;Le=r.left=M(Ne*fn,.5),je=r.top=M(Ie*fn,.5),Ge=r.width=M(Me*fn,.5),Be=r.height=M(Fe*fn,.5)}i.setSize=function(n){Qe(n.width,n.height)};var nr=i.cursor=V({},ce,e.cursor);nr._lock=!1;var cr=nr.points;cr.show=z(cr.show),cr.size=z(cr.size),cr.stroke=z(cr.stroke),cr.width=z(cr.width),cr.fill=z(cr.fill);var vr=i.focus=V({},e.focus||{alpha:.3},nr.focus),hr=vr.prox>=0,dr=[null];function mr(n,e){var r=yn[n.scale].time,t=n.value;if(n.value=r?N(t)?ie(Gn,le(t,Bn)):t||Jn:t||ze,n.label=n.label||(r?"Time":"Value"),e>0){n.width=null==n.width?1:n.width,n.paths=n.paths||er||D,n.fillTo=z(n.fillTo||Ee),n.pxAlign=s(n.pxAlign,!0),n.stroke=z(n.stroke||null),n.fill=z(n.fill||null),n._stroke=n._fill=n._paths=n._focus=null;var l=De(n.width,1),a=n.points=V({},{size:l,width:g(1,.2*l),stroke:n.stroke,space:2*l,_stroke:null,_fill:null},n.points);a.show=z(a.show),a.fill=z(a.fill),a.stroke=z(a.stroke)}if(te&&ue.splice(e,0,function(n,e){if(0==e&&(fe||!Kn.live))return null;var r=[],t=dn("tr","u-series",jn,jn.childNodes[e]);cn(t,n.class),n.show||cn(t,an);var l=dn("th",null,t),a=mn("u-marker",l);if(e>0){var o=Kn.width(i,e);o&&(a.style.border=o+"px "+Kn.dash(i,e)+" "+Kn.stroke(i,e)),a.style.background=Kn.fill(i,e)}var s=mn(on,l);for(var u in s.textContent=n.label,e>0&&(ke("click",l,(()=>{nr._lock||ot(kn.indexOf(n),{show:!n.show},Dt.setSeries)})),hr&&ke(nn,l,(()=>{nr._lock||ot(kn.indexOf(n),st,Dt.setSeries)}))),se){var f=dn("td","u-value",t);f.textContent="--",r.push(f)}return r}(n,e)),nr.show){var o=function(n,e){if(e>0){var r=nr.points.show(i,e);if(r)return cn(r,"u-cursor-pt"),cn(r,n.class),pn(r,-10,-10,Me,Fe),Z.insertBefore(r,dr[e]),r}}(n,e);o&&dr.splice(e,0,o)}}i.addSeries=function(n,e){n=tr(n,e=null==e?kn.length:e,ge,Pe),kn.splice(e,0,n),mr(kn[e],e)},i.delSeries=function(n){kn.splice(n,1),te&&ue.splice(n,1)[0][0].parentNode.remove(),dr.length>1&&dr.splice(n,1)[0].remove()},kn.forEach(mr);var pr=[!1,!1,!1,!1];function gr(n,e,r){var t=r[0],l=r[1],i=r[2],a=r[3],o=e%2,s=0;return 0==o&&(a||l)&&(s=0==e&&!t||2==e&&!i?d(pe.size/3):0),1==o&&(t||i)&&(s=1==e&&!l||3==e&&!a?d(Te.size/2):0),s}_n.forEach((function(n,e){if(n._show=n.show,n.show){var r=yn[n.scale];null==r&&(n.scale=n.side%2?kn[1].scale:Sn,r=yn[n.scale]);var t=r.time;n.size=z(n.size),n.space=z(n.space),n.rotate=z(n.rotate),n.incrs=z(n.incrs||(2==r.distr?Cn:t?1==bn?qn:Qn:Hn)),n.splits=z(n.splits||(t&&1==r.distr?Rn:3==r.distr?be:xe)),n.stroke=z(n.stroke),n.grid.stroke=z(n.grid.stroke),n.ticks.stroke=z(n.ticks.stroke);var l=n.values;n.values=t?F(l)?re(Gn,ee(l,Bn)):N(l)?function(n,e){var r=Dn(e);return(e,t)=>t.map((e=>r(n(e))))}(Gn,l):l||Un:l||we,n.filter=z(n.filter||(3==r.distr?Se:T)),n.font=fr(n.font),n.labelFont=fr(n.labelFont),n._size=n.size(i,null,e,0),n._space=n._rotate=n._incrs=n._found=n._splits=n._values=null,n._size>0&&(pr[e]=!0)}}));var wr,xr=i.padding=(e.padding||[gr,gr,gr,gr]).map((n=>z(s(n,gr)))),br=i._padding=xr.map(((n,e)=>n(i,e,pr,0))),kr=null,_r=null,yr=kn[0].idxs,Mr=null,Sr=!1;function zr(n,e){if((n=n||[])[0]=n[0]||[],i.data=n,r=n.slice(),wr=(Mr=r[0]).length,2==In&&(r[0]=Mr.map(((n,e)=>e))),i._data=r,Yr(!0),Tt("setData"),!1!==e){var t=Nn;t.auto(i,Sr)?Tr():at(Sn,t.min,t.max),Xe=!0,Ke=!0,Jr()}}function Tr(){var n,e,t,i;Sr=!0,wr>0?(kr=yr[0]=0,_r=yr[1]=wr-1,t=r[0][kr],i=r[0][_r],2==In?(t=kr,i=_r):1==wr&&(3==In?(t=(n=l(t,t,Nn.log,!1))[0],i=n[1]):Nn.time?i=t+86400/bn:(t=(e=o(t,i,.1,!0))[0],i=e[1]))):(kr=yr[0]=t=null,_r=yr[1]=i=null),at(Sn,t,i)}function Dr(n,e,r,t,l){Y.strokeStyle=n||X,Y.lineWidth=e,Y.lineJoin="round",Y.lineCap=t||"butt",Y.setLineDash(r||[]),Y.fillStyle=l||X}function Er(n,e,r,t,l,i,a){Dr(n,e,r,t,l),l&&a&&Y.fill(a),n&&i&&e&&Y.stroke(i)}function Pr(n,e,r,t,l,i,a,o,s,u){var f=a%2/2;gn&&Y.translate(f,f),Dr(o,a,s,u),Y.beginPath();var c,v,h,d,m=l+(0==t||3==t?-i:i);0==r?(v=l,d=m):(c=l,h=m),n.forEach(((n,t)=>{null!=e[t]&&(0==r?c=h=n:v=d=n,Y.moveTo(c,v),Y.lineTo(h,d))})),Y.stroke(),gn&&Y.translate(-f,-f)}function Ar(n){var e=!0;return _n.forEach(((r,t)=>{if(r.show){var l=yn[r.scale];if(null!=l.min){r._show||(e=!1,r._show=!0,Yr(!1));var a=r.side,o=l.min,s=l.max,u=function(n,e,r,t){var l,a=_n[n];if(t>0){var o=a._space=a.space(i,n,e,r,t),s=a._incrs=a.incrs(i,n,e,r,t,o);l=a._found=function(n,e,r,t,l){for(var i=t/(e-n),a=(""+h(n)).length,o=0;r.length>o;o++){var s=r[o]*i,u=10>r[o]?W.get(r[o]):0;if(s>=l&&17>a+u)return[r[o],s]}return[0,0]}(e,r,s,t,o)}else l=[0,0];return l}(t,o,s,0==a%2?Me:Fe),f=u[0],c=u[1];if(0!=c){var v=r._splits=r.splits(i,t,o,s,f,c,2==l.distr),d=2==l.distr?v.map((n=>Mr[n])):v,p=2==l.distr?Mr[v[1]]-Mr[v[0]]:f,g=r._values=r.values(i,r.filter(i,d,t,c,p),t,c,p);r._rotate=2==a?r.rotate(i,g,t,c):0;var w=r._size;r._size=m(r.size(i,g,t,n)),null!=w&&r._size!=w&&(e=!1)}}else r._show&&(e=!1,r._show=!1,Yr(!1))}})),e}function Wr(n){var e=!0;return xr.forEach(((r,t)=>{var l=r(i,t,pr,n);l!=br[t]&&(e=!1),br[t]=l})),e}function Yr(n){kn.forEach(((e,r)=>{r>0&&(e._paths=null,n&&(e.min=null,e.max=null))}))}i.setData=zr;var Cr,Hr,Fr,Nr,Ir,Lr,Vr,Or,jr,Gr,Br,Rr,Ur=!1;function Jr(){Ur||(j(qr),Ur=!0)}function qr(){Re&&(function(){var e=L(yn);for(var t in e){var l=e[t],a=Ln[t];if(null!=a&&null!=a.min)V(l,a),t==Sn&&Yr(!0);else if(t!=Sn)if(0==wr&&null==l.from){var o=l.range(i,null,null,t);l.min=o[0],l.max=o[1]}else l.min=y,l.max=-y}if(wr>0)for(var s in kn.forEach(((t,l)=>{var a=t.scale,o=e[a],s=Ln[a];if(0==l){var u=o.range(i,o.min,o.max,a);o.min=u[0],o.max=u[1],kr=n(o.min,r[0]),_r=n(o.max,r[0]),o.min>r[0][kr]&&kr++,r[0][_r]>o.max&&_r--,t.min=Mr[kr],t.max=Mr[_r]}else if(t.show&&t.auto&&o.auto(i,Sr)&&(null==s||null==s.min)){var f=null==t.min?3==o.distr?function(n,e,r){for(var t=y,l=-y,i=e;r>=i;i++)n[i]>0&&(t=p(t,n[i]),l=g(l,n[i]));return[t==y?1:t,l==-y?10:l]}(r[l],kr,_r):function(n,e,r,t){var l=y,i=-y;if(1==t)l=n[e],i=n[r];else if(-1==t)l=n[r],i=n[e];else for(var a=e;r>=a;a++)null!=n[a]&&(l=p(l,n[a]),i=g(i,n[a]));return[l,i]}(r[l],kr,_r,t.sorted):[t.min,t.max];o.min=p(o.min,t.min=f[0]),o.max=g(o.max,t.max=f[1])}t.idxs[0]=kr,t.idxs[1]=_r})),e){var u=e[s],f=Ln[s];if(null==u.from&&(null==f||null==f.min)){var c=u.range(i,u.min==y?null:u.min,u.max==-y?null:u.max,s);u.min=c[0],u.max=c[1]}}for(var v in e){var h=e[v];if(null!=h.from){var d=e[h.from],m=h.range(i,d.min,d.max,v);h.min=m[0],h.max=m[1]}}var w={},x=!1;for(var b in e){var k=e[b],_=yn[b];_.min==k.min&&_.max==k.max||(_.min=k.min,_.max=k.max,w[b]=x=!0)}if(x){for(var M in kn.forEach((n=>{w[n.scale]&&(n._paths=null)})),w)Ze=!0,Tt("setScale",M);nr.show&&(Xe=!0)}for(var S in Ln)Ln[S]=null}(),Re=!1),Ze&&(function(){for(var n=!1,e=0;!n;){var r=Ar(++e),t=Wr(e);(n=r&&t)||($e(i.width,i.height),qe=!0)}}(),Ze=!1),qe&&(hn(O,J,Ne),hn(O,R,Ie),hn(O,G,Me),hn(O,B,Fe),hn(Z,J,Ne),hn(Z,R,Ie),hn(Z,G,Me),hn(Z,B,Fe),hn(C,G,_e),hn(C,B,ye),P.width=d(_e*fn),P.height=d(ye*fn),gt(),Tt("setSize"),qe=!1),nr.show&&Xe&&(mt(),Xe=!1),_e>0&&ye>0&&(Y.clearRect(0,0,P.width,P.height),Tt("drawClear"),Tn.forEach((n=>n())),Tt("draw")),x||(x=!0,i.status=1,Tt("ready")),Sr=!1,Ur=!1}function Zr(e,t){var l=yn[e];if(null==l.from){if(0==wr){var a=l.range(i,t.min,t.max,e);t.min=a[0],t.max=a[1]}if(t.min>t.max){var o=t.min;t.min=t.max,t.max=o}if(wr>1&&null!=t.min&&null!=t.max&&1e-16>t.max-t.min)return;e==Sn&&2==l.distr&&wr>0&&(t.min=n(t.min,r[0]),t.max=n(t.max,r[0])),Ln[e]=t,Re=!0,Jr()}}i.redraw=(n,e)=>{Ze=e||!1,!1!==n?at(Sn,Nn.min,Nn.max):Jr()},i.setScale=Zr;var Xr=!1,Kr=nr.drag,Qr=Kr.x,$r=Kr.y;nr.show&&(nr.x&&(Cr=mn("u-cursor-x",Z)),nr.y&&(Hr=mn("u-cursor-y",Z)),0==Nn.ori?(Fr=Cr,Nr=Hr):(Fr=Hr,Nr=Cr),Br=nr.left,Rr=nr.top);var nt,et,rt,tt=i.select=V({show:!0,over:!0,left:0,width:0,top:0,height:0},e.select),lt=tt.show?mn("u-select",tt.over?Z:O):null;function it(n,e){if(tt.show){for(var r in n)hn(lt,r,tt[r]=n[r]);!1!==e&&Tt("setSelect")}}function at(n,e,r){Zr(n,{min:e,max:r})}function ot(n,e,r){var t=kn[n];null!=e.focus&&function(n){if(n!=rt){var e=null==n;kn.forEach(((r,t)=>{var l=e||0==t||t==n;r._focus=e?null:l,function(n,e){!function(n,e){kn[n].alpha=e,nr.show&&dr[n]&&(dr[n].style.opacity=e),te&&ue[n]&&(ue[n][0].parentNode.style.opacity=e)}(n,e)}(t,l?1:vr.alpha)})),rt=n,Jr()}}(n),null!=e.show&&(t.show=e.show,function(n){var e=te?ue[n][0].parentNode:null;kn[n].show?e&&vn(e,an):(e&&cn(e,an),dr.length>1&&pn(dr[n],-10,-10,Me,Fe))}(n),at(t.scale,null,null),Jr()),Tt("setSeries",n,e),r&&Pt.pub("setSeries",i,n,e)}i.setSelect=it,i.setSeries=ot;var st={focus:!0},ut={focus:!1};function ft(n,e){var r=yn[e],t=Me;1==r.ori&&(n=(t=Fe)-n),-1==r.dir&&(n=t-n);var l=r.min,i=r.max,a=n/t;return 3==r.distr?(l=b(l),i=b(i),w(10,l+(i-l)*a)):l+(i-l)*a}function ct(n,e){hn(lt,J,tt.left=n),hn(lt,G,tt.width=e)}function vt(n,e){hn(lt,R,tt.top=n),hn(lt,B,tt.height=e)}te&&hr&&wn(en,jn,(()=>{nr._lock||(ot(null,ut,Dt.setSeries),mt())})),i.valToIdx=e=>n(e,r[0]),i.posToIdx=function(e){return n(ft(e,Sn),r[0],kr,_r)},i.posToVal=ft,i.valToPos=(n,e,r)=>0==yn[e].ori?u(n,yn[e],r?Ge:Me,r?Le:0):f(n,yn[e],r?Be:Fe,r?je:0),i.batch=function(n){n(i),Jr()},i.setCursor=n=>{Br=n.left,Rr=n.top,mt()};var ht=0==Nn.ori?ct:vt,dt=1==Nn.ori?ct:vt;function mt(e,t){var l,a;jr=Br,Gr=Rr,l=nr.move(i,Br,Rr),Br=l[0],Rr=l[1],nr.show&&(Fr&&pn(Fr,d(Br),0,Me,Fe),Nr&&pn(Nr,0,d(Rr),Me,Fe)),nt=y;var o=0==Nn.ori?Me:Fe,s=1==Nn.ori?Me:Fe;if(0>Br||0==wr||kr>_r){a=null;for(var u=0;kn.length>u;u++)if(u>0&&dr.length>1&&pn(dr[u],-10,-10,Me,Fe),te&&Kn.live){if(0==u&&fe)continue;for(var f=0;ue[u].length>f;f++)ue[u][f].firstChild.nodeValue="--"}hr&&ot(null,st,Dt.setSeries)}else{var c=ft(0==Nn.ori?Br:Rr,Sn);a=n(c,r[0],kr,_r);for(var h=E(An(r[0][a],Nn,o,0),.5),m=0;kn.length>m;m++){var g=kn[m],w=nr.dataIdx(i,m,a,c),b=w==a?h:E(An(r[0][w],Nn,o,0),.5);if(m>0&&g.show){var k=r[m][w],_=null==k?-10:E(Wn(k,yn[g.scale],s,0),.5);if(_>0){var M=v(_-Rr);M>nt||(nt=M,et=m)}var S=void 0,z=void 0;0==Nn.ori?(S=b,z=_):(S=_,z=b),dr.length>1&&pn(dr[m],S,z,Me,Fe)}if(te&&Kn.live){if(w==nr.idx&&!Ke||0==m&&fe)continue;var T=0==m&&2==In?Mr:r[m],D=fe?g.values(i,m,w):{_:g.value(i,T[w],m,w)},P=0;for(var A in D)ue[m][P++].firstChild.nodeValue=D[A]}}Ke=!1}if(tt.show&&Xr)if(null!=t){var W=Dt.scales,Y=W[0],C=W[1],H=t.cursor.drag;Qr=H._x,$r=H._y;var F,N,I,L,V,O=t.select,j=O.left,G=O.top,B=O.width,R=O.height,U=t.scales[Y].ori,J=t.posToVal;Y&&(0==U?(F=j,N=B):(F=G,N=R),I=yn[Y],L=An(J(F,Y),I,o,0),V=An(J(F+N,Y),I,o,0),ht(p(L,V),v(V-L)),C||dt(0,s)),C&&(1==U?(F=j,N=B):(F=G,N=R),I=yn[C],L=Wn(J(F,C),I,s,0),V=Wn(J(F+N,C),I,s,0),dt(p(L,V),v(V-L)),Y||ht(0,o))}else{var q=v(jr-Ir),Z=v(Gr-Lr);if(1==Nn.ori){var X=q;q=Z,Z=X}Qr=Kr.x&&q>=Kr.dist,$r=Kr.y&&Z>=Kr.dist;var Q,$,nn=Kr.uni;null!=nn?Qr&&$r&&($r=Z>=nn,(Qr=q>=nn)||$r||(Z>q?$r=!0:Qr=!0)):Kr.x&&Kr.y&&(Qr||$r)&&(Qr=$r=!0),Qr&&(0==Nn.ori?(Q=Vr,$=Br):(Q=Or,$=Rr),ht(p(Q,$),v($-Q)),$r||dt(0,s)),$r&&(1==Nn.ori?(Q=Vr,$=Br):(Q=Or,$=Rr),dt(p(Q,$),v($-Q)),Qr||ht(0,o)),Qr||$r||(ht(0,0),dt(0,0))}if(nr.idx=a,nr.left=Br,nr.top=Rr,Kr._x=Qr,Kr._y=$r,null!=e&&(Pt.pub(K,i,Br,Rr,o,s,a),hr)){var en=Dt.setSeries,rn=vr.prox;null==rt?nt>rn||ot(et,st,en):nt>rn?ot(null,st,en):et!=rt&&ot(et,st,en)}x&&Tt("setCursor")}var pt=null;function gt(){pt=Z.getBoundingClientRect()}function wt(n,e,r,t,l,i){nr._lock||(xt(n,e,r,t,l,i,0,!1,null!=n),null!=n?mt(1):mt(null,e))}function xt(n,e,r,t,l,a,o,s,u){var f;if(null!=n)r=n.clientX-pt.left,t=n.clientY-pt.top;else{if(0>r||0>t)return Br=-10,void(Rr=-10);var v=Me,h=Fe,d=l,m=a,p=r,g=t;1==Nn.ori&&(v=Fe,h=Me);var w=Dt.scales,x=w[0],b=w[1];if(1==e.scales[x].ori&&(d=a,m=l,p=t,g=r),r=null!=x?c(e.posToVal(p,x),yn[x],v,0):v*(p/d),t=null!=b?c(e.posToVal(g,b),yn[b],h,0):h*(g/m),1==Nn.ori){var k=r;r=t,t=k}}u&&(r>1&&Me-1>r||(r=M(r,Me)),t>1&&Fe-1>t||(t=M(t,Fe))),s?(Ir=r,Lr=t,f=nr.move(i,r,t),Vr=f[0],Or=f[1]):(Br=r,Rr=t)}function bt(){it({width:0,height:0},!1)}function kt(n,e,r,t,l,a){Xr=!0,Qr=$r=Kr._x=Kr._y=!1,xt(n,e,r,t,l,a,0,!0,!1),null!=n&&(ke($,sn,_t),Pt.pub(Q,i,Vr,Or,Me,Fe,null))}function _t(n,e,r,t,l,a){Xr=Kr._x=Kr._y=!1,xt(n,e,r,t,l,a,0,!1,!0);var o=tt.left,s=tt.top,u=tt.width,f=tt.height,c=u>0||f>0;if(c&&it(tt),Kr.setScale&&c){var v=o,h=u,d=s,m=f;if(1==Nn.ori&&(v=s,h=f,d=o,m=u),Qr&&at(Sn,ft(v,Sn),ft(v+h,Sn)),$r)for(var p in yn){var g=yn[p];p!=Sn&&null==g.from&&g.min!=y&&at(p,ft(d+m,p),ft(d,p))}bt()}else nr.lock&&(nr._lock=!nr._lock,nr._lock||mt());null!=n&&(function(n,e){var r=me.get(e)||{};xn(n,e,r[n]),r[n]=null}($,sn),Pt.pub($,i,Br,Rr,Me,Fe,null))}function yt(n){Tr(),bt(),null!=n&&Pt.pub(rn,i,Br,Rr,Me,Fe,null)}var Mt,St={};St.mousedown=kt,St.mousemove=wt,St.mouseup=_t,St.dblclick=yt,St.setSeries=(n,e,r,t)=>{ot(r,t)},nr.show&&(ke(Q,Z,kt),ke(K,Z,wt),ke(nn,Z,gt),ke(en,Z,(function(){if(!nr._lock){var n=Xr;if(Xr){var e,r,t=!0,l=!0;0==Nn.ori?(e=Qr,r=$r):(e=$r,r=Qr),e&&r&&(t=10>=Br||Br>=Me-10,l=10>=Rr||Rr>=Fe-10),e&&t&&(Br=Vr>Br?0:Me),r&&l&&(Rr=Or>Rr?0:Fe),mt(1),Xr=!1}Br=-10,Rr=-10,mt(1),n&&(Xr=n)}})),ke(rn,Z,yt),Mt=function(n){var e=null;function r(){e=null,n()}return function(){clearTimeout(e),e=setTimeout(r,100)}}(gt),wn(tn,un,Mt),wn(ln,un,Mt),i.syncRect=gt);var zt=i.hooks=e.hooks||{};function Tt(n,e,r){n in zt&&zt[n].forEach((n=>{n.call(null,i,e,r)}))}(e.plugins||[]).forEach((n=>{for(var e in n.hooks)zt[e]=(zt[e]||[]).concat(n.hooks[e])}));var Dt=V({key:null,setSeries:!1,scales:[Sn,null]},nr.sync),Et=Dt.key,Pt=null!=Et?Ce[Et]=Ce[Et]||He():He();function At(){Tt("init",e,r),zr(r||e.data,!1),Ln[Sn]?Zr(Sn,Ln[Sn]):Tr(),Qe(e.width,e.height),it(tt,!1)}return Pt.sub(i),i.pub=function(n,e,r,t,l,i,a){St[n](null,e,r,t,l,i,a)},i.destroy=function(){Pt.unsub(i),xn(tn,un,Mt),xn(ln,un,Mt),k.remove(),Tt("destroy")},t?t instanceof HTMLElement?(t.appendChild(k),At()):t(i,At):At(),i}cr.assign=V,cr.fmtNum=f,cr.rangeNum=o,cr.rangeLog=l,cr.orient=Fe,cr.join=function(n,e){for(var r=new Set,t=0;n.length>t;t++)for(var l=n[t][0],i=l.length,a=0;i>a;a++)r.add(l[a]);for(var o=[Array.from(r).sort(((n,e)=>n-e))],s=o[0].length,u=new Map,f=0;s>f;f++)u.set(o[0][f],f);for(var c=0;n.length>c;c++)for(var v=n[c],h=v[0],d=1;v.length>d;d++){for(var m=v[d],p=Array(s).fill(void 0),g=e?e[c][d]:1,w=[],x=0;m.length>x;x++){var b=m[x],k=u.get(h[x]);null==b?0!=g&&(p[k]=b,2==g&&w.push(k)):p[k]=b}O(p,w,s),o.push(p)}return o},cr.fmtDate=Dn,cr.tzDate=function(n,e){var r;return"Etc/UTC"==e?r=new Date(+n+6e4*n.getTimezoneOffset()):e==En?r=n:(r=new Date(n.toLocaleString("en-US",{timeZone:e}))).setMilliseconds(n.getMilliseconds()),r},cr.addGap=Le,cr.clipGaps=Ie;var vr=cr.paths={};return vr.linear=$e,vr.spline=function(){return(n,r,t,l)=>Fe(n,r,((i,a,o,s,u,f,c,v,h,m,p)=>{var g,w,x;0==s.ori?(g=Ve,x=je,w=qe):(g=Oe,x=Ge,w=Ze);var b=1*s.dir*(0==s.ori?1:-1);t=e(o,t,l,1),l=e(o,t,l,-1);for(var k=[],_=!1,y=d(f(a[1==b?t:l],s,m,v)),M=y,S=[],z=[],T=1==b?t:l;T>=t&&l>=T;T+=b){var D=o[T],E=f(a[T],s,m,v);null!=D?(_&&(Le(k,M,E),_=!1),S.push(M=E),z.push(c(o[T],u,p,h))):null===D&&(Le(k,M,E),_=!0)}var P={stroke:nr(S,z,.5,g,w),fill:null,clip:null,band:null},A=P.stroke;if(null!=i.fill){var W=P.fill=new Path2D(A),Y=i.fillTo(n,r,i.min,i.max),C=d(c(Y,u,p,h));x(W,M,C),x(W,y,C)}return i.spanGaps||(P.clip=Ie(k,s.ori,v,h,m,p)),n.bands.length>0&&(P.band=Ne(n,r,t,l,A)),P}))},vr.stepped=function(n){var r=s(n.align,1);return(n,t,l,i)=>Fe(n,t,((a,o,s,u,f,c,v,h,m,p,g)=>{var w=0==u.ori?je:Ge,x={stroke:new Path2D,fill:null,clip:null,band:null},b=x.stroke,k=1*u.dir*(0==u.ori?1:-1);l=e(s,l,i,1),i=e(s,l,i,-1);var _=[],y=!1,M=d(v(s[1==k?l:i],f,g,m)),S=d(c(o[1==k?l:i],u,p,h)),z=S;w(b,S,M);for(var T=1==k?l:i;T>=l&&i>=T;T+=k){var D=s[T],E=d(c(o[T],u,p,h));if(null!=D){var P=d(v(D,f,g,m));if(y){if(Le(_,z,E),M!=P){var A=a.width*fn/2,W=_[_.length-1];W[0]+=A,W[1]-=A}y=!1}1==r?w(b,E,M):w(b,z,P),w(b,E,P),M=P,z=E}else null===D&&(Le(_,z,E),y=!0)}if(null!=a.fill){var Y=x.fill=new Path2D(b),C=a.fillTo(n,t,a.min,a.max),H=d(v(C,f,g,m));w(Y,z,H),w(Y,S,H)}return a.spanGaps||(x.clip=Ie(_,u.ori,h,m,p,g)),n.bands.length>0&&(x.band=Ne(n,t,l,i,b)),x}))},vr.bars=function(n){var r=s((n=n||H).size,[.6,y]),t=n.align||0,l=1-r[0],i=s(r[1],y)*fn;return(n,r,a,o)=>Fe(n,r,((s,u,f,c,v,h,m,w,x,b,k)=>{var _,y=0==c.ori?Be:Re,S=h(u[1],c,b,w)-h(u[0],c,b,w),z=S*l,T=m(s.fillTo(n,r,s.min,s.max),v,k,x),D=d(s.width*fn),E=d(p(i,S-z)-D),P=1==t?0:-1==t?E:E/2,A={stroke:new Path2D,fill:null,clip:null,band:null},W=n.bands.length>0;W&&(A.band=new Path2D,_=M(m(v.max,v,k,x),.5));for(var Y=A.stroke,C=A.band,H=c.dir*(0==c.ori?1:-1),F=1==H?a:o;F>=a&&o>=F;F+=H){var N=f[F];if(null==N){if(!W)continue;var I=e(f,1==H?a:o,F,-H),L=e(f,F,1==H?o:a,H),V=f[I];N=V+(F-I)/(L-I)*(f[L]-V)}var O=h(2==c.distr?F:u[F],c,b,w),j=m(N,v,k,x),G=d(O-P),B=d(g(j,T)),R=d(p(j,T)),U=B-R;null!=f[F]&&y(Y,G,R,E,U),W&&(B=R,y(C,G,R=_,E,U=B-R))}return null!=s.fill&&(A.fill=new Path2D(Y)),A}))},cr}(); +`) + +func staticJsUplotIifeMinJsBytes() ([]byte, error) { + return _staticJsUplotIifeMinJs, nil +} + +func staticJsUplotIifeMinJs() (*asset, error) { + bytes, err := staticJsUplotIifeMinJsBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "static/js/uPlot.iife.min.js", size: 35191, mode: os.FileMode(420), modTime: time.Unix(1612357218, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _staticJsUplotIifeMinJsBr = []byte("\xc2.1\x8a`\xe3\x80\x002r'\x02h}`\x1b\xd3\x1b\xab\xaf\xa04c\xbd\xf6l\x0eqJ<\xf1\xb5\x13E\xfc(Qj}c\xb4\x8a\xe38\xb6\x18{\x1a!FH2\v\xff\xfb\xa6\xff\xafti\x87\xb7\x93pK\x83\xc5D)\u070fq\u007f\xfc\xf2\xa7\xd5\u05efWUGu\x8f\x1f\xf6\xa6\xafV=\xebB\xc8\\b0\x0e\xb7\f\xa8\x90\xbc\x8bg\xe4?\u007f\xbf\xfa\xff\xff\xf3\xf3u\xb4\xba\xf6\x89w\x8f3\x89\xee\x9e\xf3d\xaaTD\xed\x16\xa5\x95\x96F\xf7\\*B\x80HH\xe8d\xf1\xd2\xd9\xf6M\xe9\xb5j\xf3\xff\x8c\x99\xb7b\xc5MZ\xc8BU0\x14\xb2\xcd%*>J0\xb6\x9dDgeM{\xfdU\xa9\xae\xb1Y\x1b<\x98\x00\xb3\x8cZ\x92\xb5\xc1\x86\u007f\xf96\xf2W\xdb\u05b9p\xb0m\xd2\u032b\x88|\x1bw\xe6\x1b\xa4bd\xe0\xcbW\u036a>\ab\xffq\xa5\xebE<\xca)Vv\x17\xf2\x94\x1e\x03\x83_\x1e\xff\u007fS\xed\xdd\xf2\xbe\x01Hj\xbf\x93\xc2\xe6\xea\x87\xd8y]T$\xd7)W\xfe\xbd\x9b\x82s\xef\x9d\xf74\xef\xcd\f\x17\x83\x01\xb8D\xa0\x96\x03P\x01T\"\xc0\xe5zA\x857\xa0\xfe?Cl\"\xe9\x04J\x0e\xa4#\xd5i\xbfS\x94\xb4Q\xbb?\xc6\u02a1\xf4q\u0445X\xfe\xd2\u01d5\u0546\xacc\x02\x05\xfd\xbd\x92\xa4\xe9\xf6\x87\x99\xdfK\xeb\x1c\x9dt\xda\xfd\x86\xdb \x90\x90\x04q\xb2\u0777m\x83\xbf\x9f\x86iOv\xe6\xd3\xe5\xfep\xee\xe0{?\x8d\xe7k\xbb\xadx>wC\xcd\xef\xdd\xf7\xf5\x0f\u077a{T-\xb9d2\x11\x0eO\x87\xfd*3\xe7s\x97\x9d'z\xa9,IFM(\xe7+\u0166\xa5o\xe2<\u043f\x8539]\x1f\xd7\xe7\xe5~_>\x02\x81\xe0&\ub4bf\xba\xda\xcaa\x0fy\xcc\xd1Y\u07adB\xbc\x04\x1f\xf3\xca\x18\xb9!\xf6\xfa\xe8'Z-Z\"\x82\x04L\xaf\x90'Wu+\xb9\x1aZ+K\x8c\xfa\x95\x9fILf\xe1\xefO@\u0282\xe2\xa2N\"\as\xd09D\x12^\x01\x87O\x91\u07c7\xe1\x99\xca*\x9aR\x90I\xd5j;\xa3\xb8\x95\xe6\x82\xc1}\xc8\x05X\x00\n\\\xf49\xea/\xb8\x03\x8f\xa9\xac\x94\xe4\x18`\x92\xba\x12kq\x02\f\x040+\xa7c\x02\x04\x15\u04a7mJE#\xe2e\xe9\xf2\x1a\x8b\x83\xd5\xe4\xf9\xabB\xf2\xa1\x9alS\rD\x11\xae\u070cI\b\xaa\x92\tv\x0f)\xa4\x04\u059a&\a\x0f\xa0>\x9f4s\xe8\u03c6IU\u04b2\xe0\x13\xf9\xef\xd4+\xc9(|\x8d\u05b2\x18\xe3\xb9D\\$Y\u02faU\x1f;@\xcd0\xfd\x92\xb1\xae\x02\x1b\u02f7\xc3\xf0\x84\xeaQ\x9e\xa3q\x96\xc7b\xfcU\x80\x05\xf5\xb0&\xac\u0694F\xa9\x9d0\x9b\xfd\xa1:\xf6\xd4\xe4!\xe66\xa1tc\x8fy\xb8\xbbZk:0A0\x8bV\xb1:FE\x8c\xc1nEK\x16\x17\xa57\x99\x10\x95{?\xa0Cy\x8e\x10\xfb}\xc7\x02.c\x90\xfe\x19`A\x85qa\x94+6\xf0\xa70\xee\u00e9\xd9\xca\xed\"5\x90]\xbc\x88\xb8 \u023bH\f\xe4\x1d\xe3\x12\u5b30\xf9g\u0789\xed\x19\vu7\x1bcX~\x91\xe3\x15\x91u\xb5\x02\xb8\xb4F\x9c\u0722\x9182+\xaf\xe4>\xde\x04\x97\u0555nY\xb2\xb4I\x90\xe0\xc0\xbd\xb3.\xbe\x8b\xbb\xd2|v\x93\xbci\u2026p\xc5\xcd\u3f87wa\xf2\xff9\xcd\xdfF\xe9cJ\x9f\xcc\x14\xef\xf9\xdb\x02\x99\xe3^~bew\x1e\x87\xb0\x99\u0572\x98O\xad\xc8&\xd3\xf7\x05\xb0\xbc],\xa1<\x16\xe7\xe7t\xf9G\xb0\xf7m\x94q\x1fc\x86TV\xd3\xde\u007f-\b\xf6`\xe5\xea\x92Y\xd0\xf6\xe8Q\xbf`\x1f+\\\x80\xcb\xf2\x17\xa0\x10\xe2..~\x870\xf6j)\xb2\xbf[m\xbc\x86Mo\xcc\v\xa0\xe5\xa4\xe3\x93\xfd[\xa2]\xdfXC,M\u05bb\xa3Q\x1c\xe8\xe7\x84\\q\xc0d%$\x8cP\xc6\xfd(\xd7\xc5\xfd<\xa0R\f\x05\xc72\xc5~\x8b\xdfS]\xef\u042d0\xff\xcc\x19\u05f1Z\\\xc7\x17\x03\x85i\xfe%Q\xfbS\xbc\xb7\xe8E\xb6.`ov\xe1\xefOIJ>\x1cj\xf6(\x1e\x95\xafzUY\xa8\x114\xfe\xc2]z\x8a\x9cC\u04c5E\u012f\x97\xd7,\xa2Q\xfc8+\x9d\xb2O\x1c]\xf1c\x976N\b\xf3V\x9e\xa6.\xa7/\x1dO\u0746\xe7~\xa6\xce \xa9o\xc2\n\x17\xcb\b\xa1\xb3\x87A\xeaYvLPQ#\uebd8\x05\b\xe5m\xad\xa0\xa1[K,\xd9\xfb\x1aC\xfd\x93\xf4\xf2k\xe8\x14\aX\t?\xef\xa2\xf7\xfe\x16.?\xe1\x82P\x1eQ\xc2\x01\x15K:o&\xea\x1b#\u007fo\xa5h\x8c\x02\xa3Y\xb5&I/S\xa0\x16NHeqw\x93\xea\x9a`\x86\xaa\xaf\x02j\xddj\xc3X\b\x8f\xbd\x9bxl\x96<b5\x88']\x01w]\xed\xd5\xc85\xab\x941\\\x10\x10\xb7\xc9Ap6=K\x9e\x88\x12[P)\xf4\xaey\xfc\x85\xc3G\x8aX\xe6\xdf\xf6\xad\x02\x99\xb4\v\x1c}bW\xacU\x02\xb0\xe1l\x1e`\fH\xe2&v8\xa1\x91g\x86\u0499f\xcf\xe4E\x13\xd56\xb4,\xc2Af\u032e\xcb\xd9m\xc4\xf8\xf0\x1d\xa5\xa5]\xc9\x12mo\x873JOK\xf2\xea9\x13)\xf7\x8a\x1dU,\x81h\x17c[\x12z!~\x1b\x86LI9'\x19\xc9\x1c\x83(Y\x03-\x92\xac*\x1e\xbaJ:\x06\xa2\x9f\xf5\xaa\xc6t[0\xde\x14&.\x97\xd3~\u02b6\xc0*\x96m\xc5P\xa5o\x97^\xb0\x87\x1d\xeb\xd6\x05`\x84\u0192\a1\\\xe3|<4%\x10\x14`\x15\u007f\n\u0347\x11t\x84\xe8n\xe9\x04\xc0\\\u0198|\xc9G\xa8\xbd\xb7~F;c\xbf\u0beb\xf3\xc9v\x96K\xf8\u01bd|K\xf8\x18\xb91$\xaaU\xdd\x13\x05OZ\xfeH\xd5.\x85L?V\xd3\xf4\xfe\u0650\xe8\xd1\a\xd1r\x1d\t\xf3\xdf\u008a\xe1*\xb2m\xe6\f)\xe1\x19\n\x87\xa7\xf2\x15\x17\xbc{\xc3\xf8\x95\xbc0\x1c\xfa!\x0f\x9f\xc1\xec\x13\xce\u07bb\u01a8\xbd\xf3a\xa0+\xbc\x12\u064f\xeb\xd2Vx\xb3A\x92\U0007ec67g\\\xa2C\x8e\x8d\x96\u022d\xc2~\x11\xe9~\x9f\xd0\xf5\xfd\xe7\x81h\x9e\xb9\x04\xf0\x80af\n\xc1\xb4\xe8}\x82\x9e\xbe\xec\xf9\xf3\xd0\v\x8a(\u0759\x00#\x89\xe7&\xea\xc18i#\x1d$\x98i\"\x03\xcd~\xb0ZV\x12\xbb\x9b\xe2\x96\xd2b\x0e\xf2\x9c[\xf0st<H\xbf\xee\x85\xf5\xaeQ\x13\xc0\xf6\xc7\xe4q\xf6W!\x8f\xa9\xefDP\xff\v\x1a\xd6B{\x13\u007f\xb9\xdfC\x13\x82\xf7z\x98A\x87\xcfJ\x14\xa7rxI<D\x90\x01K\u0401\xfe\xb85x\xf4\xe4\x1a\x00r\"%(\xb3\xbdp\x9fe\xb8?\xdf:\x1c,\x9f\xb3U~\xe6(2>\xbb\xf9\xb0\x90\xac\xf9\xc1\xa9\f\xd7\xec`\x8e\x03;\xbaK\xef\x00\x8f\xdd.\xf0\xf8\x158\xcc\xf2\xd4\xd2\xf9\xa4\x14\xec9:\xd4\x1a\x03\x81\xf1Rf>xy\xa36\xc0\xe4\xdcl[f\u00d9v\xe4-%5\xb3\x91\xe1|\x17\x82+`\u3fd4,\\+\x97\xe1\xc9o\xce1\x9c\xb9\xedR\x9a\xdc\xe1.\x9a\xc1Bv\xe8\x82\xd3LhW\x0f6\xde\v!\xbaD\x8d\x1c\xdd\xed1\xdf\xdc)g\xe6\xb8\u304f\xd5\xd5V)\x92\xe5\xe5j1\xea\xf0\xbf\xc1[R\xdc\x1dj\xfa\x8f\x1br\x9a\r\xe6/\xc9i\x90\x1f~\x8b=Z\xd8\x13\r\x93d)}\\8\r\xcc\xf4H\xa1\x0f\x8a\x0e\xf9t$\x81\xabL\xba\u00b1\xf4p\u007fR\xbb\x0e\xec\x82\xeb\a\xadl\xc5s\xd4\xfaQ\x17\xf9{Jo'\xc4\xc7Y1\xcf\xdfm\u8d11w\xf0K\x8f\xf0\xa7\u07e4~\x9c\x85\xac\xe7i#\xf811&#\\\x86UW\xbfy\x80\x97\xe3\xfaD\xe4E\xd2\x1c:\u0618&\f}\xb2\x8d\xbbG\xab\xf8\xd9p\xc3t0\xa7\xb6S\xab!\xe2:\xe0\xb1\v\xfbE\x00\xfd1\xfc\xd6G\xe2\x87\xfd\xe0\x02Q\xe9\xa2M\xd8x\xd1\xd7d\xb3_\x03\xb7m\xeb7\xc9\xd0d\x1b\xbc\x92K\xe6\x11\x93o\x1eb\xb6\x1dU\x13'\x1a\xf9\xb4=\a\u02e0\xb6\xbb\u0754\xbe\x98=\r9sg\xa3\xfb\xf7/\xc3\x0f>:\x1b~\xff\xd1A\x0f?\xf7\xb7\x1f\x87\xe2\u01f5l\xb8\xed{\xa7\xfc\xc8>\xaf\xb0L\xf7\x89R9\xec\xc2|\v\xe0\xad\xdd,d\u00a8KJ\xfa<\\%`m\xf0p\xc7\x0e\xc4\x01L\xe6\xe4\xd40\x9cS\n6p\x86vO\xf6l&v\xf3h\x9c\xffw\xac\x1bt\xf9\x89\u0437?\x1f\xe8B\xf7\x9f\u058c\xfe\xfak\xb9\xfc\xff\xe3g\xf3-;\xbd\x96\b\xecW\u07c9\x84\x8f\xa6\x138M\x9f\x86\xb4\xc6\xda\xeeN\x8b\xef:\u018eW\xcdRU\tV\x98J\xe6&\x86\x0e\x82\x12<r\x92\xc4\xf5\xaf\xbcRbH\\\xe8\xb2\xe3\x18e[F\x1bhL~ji\xa1\xe1\bB!ry\xf8;R\xb4\x1d\xeeY\x91\x88\xbe]\a\xce\x01K\xe1Y\xa5\xfd\xb5\u007fR\x16ff]\b\x13&\xeb3\xcfM`-\x8a8cr\xe7\xab\tB\xdb\x12f\xe0\r\x16I\xe8\u007f\xcc)\u00835\x04\x8f\x8b\xaf\xb1k\xb3\x84\xe0\x98a\xfb^\xbc\xdd\xc1\x8e\xf7\xfd%\xdf\x1b\xc7\xdc8\x9dq\x8f\xfea\x8f\xb1-l\xe0\xf4\xc8\xd6\xdeP \xb1\x9f\u007f\xa2\asn\x17\xe7/{\x94\x1f73\xec\xc3U8\xb8\xc1\xfc\xcc\xd0\x1e\xe6\xdb\v\x0e\x03\xc6\x1a[\xdeM\xb9\u0783\x1c\xaf\xea\x8cZ\xdf\xdd\x1ca\xf7K\f\x14\x9a\\-\x92k\xea\xe6I5\xbd\u07cc\xc3Rk\x10\x19\xcczG\xad\xa7\x9b}\xb8\x81\x95O0\xdd\"\x1dw\xff\x85\xf1\xd9\x1c\x89\xef\xa0\u0259\xfa:\xe1\x04'8\u1e41\xc0\x89ENO\xf1\x87\xf8.\xfe\xa5\xc9\xc5\x17i\xe1\xc1\xbb\x97x\x16\xdf\xc5?\u017f\xe0\xdf\x18\x9f\xe3\xe7=\xb9_\fa\xe8^\xe2\xfb#\x94\x13\x83g\xf4\xe9\n\xf8\x80g\xfcv\u01ffu\x13\x97\v\xa5c\x1e\xfe\xd3!\xcde\x92\x8c\x1e\xf6\xefTm\x1bz\xfb\x9d\bn\xec\x1c\x03\ub2aa\u025c~\f\xdbz\xfa5i\xde.G\x19\xe7uoVuK\xbel\x8b\u0655g!\xffj\xbd\xd9<\xd2\xe7\xe1v'\xd4\xdc*=\xc7\x04{ME\u00da)c6\xe8Hu\xd2\xf0\xfbJ\xc59(\xab\xdd\xffC\u0701\xe6mfbV\x83V\u0656\xb1\x13t\xc90\xd5\xc1\xb2t#\xc3\x15OS\xdd\xd4\xc1f\xf0D\xe7\xaan\xcbhz\xf4\xa0\xc64\xb7/\xa8\xca\xdbc\x181\x91U2\xf1\xf2o\u05eb\x95u-\x9f\x11\xbat\xd8oW\xf4\xa5CJW\x16$\xaa%]\xb8\xd95\xe9\x1f(z'\xdcl\xee\xba\u02fd\xbd\x8e\x0f\xce4G\x9f\xfc1\x87\xb6\x0f\xee\xb9\xc7\xf5\xe9\xff\xfc\xbe\xfb1\xfa\u0188\x1c\xf5B\xbf\u06eb\xd8'g\xf6m\x06\xa9\x96X\u067b\x99t|I\x0f\xa6<\xc6\xf1\xf7\xe1!\xf2vy\x8b\x82\x01\xd7\xc0\xa3\xdcj,\xb9\xb5P\xb3\xfcm\xf7+=x\u0239\x00\xbd\xed|\b\x93\xf6\xb2P\x88Q\xb67!\xaeH\xb4T\xaf-\x15>X\xd1\x03\xd7\xc4\xe8\xed\x1c\x9aG\x1e\xe8\xaf>5\xa6u\x11\xdb\xf9\xb4G\x01\xb3Y_\xdf\u0604\u07f1\x1bS\u9455\xa6\xd1\xe1S\xd6\xfbx\xbc\x9f\u01ce\xdcf\xb5X\xb7\xfb\xbbt\xff\x95M^\xec|\u0739\xddm\x9b}\xfc\x06\xda0&\x99\xc4\x10\xf4\xf82\xbe\xfes<)\x84\x82\x93nn#\u06a4&\xdc\xe2\xab[}\u0329j\xa7\x90\x8aAne\xe5u\u0790\x98\xd5;\xbc\xdc\xe9\xddF\xc4\xe7\xe0\x8b\x19\xa2\xe6l\x00R\xf8\x80\x89y\xf57\xff\x15\xfb\x86\xb7\xc2+<\x15^c\xd9\r\xf9\ti\xb7\x9d\x89Bg\xcam\tI\xfd0\xf5#M@\xfc\x18\x8a\xd9m\xfe\xb5\xe7\r\xd9{J\x88\u0308\xedG\xe2\xb2d\xfdWcJ75\x1a\x12Ks\xb3\xfem\x84\xce'\xae\xac\u05e0\xec6\x962\x17;\r0\xcaGm3\xc71\xdcJZ~\xb1\xca\xcaO\xa2\xb5\x00\xf2\x19\xb2\xb8bM\xcb\xfd\xad\x00i\xa0\xfe\x19Bz\x94K\x93`\xa3T\xbaB\xf7\x93H\x83\xd5GSJ\xbf)\x95\xe0M\x95C^'\xbd\xfc\x12\xdc1b\n\u0729\xc5\x1f@\x9dT<C\xe2\xc4\xe2;\x94N#\xfe9\x83\xac\xe3\xf9_S\x00\x8d\x04kq\xa6\xa2\x8c\x95\xb0Q\xc9\xca4R\xca\"\x15\x90e\xc3q\x9bVN\x96\xef\x82P7W\xb1=L\xe5^]\xbb\xfa\xa8\x01|\x16\xa9\xe2\u07b0\xe8f\xaeay7\xfaD\xd0.\t!\x985Oo\x82$\xa6?\xe1\x19\u506d\xb2\xfe\x10\x96\xac\u0106\xa8\xfc\xdaO<\x996\xba<7\x9f\u0544\xf1\xf3\x85\xa3q!-\xe0\xdb\xd1H\xb0\x91\xaf\vIQT\b\xa7\xfc\x11\xd5\xdcTA\x9b,\xd5iS\xa3\xdb\\\x1a\x8b\x8f7\x9e\x99\x0e0\u074e\xd3\xe3\x1b\xf2\xac\r\b\xef\u007fSF3\xe8\x11\x1bIRJ\x8c\x18\x88\xd0\u024dR\b,V\x156[\xc0$H\x96\xe5\xb5\fP9\x008[\xbc\xf4T\xa5Rq\x18-[\"\xb2e\xf2\x9b\xa2t4\r]9\x1fo\xa0\xb8F<\x99\xc3\x05W\x0e(\n\x92\xb3\xed\xa1\xf2f}\xb0\xe6\xb0!\n\xf9<\xf4\u045a\xd4\xf9]r\vp\xd5\x14\x98&\xe6\xc1P\xdah\xbe\xe6\xd6\f1\x0e\xf5\x9f\xa7\xb8\xd5\xe0E\xa6\xb2E\xa0\nn\u0516\xd4<\xe7w\x19D\x89\xa9a\x98\x92\xb8\x86\b\xecG\xa6\xc4\xe2\xe4\xf1q\f\x16'o{u\xf6\xc1CZ\xb2\xbacC#q\x87\xd0 9E\xca\x0f\x83\x85g1:\xf4\xed\xf5=\xfd\x98\xfb\xf9n7\x92\xd9\x1e\xedaz^\xa1!\x03_]\x84\xe4LY,\x94\x8c\xb3\xb0(\x8e:\x17\x1d\xb9\x97'\xef\x95\xf4-\x1e\u055c\x16\x1b\x93\x89\xe8\x87L\x96\x1d\xb8\xe2\xd6\xe0_\x97\xa0(,\xf5\xbf\x10\xe4\xa1\x0f\x86\U00011939\u0272]7\x9c\xff\xbco\x05\xf3\xbf\xe7V\xfc\u041d\xd2O&\x10\xb4w0\xff \xef<\xd5#\x0e\x00Vg?\xf1)\x92\xce\u007f\xe8\u0370\x98\xb6\xa7\xaeN\xfc\xbd\x968\x87\xb5\xd6\xe2\xdd\u0719\x8eS\xbfz\u007f\xeb8Q.\u007f\xd2\xdfb[\xc3\xdb>\x9f\xbbv\xb5\u04e5\u03de\xf9 g;t\xff\xd0sfu\xfc5&\xddZ\x01\xd885v\xd2\"\xbf\xe5\xf2\xdf\xf5\xff\xd9E\xbf\x91-\xff\x93v\x91\xd1f\x02\xafx\x88\xb2s\xe8@x\u07d7tT\xc5B\xf5\xb30\\\xde\v\xa8|n\xb2\xa1\u07de\x9d\xec\x88\xf6\f\xcbdC\xbc?\xfd\xd3\xd7\xd8\x14\x97\uf637\xb2\xbb`\x1fOxs\xb1\xb5\xa6C\xa7\xa0+Y\u0791\xde AN\xa8\xc9R\xc6\xe7\xcfRG)=\x82\x00\xaa>t\xfa\xbd\x11$\x91\x85>\x1e\xf7\x15\xbe/\xd9\xe5'\x1fkP\x8f\xaf\u0439\x14\"\xbe\xa2q\x96\x9aD\u03c5.G\xb4\xacF\x9eZQ\xb95\xa3\x00\xff\xfd\x9d\x8a\xc0\xf2\vSK\x8b\x96\x10g\xb5,M\x01\f\x1cr\u0529\u05acj\xefi\xa0s\n\x86\xcf\xff\xff\x8d\xf97\xa99\xc6*8j`;+\v\x13W%B\u01a45E6G\xbe\xb4C \xe96`d\xa9\xff\x16_uA)7$dv\xe8\xbdQi\u0205Z\xa3T\x00\x8f\xce\xedJ\xa1Y\t\x8e\x15\xfa\xb1U:%\xd7\x13\xcfa\x9f\x01b{\u0255\xb0\xe5\xa4\xf1\x9e\a\xea+\xdc\xea\xbaA\xeaG\\\x10\xc8a\xb2n8^\x80\xe2\u0337\xaf\u07feD\xf0\xe2\v9_n\x8f\x16\x8a\xbd\u007f\x9b\xc2\xddB\xb6z\x81cVV\xeb\x1d\x92\xd6\\\x83\x00\x0e\vI\xfd-\x93:j#\x8e3\u049a\f\xb6\x92\xf9$24\xc7\xf0\xf3\xf4\xfd\x94@\x05Dl/\x94\xb8\x11\xaf\x0e\x97\xf9\xff\xee\xa7[\xf5\a-1\xe9\x9f\xe3\xcfO\x1f\xc8\xfa\x03\xa2\xeb\x17\xdd\xc3Ip\xadE\u04d2(\xb2\x1f\xc9<\u1f81L:` \x950\xf0\xe66\x80\xe2\xe1\xd7\xf6\xf3\x839\xfd\x81Nm.\u0340\x9c\xf6\xcd\nM\xff\x12\x13ar,\r\xb1\xed\xa3\x1a\xba\xa4l$\xc0I\xac \xbf5\xd5F:J\x95\n\x06<\x1fF*7\x15\xe4\x00\uec184\x18\xa6\xb1\x0e\xdd\xf9\xf2\\\bE<_6\\T\x8e\xa7\x8a\x88\x1b\xf98\xaebJ\x11\u04e2\xd6\xdf\xfdw;~\xd6\xc6d\xa6\xf7\v\xfc\xa2\t)\xa1r\xa6\xbb\x8e\u00bb\xdcHp\x1d\xec8>\u04e9y\x0e\x81\nN\xdc\xf3{\x16,\x9b\u0666=~\x96\x14\x1dUm\xd7]o\xe8J\xf0\xb1t\xbb52\xd1\xfd!P\u06b8\xdf\xd2h\x06\xb1\x17TS#\x93]\x99\xc3g\x14Yrg\x8bP\x04)\x9c\x0f\xfdo\xf9\x9b\xcaz\xbd\x11\xc4u4\xe2ir\xe2\u0441\x10\xf5\u9966\u6e77\rC\x14&\x02\x8e\x8d\x9d\xffT2\xc5B|d\x05\xd6\\\xac\v\x92\v\xc5{\u04d3\xf9~o\\\x82@v*Hl\xec\\\x0f\x0f\x91\xb8^\f2\x8bo\xca`\xdeT\xdd\xec\xfe\xb7DU&\xd9|z\x84\xb9Zz\xcd+#\xd1\u00df\x1f\xa1\xb5\x83\xdb\x06\x84\xa4!\x82}\x1d\xee\xf4;\xaa\xf2\xe6\x10p\xd0\x00W-S\x8f\xab#\xb2\x01\x87\x8b\xb3\xca\x02\u060d\x8c\x04\xb8\x94\xa8S\x11\xfc\xa8\xa5\xe2'fYBLV\xc3\x15\u0448C\xd1\x12r\xf1\xc7V$\x9d\xd8\xe8\xe7(m\xf2\xbfr\xa1\x8d\x81\xc4U\xc1\x80\x94\x03\u00c5\x84\xe5\xe0\xf04O\xc2\xed\x809\xbc\xef\xfb\xecj~\xfd2D,\xf2\xe3\xfb\x06+8\xc0\v\x9c\xad\xc2\x19\xdb\xd9:O\xaa\xc4\f\u068bx\xa42a\xc5\xf3Y\xdf%+\xe1\xb2h6\xbbG\xddV\xf2\xc4\xeaBr\xcew\xe2\xf8\x966\xc6D\x05%\xd2,\x050& \u0418\xe8\xb3\xcdp\xcb\x18\xabI\x83\xb2a\n\xbe>\x8b6s\xb46\xfe~\u015cq\xd8\xf9\x9fZ\x16\xaeF\xe9y\xd8OS\xf0u\xc0\xbbpz\xf9\\Dg\xd4_U\xc1\x8eW`\x98\x94A\xbb\xadx\xf5\xf2\x9b7\xa4\x80\x14,c\x13\u008b\x02\u033d\x83f\x9aZ\xce\xd3\v$BX\xbf*;\bFZo\u1265\x90\u07d2+\xa34\x04\xa6\x15wk\b~\b\x8c\xd2J:\x9d\x1b\xda\xfbM\xb1B\xf2T\x1f@A\xb9\xfb>\xa1\xf3.\xb4o\xad\x92Q\xd0\x06\a\xe8\x9e\xcb%\x0e\xc5\xc2\xd8bo\xba0\xea6\x06\x9c8iyV\xa3\xd7\xf9y\x92\xc1\xf4\xf3\xec=\xfdtM6\xf9v\x03q\x8e\xb1\f[]\x06_`\x9e\x15\x82\x9e\u04fd\xcbbg{}\u0083\xafo\x10\xf6e\xf2{L~?Eg'\x96\xf6\xf3\x89_~vM6\xf53&\xbd_~\xed\x8f\xe7~\xfe\xe82\x17\x9c\xf2`\x87\xfd\x01\x9d\xe51l'MS|\u0226jE\x8f\xad\xf2\x99\xf0\xa6\xc2\x01\xb9$\xc00.\x1a\x1c\x92w\xdc\xedU\xfc\x90\u073a\xf2\xf6\x84\x95\xd5\xc7\u00d3J\xa1(\xddI]\x82\u0403\xbb\x83\x93,\xd9^Nu}M}\xd6m\xa5\u04ed\xe3\xaaW\xa9qg\x05o\xd4\xea\xaf.:\xfar\xec\xbbL_1\xc9,\xe1\xf3 \x93\xac\x86E\x83\xd6A\b\x92\x88\x02F\x95K\xd8\xf8#\xd6\u007fb,\xe9\xe91\xee9\xe3\xf2\x93\x80\xc4R\xa3\x95\x94u/1\x8a\x86a\xc9\x06\"d@X\xc0L\x11(H\xec\a\xac\xad\xcc\xf8Zwpc\b\x17A\xb9o\tw.S\xd6\xff\x03w\xf6\xbf\x1d\xb6\x92Y7t\x98\xb4\xd5\r\u027fc\xda\xec\x01\x0e\"\xc7f\u06eczo\xa3\xe16\x93\xb3\x9b\xdca\asv\x8b\x15\f}\x02_\xa5\xe7\v*\xacGcS\xef\xae\xd92\xbf\aK\xac\u07a13\xbb\xb7]XaW\xb6b9\xf0\xc8\xc8jo\xc8\xc2{\xc6C\u05eb\x97_(d\x80\xe5\\g}\xd2F\xfa*\x977\xda\x17\xb9\x9a\xddA/\xdb\xeb\x02D\u0591`X\xb8\x00\xd9\f.\xaem\"K\x9c\xf2\xe0\x8c\xd1\xf5J\x8f\x82\xdb\xd3\xd5>*\xd0`\xb8\xe6\xe9\xa7\xc5xJ2TO\u05d0\u02e68\x15\u7763/\xdbA\xc0\xf6\xc8\u00e7\xe4\xb6\xe4\x80\xc0\x83#\x04\u065c\x9fk|\x9a?\x86\xd5;\x1b\x99m\u00f9C\\\xe4\xf5=\xbeM\x06=\xb4\xec\xc1\xedh\xd8s\xf9\xe7\t\xe0\rW\x1f\xd4\xfc\x16\xe9!\xde\xc1;\xdb\xf7\xaeo\xc0\x00\x8e\ua2eb\xfcL\x9av\n\x91\u007f\x06\u0518\x9b\xdc\x10t\xab\xd6R\x154\xb3D \xado \xdf\xda\x10\x19\xd3\r\x95(\xb7\xe3\xe3\xa3\x1f&\u00f7\r\x9b\xa3\xaep\x9af\x13\xab\xf5t\x9bY\x8b~\xdbetp\xd6A\x87\a\xbe\x80\x05\x98\xe1q\x1e,\xec\u0124/\xec0\v\x86_\xafi\r\xce\xc5N\xc6\xeb\xb4\xc6Y\x9f\x9d\x03.k]p\xacw\x92T\xac:\r\x03a}\xb8\x96\x8c=!\x82\x02\xf6\xfd\xe4\"_\xad\u024ebG\x98@C\x86\x92L\xf7k\u0264\u009d3\xd6\x1a\xe2\xbe\x15NS\x8b\x14\x81\xf5\u3668i\x8d\xee\xa6.\x8agC\xed\xb5\xd31\xb3\xa7\x85\xe8\x81z\x8f\x8f\xa5{\xd3\xed\xab\xb5\u82c6I4\x94&\x16\xc2\u0585\xbd\xf0\x8a\xc5Jt\xd4\xd4P\xb0\xce\\\xa9!\xda\xf26T5g\x8e\"\xdb\xd1%\xee\xa7\xfc\r\xf9\x8e\xe2\x0e\xf7{\x95Bco\xa3\x1e\xf5\x9a\x18\x9aEC\xf1>\xa9f~u\xc1f{\x0f\xb5\xf13KaGfBK3\x1e\xb9\x9a\xd8\xd2S\xf4\u07dd\xee\xde\xd6\xf4\u0789\xcbB\xf9\xef3\xdc\xf7\x9b*\x15\xb5\x81\xf6\xac(\xd7\xe5R,e\xe0\x19*\u007f\xe9\x03\u05ed\xf1\xe3G\xb0_\x91u*\xd5\u030auAX\b\x15\b%\nVM\x88\x06\x1e\xf1\x89`\xe1\x93\xdd\xf5\ufa23\xb9\xdd\x12(w\xa2\x12-e\xf1RD;+\x15G\xca2/\x83]\x81\x84\x12\x94\x14\xa4\x9e\xa2\xd7p\xcf\xf2Y\x86C\xaaf5\x0e!\xbai)D\xa0\xb6\xd0!\x11\xea\xf1q\xc7fi\xff\b\x1e{\x10^\xf7\xd3\xc8\x19z\x1e\xa0!\x9f\x01\xbf\xbf\x8a\x91\xf5\xc1\xaf\x84\x01\xbe}\xb7\u0246\xe1\nB\r\"\x03`\xc6$\x03\x92}\xa8\xf3&\x03\x90*\x85M\xfe\xde\xd3H\u024f\x90\xe5\xeb\xf93\xf1\xb5\x8b_\xdb&B\x92\x1a\xf1\xa3bJLo\xbd\xa1\xd2S; \xc1Z\xf6 \xb6\xffn\xe6C\xb5\x90\x8e\xfc\xd5\xf0\xbb\u023eWx5$\xf3\xb0k\xa6.\xb7\xee!\n\xa7$\xeb\xee\x1c\u689e\xa2_U\xbd}K\xfb\xab\xfd\xf2\xac\x96\f\xc9\xfd\x9b\xb7bmk\xe1\x0fT\xa0\xe3\u070c\xf9jX\xc3&c\x92\xa7W\x98\x83]|\xa4\xe5^\xba4\x86\x8f\xf2\x91,\x93bk\x04U`V\xd6r\x96\u0396<\x1c\x81\xfd\x1c\xd6\xe4u\xa6\x89\xa8!m]\xfe\x84\xcd\x12b\xfa\xa5\a\x1e\xf45\x89\"\xe2\xe1\xe5D\n*rU\xc08p\xf5|\xbf\x80d\xbeD\x89\x87\x14d\x8a\x89u\x85\x9d\u0373k\xa3\xf0\xf2\xe5Xj\x148\xa1go\x8aP\u023fL-\xcd{$\xf6/\xac;\u01b7mr\"\x84\x87x-\xf4\xceY\x0f\xb4b\xc92|\xf9/\x9d,\x888\xfd\x9cm\xdc*\xec-\xe9\xb4\x03nf1|1g(\xf0R\t\xcf^\x93\xfc\xc7\xf6\xf6d\x83\xc6\x10\u04f6\x18\xd4U\xbf\u058b\u05a0\x1d*\x88}\x0ep\xf4\xaa1\xc34\x18\xc7\xf3\uc789\x06b2\xa6\xc2\xc9\u0114\xf83t\xbd\xbfy\x16\xcaz\x94\u015e\xa3\x18\xe4\x03\xe9\xb3\xd4S\x98\x99b\xef\"\xeb\xf0\u0514b\"\x9f\x15\xfa\xebF&\xfa\r\x95\xf0\x01;=\xb7A\xd4k\u05ae\x15a\xd92\xd9>\x85\xd9\xd1]\xd6\x01\x13\x02\xc9\xdd\fL\x89\xa8\xdc\xc2q\xae\x18\xc3\xfb\x0e\ue0cf\xd4\xf36W*\x1fE\xea\u9899y`\x88\\(dJ\xe8\xc8 9P\xfb\xfa\xd1H\xfe\x192\xf3\xbe0\b\xc1\xa7P\xe1\xb2D\u0652\xcd\x05e\x01\xfbp\xab\x19%:X\xf1\x11{\x01\u012e&0\xfd\u070f\xa9Sj\x85w\xab\xa5Y\xe8g\xd10M\x98h\x8aY\x8a\\M\xf7\xed\x97\x10\x88\xae\x1cIG\xffBB\xa6\t/n.\x14\xcc\xce\xf4C\xaa\xd4\xc6\xdeU\xb1\xf5\xe4\xa6t\x85\x02Lk\x00\x9cZ\xce.F\xe66\xae\xbfkE\xdf\xc8\u04f9\xe6\xb6\x15UW\xba\xeaB\x85\xa1\x95\xfa\t\xc8\xfb\x86p\x90\x95\x1bb\x16\xd3KJ\x8b\x04\x11\xfd\x11?s\x1c1.\xc4\x18gx\xa2\xdfe\xca]<\x12\x13V\x13\xcd\xeb\xabR\u02a5\x04/\x136\x1e\x02R\x8c\xc3\xc8S\x1b\xdf\x13v/\x13\x8b3e\xec\xf2 \xcf\xe3\xf1/\xa7D#\xf3\xeaF\xda\xf2\xe3&\u0097\xc8p!n\x1c\x89\xc6\xec2\x8c\x9ey\x0e\xe0}\u03a4qzy\x87\x90s\x90\xf5\xd9\xf2\bd\xcb]e\x89\x94d]R3\xa1@\xcc+\b\"\xf6\xdf\x06@\xc3]\x87/\x17\xe5m\xdd\x01\xf7\u029a\xf5\xbb\x9b\x99[\xf1\a\xf9\xf6\xa7|\xf4?4\x9a\xb4+\x12~J\x89T$J%\xb8\xdb\xed\u07bb\xed\u0301\xeb\xab)\x1dJ\x13?>\xf0\x8e$\x06\xdbz\x135\xf7\xcbH\xe6EF\xa2\x13s\x13\xedJ\xec\xe8\xaa\xceIRy\x04~\xed\x87\xe2j\xbc\xe8^Q\\z\xe1,\xfd\x8b\xfdN\xec\xd6\u05eb\xda&\xcaW\x80 \"\x8d\xfe\x13\x8d\x1c}\xab\x9e\xf1\xc2\xd6\xd9z\x16\xbd\xfc\x01H07\x9c\xe1\"[\xfb\xb2J\a\u05a4\xac\xb8\xec\xa1sTx\x84\xd9\x02\xa8\xe4M\xe3]\xe3\xc5\ueb19\x94\u02dc\x19\x19\xf1N\xa3\xf1\xd5W\xa6\x9cU\xcd\xcc\xfbS\xefz\x03SQC%\xda,&G:\xc1F|\xc4R\xaa\xd9\xc8\x13i\xdf\xe6\xedT\x9e\xd8&Hh$A\fgG\u0776\xba\xc3*\xacv\xcf\xcaN~\xaa]\xb4\v\xb6\xcejK\xfdi\u00f9\xba\xeb>\xe8zrJz\xd9lOVn'Q\xfb\x02\x8a\x0eM3\x0f\xaaWc\x91Y\x1c\"Vu\x94\xf8K*\xbe\xec\x1c\x91\xdb\x1c\xab\x98\xb5\x05\xd3\xc2y\xa1\u0147#\xedC\xffy\xf7\xca\u0683\xdfX\x1er\xb4\xbb\xb7\x06\x1d\xcaUh\xf4\xbfv\\\xa5\u0455o\xd0LD\u06d5*]\\\x95g\xa7N\x19\xf6\xb1$\f\x01\x04[&\x97\u0086\a\x97}D(\xa6m\x15\x0e\x87\x0f\xe5\xf2b4\xb2\xa1\xc5\xfc\xcd\x01\x14\x0f*\x10:\a-P\xe9\x11\xdf+BiV\xac\x8e\xfa\x8d\u0527[B\x1d\v\x87\xddBVo u\xeaJ\xd8\u0230\x1b\xb9$\x1e~\xb8w\xf4b\b\xeeK\xd3}\x02\xa8\xb51\u0668\xc00\xf3>\x1f;\xb4\xb4\x9b\r\rh\xa3_w\xc3V\xc8u\xebH\xb4\x12J\u0345Jj\xeb\x8dm\x92\xb8,\x12\x0e\x89\x92\xb3^+`y\xff\xb1\x1c\xca\xf7\x80.&<Ky\x1c;j\xb1!\x06\x1b\x8e9k\tK;,\x017\u0664\x0e\xe6\x11\n\nT\x0e\\y\xc4\xca\u017b\xbff@\xd02M\xc6b\xc0\u06d4\x8a\x90\xbc\xeap\x1a\xe5\x88:\x89K\xb9PS3\xad\xc2\xf5\xc0\xf6\x9b\xfd\xd1\a\t\xb36l*\xdb\xcf\xf7B\xa2\xb4\xa4\xcf\xc7X~\xd1\xfc\x13C\xa5\x1a\u02ec\x93d{\x88ej\r0P\x8d\xd67}\x17\u866c$k\x16\xb0F\xe8\xb0\x18\xa9\xa7\x01\x11\r\xaa\xb0\xd6\xd8p|\xcfT\xf8Z2+\x06\xa48\t\xf3O\xb0\xfd\x87XLD\x1a\x80*\x80\xc3i\xc8y7\x03,\x1e\xa3\x12\x15%\xb7\xde\u0740\x11\x02\x02\"\xac\ud3eb\t\x83\xa0\xe0z\x86\xe8I\xd0a)\xc0M\x93>LI\xaf\x05P\xba\xb6\xaa+\xdevN\xaf\xb4N,\ns\x1bp\xae\x15\xdc%[#\u00f8\xd0\x1955\xc6\x10\x86\x93\x9d\x19\x8e:\x86p\x0f\xe0a\xde*u\xebL\x06=wqn\xce\n\xb6\x8a\xb9q\u06d6b\xfaH\xe7hS;\u0524<\xa4\x86\x1a\u007f\xb6\xad\x8c/\xeeHlf\xd3\x1d\\gg\x95W#\xaaG\an\x05\xa9\xb3\xec\xbe-\u486db\xe7'\xbc\x02\xc7\xfcj\xbc\xd2\x103\xb1\xa7\x91\xb4|\x0e\xe8\x0f\xa6\u0083\xbd`2\xa4v\xac\xc0?\f_\x05\xe8\xedo\"U\xcc\xcbT\xce9\xeb^\"\xc5\xf1\x1d\xa9\x80\xaa//\x85\xe1\x15\xa0eAs\xba\x14h\x99\x02\x14%\x0e\xe1\u007f\x98P\r\x18(\x82\xbe\u0137\x10\v\xee\xf4J$\x9d\xc2\u02f0E4\t\xc3\xed\x84[\x15YT\xfe\u007f\x90\x97\xf6\xfcU\x05\xc1G5\xbd\x9c\x109GKB\x17\xa2\x8a\xa6\x16\xee\xda\\hM\x9b\xd4\xf0\xd6\b\x96\xf4\x85\xcdd\x88\x8a\xe4\x98hd\x97\xe6\xdf\x00\xbbs\x14iy\xba\x97\x94ut\xb9\x92\x85\x02@C\xde\x06e\x1ar\x1a\xad\xdd?\x02.\x815u\xf2\xb4z\x03e\xc2\u007f{\xc0\xab;\f\x9c\xa2x\xf0\u06e6(r\xfd\f\x03MT\f\x86\x9d\xe3\ak\xa1i\x901\xa5\xbc\x1b\u0569h\x97\x97i\xd9\xf9\x05\xc3RM\xe3\xd30L\xba\xd4T\xa1\u07ca\x82\xeb\xe6'Z\u0480\x9d\x9edJ\vg\x12qJ\x80ny\xfe\x8d\x97ng\xb8\xbc\x8b}q\x1dV\x8c|\xb0\xf4\xb9l\x89\xac{\x11\x91\x17Y\rX\u0609\xe7\x9e\xf5\xe9\x99\x19\x1c\x10\x82\x13\xef\\\xb4\x97\x1e\xdd\xd8X;\x17Y\xa6a\xd2\b\xf8[\x1e^\xf6\xc1\u007fN\u032c\x9a\x81\x952\xb4N\x82c\xbdK\ry\xfc\u038f\xe5\xa4N]\xd8\xc3\v\xa5\x1eo\xcd\xe4\x90\xc7\\8Uz3v)7p\xf2h\x88do\xd4&m\xf0O\xab\x10m\xfd\xf1\xda\x05\xfcE2q\xfe\x93\xdc4\xa5\x93\xa6G\xa4,\xc0\u007f\xfa\xa3qa\xe1X\u06a4\xf3\x8f\xd7\xd1\xf4\xdcS#\xfd\xc8\u05d6m\x1e\x86 w\xbc\x8epm[\x19&\xfbn\x87wK\xffj\x93u\xf1\xd3}\xeb\xf8$9\x8f\b^\f\xff\x03\u009b\xe5\xb1\xd8>\u070f\xe0\xa4\xfd\xe2vk\xbe\x06\xcd\xe0\xe0@\xf0:w*\x95\x92PL\xd8;\x01\v\xa7&\xb8J\x81\xceW\xda\xc6\xf7\x98:\xf6\xf3\xbc\x9b1\x8b2&1ao\x82\x8e\x9e\xa9^8<\r#\xfa\xcb\xdd\x06\u007f\xb39-\xa4\xfd\x8f\x1c4G\xaf\u05ea\xea\u06a6%\xd4{\xe1'\xe9\xe4\xe6\x1e\xe8:\xdf\x06\xf7\x82NV\b\xeb\x98s\xdat\x14\xc4\ta\xaf:\u9c97\xef\x14$0\x96F\xda\xd9\xdc\xc3F\x92\x99\xe4\x8a\xd2\u0307\x8e\xe7E4\xc2m\xf4\xe8q\"\xa0 \u007f\xf0\x17F\xf0% \xef\x8a\xe9l\xbap\x12\xb0\xe4#V\xe3\x96e\xbc$IW5\xbf\x87\x11\x1f\xd1\u007f\xf0$\x1er\x1b\xe9\xf1\xfa6\\BX\xf0s\x15\x9c\xd1*p\xa0\U000cb51a(?\xac\xd0:(\x97]\xa9\xaa\xc2\xf0\xe9\x12\u0ddeo$d\xb9\x91\xad\xe2~\xb5\x8b\xf0\xbcy\x97>\xa4\x16C\x80B\xc74\bH\r\xa2\x1a\xa6\xdfq\\\xc7qv\xce\xc6\xd9:7g%\xe6\xe5\xe4J\r\u06020\x0e}\xa8\xa92\x9f{\x85s\xe1\xc3y\xb5\x0e\xc0y#\x8d\r\xa9\xbcp\xaa\x02\u04fdQ\xf8\u4a5706 \x8a\xae\x8e\xf9\xdc+|\x14^G_b\\\xba\xf0)f\xefq\x88\xd1yW\x94|\xf6\xb1\xeftDvTt\x1b\xb4\u060e\x96\xb9\xc5-F\xef\b\u0614=Y \xe8\xc8P\x10~\x9b\x04'\xa6\xc1\x11\xbc\x97#T<V\xf2\xb1x>\xf6\xeb\x12\xa9v%A\u03f3\xcd\a\xd7\xf5\x85S\x0f,W\xa3\xa6\xbf\x9d\x16qU\xab\xe2\xb4,\u038f\xec\xb4\xd6 \xbf*\x9b\xde+#\xc7K\x01\x176\x05\xe90\x1e\xa1\x98je\x19-\xf7\x818\x1a&\x0e\x83i\fLE_\xdd\xe3\xe6j\xabI\x89M\x81\xe3Z\x98\x00\x16\x1b\xba\xdc \xabQ\xb9\xb9\xb5g\x0e\x04&\xe7\u29a0\xb5\x12`Y\x15^\x16%\xe8\xe6E\x86R\x11\x98\x97!\xab\x12\x93\x05\xf7z\xe5hyr\x19\x9fLa\xe3\xd3\xfb\xf5>\u058c\xe3\"l\u007f%\u06b9V\xb6Y\xc8\x18e\x81g-\xad\xa20FYgR\xb2\xe7\r\xe7y\x1c\x97\x13\x1eU\xadqI\x879&H4ma\xd9oE\xad\x9f\x93\u04ad\x1d\xff\x8c\xe4\xba\xfa\xe62\x0fW\xec\x13\x1b\xb1bhu\xef\t\u05d93\u043a\x9fq'\xce\xc3\u62a9g\x87\xc6\u061a8\xa2\nd\xc8@\x9b\xa3\x96\xf9b\rw&O\x96\xe2\x0ef\u0665.\xe7&\u04ac\aR\b\x88#\xa9\t_\xf7\xf1,\xb9&\xeff\x8a\x95\r\xd3Gk2\xf1Ev\xea\xd2\xccN\x12CH#9x\xbd\xbcg\xf2\xfaj\xcc'\xe9Y\xf3W\xc0,\x1a\x85\x0f\xf5\xbbU_\xa7\x139\x1d\xfa\x94|\xb2\x99\x1b}\xec?\xd7.0\xc9\xe4ErS(7b\x8d2\xf1\xd5\x00It\xc0\xcc3\u06ae\xa2.\x87\x05(\x18\xd3\x00N\xec2\xb8\xf9\xe2\xbd\xd9{\u0347\xfc\xee*D\xba\x98\x13\xf5*\xdb\xf0\xec\xc5j\x82)\xebH\xdc\xc8\u0501\xf7\x1c\t6j)\xcbW\x88\v\t\u0726\xddR8\xbc\xc0\xbb\x19k\x85Kp\x94#\xa4}4&\x19\xe6y\xf0\xa9\u0698\xd3\xec\u0168n\xcaI\r\x0eB9\x18\xb0\xd9\x1cAT\x0f\xe8\u06e3Ws6l\x9d'\x82j\xe0\xc8u\u016a\xe8\xa1\xd0W\xbf23\xc2\u05c9y(\xa0\xcalyz\xa8n\xfa\xbb\x19\x91\x9a\xbd\u04b9\xa8\u0788|A\x9d\x02^H\xb7\x88\x1eM\x81\x8e(\xf4OD7\x93dA\xabB\xdd\x19\x9a\a\xbb^\x18{wF\n\x8d\xa7\xe0\u0570\u03a5\xbdp\x80o\xb7\xaa\xc4n^K\xdew\xf9\t\xd0\x03<\xe8\xc0\xa7\xbb\xe9]\xdc\xe0\xeb^\x9a\xc4'Z\x13\x0f\x01J\x19\f\xf76\xe5B\x97&\x1dZ\x98Y\xc2A\xc37KEp\t6\xbc\x1b\xc1\xca%\x10b\xd5.IT!\xea\xe6I#OH\x93a\x83\xccb\xbf32\xdfl\xb6\xdd\r\x04\x9d\xab\xe2\xd1X\xe4\xc9\xe4\x05\xb3\xb4G\r\b\x82G\xd7\xdbfC\xc4H\xe6f\xc0\x98z\xcd.\xc3\xe5:RA\x84\xbed\x97r\xabB\xb5\xa4\x18/6\u07d4\x80\xb0\xe4\"j\u0770g_FeK\x83\x814\x9f\x15\b\x9a\x17=\"\xdc\u066cH\u0704\xd7\uc0f4\xc0\xe1+R\xfd\xd48o\x06\xe0\xe9\xe1\xac\x1a\xd6\xe3!\xb4b\x9a%\xbc.\xeb\x03Z\x1aBvz\xb2B\x06\u00d2\xaa,\xd5g\xda\xcc\x14\xaa\xceH\x83V\x1a[tn\xb8\u06cd\xebb\x18B\xf6\nltec\xc6\x13\xb9\x91\xe8r\xe7u\x94\xf3\xea\x1eu\u0344)YG\xbf\xb2IP\xb1-\x99\xf0\xdeQ\xc8<\\E\x83\xcbeP\xbe\x13)yx\xa4\x91c4\xd6\xceH\x8c\x89\xc3h4g\xc7\xd9-A9\xa5`\xa2\"\xa4|\xc2\xf0\x90\xf4!\xfe\x99i\x85\u0532\x9fP\rQY\xf3\x8c{{\x89C\xb9r\xca\xde\x11\xc9T\xbc\xdd)\x99!\x95\xdfM9\xd0\fK\xad\u03b5Ux\x19\x10\xfec\xe3\x00\u0232t1Q0\xbe\x80@\x04\x87\x89\xa00\xfd\u04d5\u0627\x18amXjn\x8b7\x05pb\xd4i<9\x80\x1eLL=\xbc\xbc[\xd5\xf1\xdf%\xdbi\x19\x16$\x1c@\x91\x17\t\x88\xe2T\xd01\xbf\x90l6\x84\xca`\x10\xf3\xbe\x03\xb6\x98\x00\xbb\x1b 59\x1cmk\ad-\u025a\xe4\xbd\xe3\x1ev\xd8oG3,\x97b\b\uc22a\x97\x88=\x94\x9b\x91:\xe6dK&z\x92H\x85\x9el\xa4\xe72\x1f\u075c~\x90i\xb4\x10I\xf7\u03ae9B\x19\x98B\xf9\u061b\xe3\x9aa\xc6\xe4\x90l\xc4\xe7\x1ep \xbf\xe047\xb5\xf9\x03\xbfv\ubea2\xbcD\x91~X\xaeY\xbb\x8a\"\u0534\xfdd-e\x1f\x1d\xca\x11b\xe4\rW\x11\xcaf\t\x94\x01v \xa8\x02\xbds\xd8p\x02\xc0\t\u06e6H\x90\b\xd3LQ\x13e\xe3+\xf3\x81\xbc-\xa21\xbaa\xe2\xe6\xbb\xf7\x16\xda\x0euu\xca \x1bG\vQ\x19\xc0\x99\xf17\x92T5\xd2)&%3\x9b\xfd\xd4IY\x11\xb6\xa7\x9a\xe5[\"\x1c\xfd\xd4\x19\xb13\xfdT\x82V2quJ\x11\xaf\x12\u94b5W.\x14\rG\xcex@W=\x13\x0e8p\xa3\xe2L\u06e0#\xe9\xbc\xf5\x80\x17\x88\x98qM\xe1%\x9b\xf8O\x86\x81\xb7h\u01a4\x8ce\x14s\x8d \x8a\xaes\xddT\xf5\x11\u031c\rd\xd3j\x02{\x87\x82i\to\x1f\xfaj1\xe6_T\xe0\xba\xc013\ue73b\xa7\xa5\xb5\x90\x94T4\xa0Q\x92\v\xd0\x02\xfb\xba+\x8e\xdcRRK\xe5h\u0748v\x12\xb9\xe9M\xe4\xb2s\x1dL\xca\u06886\xd0a\x87p3\x8b\xf5\x9d\xc0U\xfa\xcb\xd4c\xd8\x00\xf3;M\x9a\x01}\xa8u\x17\x06\xe4M-%\xea\xd6\xce\t\x98q\x9f\xa7p\x1e\x83\xe2\xc7FF\x97\x1cM\b\xe5\xb9w\x83c\u0471\xafu\xc5`\x14#/.\x9a\xf2t\x8cO\x94\xc1\xf5\xecRL\xf6\xb9\xadc\"#\x10\x14\x80\x05\xf4\x91\xb5?\x8b\xf9 #D|\x80\xf7.\x02*&\xb8\"\r#e\xb5\x9dM4u}-$%\f\b\xdcY+\x89\x97\n=\xc6%\xcb;\xf70\xf7\bC\x81_\xb8_\u0777\xd7aa\x8f0\xa9\x80\xabB\xc9p\x0e\x1b\x91,\xb3\x01\u0521\u02b1\xe1v\x15\xa5`\xb2J\u02dbm\xedE\u0259\xf6D\xfa\xcb7?:T\xff\xe6\xd3\x18\f\x99\r\xfe\u007f\xe5Ng\x00\xe9Y\xd7>j\xa3&\x81\x1e\xceXF\xfbE\xd3\xf3\xd7[\u007fLd\x19\r/Ym\x81\xbd\xe2\xe6\xc7\xf4\xa6\xa1\u0478\xcef\xad\x85p\x90a\x11\xf9\xe5\xb6[K\a\xee\xc08\xe9\x99\u00da\xecY3$$\x99\xa3\xa9\xc0\xe5:\x99\r\xde\xfa\x9dR\xa6\xc0\x8e)\xd2\x00\x83\xa4&\xb6\xd8cu\xc2R\u008b\xde\x04\xcb\u0217y\xe4\xf0\xd5c\xd7I#\xc1D\xa5\x80c^0gC\x90s:\xe0\xe9$\x1d\xa9\xd0(\xf0\xeb\xbf)\x97\x8c\x8d\x12I\x86\x1a\xfb(\xcf\xe0\x12F\x9bF\xceD\u072f\x8e{\xc7\x11Grp\x9cr\x9c\x96\x86\x98\xa9\x95\r\x15\xba\xce*\xc8<\xa8\t\x19\xe2M\v\xbc7\xa6-\xf6\xbe\x11*e\u026c\x11m\xa3\x101|\xd8\n[\r\xb3\x9c\xf2\x9a\xcd\xdd\xde\xf7Pac\x98\xfd\xfd\u01c2\x9a\u02b2u\xcaN6U$u\xc8\x01Q\x1f\u048e\xd7%\xb4-\bg\xd86F\xb4\x0fF\x03\xed[>:Tpq\xe7\xaey\x03\xc1\xa7%\x18\xbf#\a\x1e\xc2\xf6\fPiw\x9c\xcaM\xa2\xcb:\xa5\x84\x93\xe4Z8OJ\xd9\xf6\x1e\x06]U\xab9k\x11\x1f\xe6\xa0L\xccDcM\x86\x0f%6Y\xb3f5y\x8cM_\xe1\xa7n\xbc\xb41-\xadh-\x80 E\x11\x94ofw\x96\x05\x8e\xb2\xdeZ\xe2\xa8\x00\x96c\\P\x8cs#\x91\u0b65\xaa;\x82#\xb1jL\xb3\x8d\xdf4\xce!4\x12\x17\xb9\x8c\xb7\xbap\xc6Dz\xc9\xedIY\x02U\xeeQ\x12\xd9\xec\x1c>t\x8f\x8e6\xac&\x89\xf1\xa6\u041cO\x99I#<\x97\xf1\xb6G8\xb56\xc5e\t\x811+\xecV]\xa3Q\x8c\xbeMK\b6\xae\xdb\u0270\x10Y\x18\x18h\xd4\x19\xfa\xfd:K\xe3\xa2H\xdfU\t\xbeS\xb3u\xf8&3Ah\xa2,S\x06Tr\xc9\xc2\xed\x18a\xbe\x9f\xbd\xb0\xe6\xf3\a\xed\xe7\xc7\xe8\xe2\t\xa8\xa8\x80\xfb\xaa\t\t\x17o<\xbf*\xb4|\x18lv\n\x91L!\xccjB\x1ce\u050e\x0e\x91v\x83\xa4 \u0236Q\x9e\xe3\x83\xd4\x01\xc8H]\x03\xb1\xb8\bI\xd6y\x9f\x85\xf7\xf4\"\\\x1f\xe0\xc0\x0e6\xb0\x85\x13\xec\xe1\x06+\x98\xc3a\xc8;\x9a\x87\x97\xdah~\xa7\xa3\x96o\xf69\xd5\xcb&<\xa3\x06\x9f\xe6\xc0\v\x18\xc0\xc9D\x9d\xc4|\xcf\xf3\u05f0E\xac?\xf9\x97\xb2\n\r\xaa\xad+\\\x9b\xd4\xc1@=\xcb\xfa\x9f%H\x01H\x8c\u01f8_-\x93\xaaA\xb8\xa7\x01\xe3\x8cO\x99\x827B\x9a(\xbb\n#\xa4x\x92f\x93<\x03\xe3\xfdOL\xd5T\xe8/-\xc7\xcdp\xc1\xcea\xff\x88\xc7=;\x04\xf1~\xa4CqL\xb6\x8e\x16\x80\xa2\xda#:!\xba\x1fJ\xac\u04869J\xa0\x9c\xd5@\xe4\xed\xe1\x1aeTWh\u052dN\xe1V\u0508\u065e\x1a2\xd1g\x81\xf9&\u00a9Bd\xf9\x9d\xc7\xc2QE;\xfac\xed\x83\u07ca\xb9n|\xa1A\u030a\xef\xefS!\xd2{\xeb\v\xd4\xe8\xe6\u01a4\x10Z@4\x9b\x85\xeb\xb1x\x99\x8a\x1a\xad\xa0\xa8\xa9\u0183\xdfPY7\xcdM\x03\u0556\u0126l\xef\xc0\xb90]\x96\xea!\x14x\f^\x1aV\xf48\xab\x96V\x12^\f\x9e\xf8h\x9dU\xde\x00\xbe\vT\x19\xd0j\xb5\x10\xcaL<\")\x18\xdd\x1ed\xf5\xc5\x06P\xc8\x1a\xb3\xba\x87P8\xaa\x88\xa6\x82\xf1B\f\xb3hR\x8d\xc7\xfdW/)\vp\xa2\u0479\xe1\xbaL\n\xcaf\xc7\xeeE=\xc6\xe4!\x044\xe7\xbc\x002\x03/\xd68M\xdd\x17\x15Z\xac\x16\\\x99\xf1M\xe5~\xb7 \xcfm\x83\x10fP\x8f\xaa]\xa8\xd4\xf0o\xa0\b+\b\xe0\n\f\xd2j\xa7\xaf0\x03\x05\xaeM\x93\xeaR\x99\x89nG\u02afYLX\x00)G\xba\xbf\x91p\xd8\u016ai\xa40Z0\\}\xa6nC\xaa\xaa\xc7\xd3\xc9\u9258\x1a\x86\x9d\x1a\xab\x02\xbd\x1a\xb3A\xfbC\xc7\x12\x8d\xaf\x94\u0246\x81\xfb\xd71\x80\x17j\x11[R\xf1|\xd3I\x88<\xdft\x0e\xf9\xbci\xfbI\x9e\xed.\xfcM\xa9<;NRF\x92\"4\x85\xdc)\vy\xa1d\x1cR\u007f\xfc\x85\xba\xb8L\u007f\xf2U\x14+\xaf\x8d\xc8\xea\aN<:\u02a0\x10R\a\xd1\xf1\x85\u0145<\xf0f\xb0\xf1VB[]\x8e\xae\xb7\xdcs\xf8\x94\x0e\uad5b\xd8@I\xffl\xcbO\xb0u\xdc\"*9\xd7i!\xaf\x93\xa3\x1e\xfaD\xac\u02f8B\a\x0f\x89\xd1`fV\xc5\xe9\x1c\x9f\xb95\u07bb\x1e\xd7?nW#\x0e\xc8g\u0639\xc3\xe6\x80J\\w\x1e\xe7@\xa6\xb1\xf8\xb78\x8b\xfd\xfe;\x03\xa0 \xc6\xe0HJ;\x00\x96_\xe8\x89\xd9$iyk(\x9fy\xc1\x14\x8bg\xe7\xf3n\xf9\x90}\xbf\xf4N\x8a\xf1\xa1Co\x1eZ\xb5\xfb\xc0\xbc\x9d\xdc\xd9\xff\xa4\xf3\xa4\U000e4cff\xc8\x14#\xb1\x10}\xe0e-eb\x91\xb4\a-9\x8f\xee\xa7\u061f\u0296\x8c\xca\x14\x17F\xc6\xccR\x9eU\xb9\x9a\x0f\xd5\u007f\xf4\x1b|\xb8\x9ah\xa4n\xfa\xbd2\n\xdf\xf2\xa3\xfeQqj\x01\x83\xd3U\xc9Y\xfa8\xf4\xd9`\xbb\u0680\x8a\xdfsf#y\xf4\x1dG\x98B\xb0\x99e\x0e\x83!~\xe8\x05N\xf0J\x03p\xc6\xd1\x13\x13\u03a3\x8c@\xa6+\x02\xdd\u0188\x12S\xb2\xd7<\u014dv\x87CK1\xd17\u0362'{\x97\u01a4\xc1\x98\x1c\xcd\xce^\"X\xfa\xf2B\x91\xa3\xf7\f\x15\u078cF\x84\ue032`|t\x96\x1c\xb5\xbd\xc7ij?\x1e5\x9cx\x86\xf0-\xf2\xb2RA\xef\x95S\x1b\x95\x06\u0210S\x1d\x91\x06\u007fkb[\x10{\x03x\x18\u06e7\x87A\xf7\u008e\xa8XZ;\x8b\xb2\x8b\x80p\x0f\x12Y\x06\xc3\xf1\xce\t\xe0.\x1e\xac\xb1\xf0\x80ly\t\u03f4\x94\xf9\xa8\rx\x8d\xe5\u052b\xba\xdb\x11o\xd1kB\u01e7\xfd|\xdf:}\x99ra\xb2\x88\x9cBr\xaf\xdb_\xef\x9c\xd9\xe3~\xef\x98n]\xfc\xb6\xb5sR'Z\x90n\x1d\xad\x03\xb3)\xaca\xe1\xb6DRFZ\xc6\xc1X\x81K\x9b\xf9\xd5\xe5\x04[\xd0\v\xb0\xc8?(\xe7\x8cZ\u02a3\xeaG?\xf3*L!\x96>\xf1ZL\t\x06\x96\x8d)\xadp\xf0^E,\u00ba\x04!\xcf\xecXr,\x8c\xb0\x1dn/\xfbE\xd1&\xfc\x1c\x9f|\"/\xfcv\x9dW\xb7\xbf\xad\x1c\aC\u0102&\xac\x15\xc473u\xaa\x0e\r\x95\x13\xcbpi\xaat\x92\x14\xa5s\x18)\n\x19\xa6#4\xa2_\xf2:\xa1\x88\xea`\x15L9\a\x88D\xa1\x83\u0509Yq,\xd4\xedJ2\xfa\x0f\xc9t-\xb4>\x02\x133\x004\xf8\x8d\xb4\xf8/`8p\x98\x90\x9e\r\x19XQ\x9eX\x95r\vY\x17TJf\xca\xfd\u04be'x\n\u050b>U\u0264\x03\xec\x8d\xf6\aH\x06\x06\aba\a\x8e\x1aW\x89b\xa3\x99\x89\x12\x8aY\u048b\xb2\xa5,U\x12\x94\x8e\x84a\xae6\xcf\xeey\xa0\xd1z#\xe8!\x0f\f\atx\f2\xbd\u03a1\x19\u00963\xf7\x91P\x8c\aI.\x92j\x1c\xf3 !\x0e\x1e\x01\xb1\xab$\x85\xad(z\xa3\x99W\u0779\xd4}\xe4\x17\xf3h9xs\xa9\x91\x8c\xb3\xe1wO\xfa\u03ed\xa2\xc1\x17\xac\xc8[\x83jiJ\xd5'\x1fuI\x8a[\xb9\xda&Of\xee\xed\x94N\t9M\x192\xee\xba\x1aZ\xb7^\xec\x05\xee*\x04r\xa4\xad\x04c\xb7c\xc99\xcf\xc1.\xd6\f\xf4\xfc\xe5Dz4\xf0\xdbH>\xe2R<\xb7\t\"t5\x018\x04N\xaf\xfd\xf1\x86\xc2\v\xdf=j\n\x99\u065ef\xe7\xe5\x92\u06d9xau\x8a\x86\x04\xd6\u038a\x91fv\x91\xfelX\xe70\x02W\u071c9\xf7\x13\xf8\x03a\x12%\x8f\x8f\xb4C\xd8\u03b7q\xf5\u0460\xaa\x1bV\x8b\x1c5x\x96\x80\u045b\xd2\xd7\xf9\"\xf9E\x86$\r\xeb\xd4\xd1\xed\x81\xeaJ\n\x06\xed\xa5\x9c\xfa+]\xc2x4\x82H\xea?\u0290\x87\u007fm\x87\xfc\x9a.h\xe9}&C\u055a\x9asH61zz\x17\xb83\x18\xf6\xf7bY\xea\n\xab\x8e\xe3\x8c4s\xd7v\xe7\xee$\xc5\u04f2rl\xdc\x11|\xa41\x82\xa4\x1ev\xd6\u0586\x1b\x1d?\xab\x97\x8c\xe4\x93]\xfe\xc5o\u02da\x85D\x9e\x86X\xc0\ae\x9e1\xca:\xe969\x1f\xc8\xfbZ\xa4\xacF\x02?\xc3\xc7\xf5\x8c'\xb4( }\xd8\ab\u1a32\x93\xa6w\xa5\x13&6\x0fx$\xec\x1ca\xe7\xe3\x10\a\xbe\xf4\b\xb9\xd8\xe7;\xaf6\xe2@\xed\x87\x11\xb15\xfa[\x1fO\xd3K\xfa-\\]\xcc\u077a\u01bc2\x8b\xa2\xc1q\xb1\x95a\xc5\u056d\xd65\xf2\u07e8\x97\x98\xb6\xa6>\xd1\xd3C\x90$\u03da\xda!\xed\xfa\xcaq*9\x91\x9e\xaf{S\xb7_G\xf6RJ\xd6\xf5?\xd3\xf6\xd6li\xd2%\xbe\x1b_RH!)\xb7\xbe\xc1\xb8\x84\xe4i\x8c\xbd0\xf0\x81\x98tI\xd9tV\x13\x0f\x81\xd0Wp*i1\x9c\xaal\x9d\xc8Y\xea\xad\x17hC\x11\xaf^\xb1\xb9,\x9c#\xa7\xa9\xa4\xa4t\x86\xcc\u04b2\xd1V\xb8\xb7X\xe2\xb7C8KR\xc6\xe0\xaaV\x16-\x83\x18\xf9\xd4\x16\xebF\x97%\x9c\xcf\u063c\xcb\x05\xba\x96\xbe\xc3\b\xf3u\x17\xa5E<\x96\xda\xf3\xbah\bQ6/2o\u2088\xe3\xf8\x06\\\x1a\x8b\u0187\xc0\xdd\xfdl\x15\"\xb9\xe86[,\x95#\xa2\xe3\xab\xc0\x84wCF\xffx\xfe\xc857\x1f\x8d\x8c\x89\xe8\xf9\xaf\xf8\x01\xca\xe6\xb1\xef5O\xc4\u983f\xd0\xc6r\x8e{\xdb\x15\x06\xaf\xc8yH\t\f<\x13\x8e\xddX:S?H\x8c\xfdY6i\x0f}n%M\xf4Z\xb2G\xf4\x1fk\xb7k\xbf\x80\xd0\xe9B\xe2\x81+Q\xcfh\x19m\xc3\x11\x94\xbf\x16om\xdc{\xec/\xb3o\x99\xba\x9b\x94\xfdh\r7r\x99\xd0\xe0\xb5\xebf\x80\x8d\xf0:\t!\x01\xe0\xf8\v\b\xa4\xb1\x06\xb4\u0398\xfc\x14\xfe\xc8\xfa\x1c\xd1>7\xce\xd7vz\u05db\xde\xf6\xa9\xf7\x00\x05\xd7\xc6M\xfb\x1e\xa8\xbeb\xbf\xf9s\xcc#\x97\xe6\x81\xfd}\x01\xef\xa4]n\xc2\xde\xf1\x14^\x80\xee4\xf1\xa1\x88\xe2\xb6\xefWq\xb8q\xc7|\x18\x13\xab\x95\x87\xc1\x86~T\xbe\x03[f\xb6\x97r:\x1cl\xc0.<Yo]\x0f\xef_K\xbe\xa4\xb2m\x9f\x06\x8d\x9dN\xfbC,\xee\x99,\xc1\x18\xf3\xef|\x01\"\xc99\x8bb\xe0,\x8af,\xb0\u007f\fO.\x10:9(\xab\x01\xdf\xf6\x93\xc6n\xb3\xde\t8SX\xc1>\u00b9\xea\u06b8\x8aV~\xf0\x99>u6V>\x0e\xfa?u\xf8\xccW\xc4\xd6r,0\xa3O\x9c\xa9r\xba\xde\xfa\xe9\x8b\x1c_\xcdz\x9c\t\xd1\xd3r\x84\x93L\xff\xe9\xf4Q\xad[\xd5'\a\xd0[\xf4iJu\xf9\xf5\u0101\xed\x9c\xf7\xcb2u\xf3#K\xeb\xb2p\u009c\x94[\x82~\rLF\x97X\xc4l\xf7F\xb7\x957N\xe1\x935\x0f\x8c;{8pM\x1c}\xeb\xa7#O\xe37LT=)o/\x8e\xc44}\x02o\xb2\x94\u0242\x8f\x85l\xa9Rh\x9f\xda17\xda&)\xc72\x88\xce\xf8\x82(m\xf5kB\xd4\xe9\xcdp\xb8\u05d3z\x1d\x9f\x10\x11y\x95\xd7\xc6v$\xcd8GA>\xf9U\xbb\x98\xd9W/@\x0f\x9dG\xa9\xf2\u047bB\xb6vWC9*f\xabso\xb1\xa1f\x1f\x86\x1e_>c\xb6\xc6\x06\xdb*\xf8N\xf2\xdfq\x8aB\xf7\x9e\x8e\xf9u\xaa\u0271\x10d\xa5\u045c\xd1g\x99\x10\x9d\xdaX\xe3<\x1eO^\x9e8\t6\xfd\x05mv=+\x9b\x92\xda\xdc9\xc7\xc4:;\x1e(E0\\V\xd2%DV\x1e\xc0V\x86\xe8'w\x83D\xa1\x99W9\xa3\x95\x9c)\u007f\x8d\xdf\xeb\x82j\x9c\x03\u060b?\xb0\x86x\xc2\x0eay\u072acR\u056a\xcd#\xfc\x8c\x1d}Y\x0ef9\xc1\xd1q\x1d\xc7\x17\u0767\xfdY\x9a\x99 \x01\x99\xdbf\x9c\x8e\x93\xb8\n\x98o\xbb\u00e3\x9d\xda#W\xb5^\u06ccX\x9fU\xe8h\xea\xe0;S\x96\x12\xac\x04\u0324\x81\xd6\xc1]\xe8\u029b\xb1\x0e\rg|\xd1l\xa4O\xde5\x1abY\xb3I\xf5x\a\x10d\x9a\ubc4cW\xb8:9\u41f3G\xaa\xf2\xaf0i-i\x95Yo\xf1\xca\x1b\a\xc4\x0eI]\u0576\xa4\ue334\xdc\xd2t\xa5\x02\x1c\x1dGL\x02\x8e\x00\x9d;\tSd\x13in#\u02e74]\xbf&\x80S\x94\xde`/\xd2T\x86\xe6\x01\xc4\xc1\xaen\xb8\x9e\x1b\xcd|\u026b/gF\xf5[\a\xc4\xef\xe6\x02,\xea\x98?\x94\x1d\xb8+\xe1\xf6\u01cf\xeb\f\b\x10\x84\x10\x88\xbf\"]Y\x97\xf1\xf2\xa7/f \x02\xd0@\xe1\x8dEM\x8c\xb9\x87bi\u05a1Q\x1e>\u05a4\x81x`\xd5T\x00\x8c&F\xe3\x94\x05\xd4\x1a\u055c@\xaao\x94\x8a\xf6\xe4\xe1?\xd3,\x89\xed\x8f\x1d\xf8\x12X\u06b5H\x1e\xcf\\\x05i\xe9]\x15s\xd5LdX\xaayd\xa1\xd4MA\xeeZ\x84\n\xea\ue5b9Hi\xba\xa4!\xf9\xc8\x10\xfb\xc1\x1d\xfbQ%C\xdaTM\x85\xd2\xd9v\xbc\xeaA5Q\x8d{\xa50c\xc3\xeblXX\u007f\xa6}\xec\xba\xdaz\x12\x9f\xb2\x82\u025d\xb1\xb2\x96YtS\x93\xd9t\x12#\x15\x90\"\xba4\xe5\u0405\xd0p+\xe75\xb6\xa1\xfaUv\xe2K\xe4/\x13\u6f8d\xf6\x98\xa3L\x15\xad\x1e\xe1S\x17|M\x17\xd1\u01d8\xb5j4\u0676@\u018b\xe3\x17\xd5\xe3J]\xe9\x1b\xba\x93\u01e9\xc7_~\x9ca1\xf3\x93,\x16\xec\xb0mla{i]\"\xa3\x9b\\\xd9<f\xff\xb4\xc7\xf8|P\xcc\u00e9\xa9%\xa6(\aE\f\xc5\xcfy\xebs\x17K\xa1\xe2\xb5\u0616\xe4\x18\xc5\xccaV\x11\x12\xf5\xa9\n]\xce\xe4\x88?\x02;3\x88\xed(]l]\xbb\x85\x06\u012ff\xf8\r[\\\t\u019d'xKa\x0e\xd8W\x832\x81\x8eAT:O\x8e\x9e\x04cA{q\x10\a\u01e10\x02>l\x1e\x9d\x92\u06e5\x1b.#\xc4\x17\x198\xc0\xde\xf9*\x1cB\x12\x06Nf8\xfbk\xee\xaa=W\x84\x0f\u05e1\xa5\x14\x9c\x8e\xd9\u045fx\xbf\x14w\x8a\x0f4\b\xd9\xf9\xba\xb3\xfd\tH\xd3\b\xb6\xcb+\xf3\xc9\x06\x1fd\x80\xe9\x05\xb3[\x9a\u0125\bX\u068f\xb4C\xa0]\x0f\xb8\x16\x13\xa2\x8b\a\xf3\xef\xd8!\xcf\x06\xb3\xd5\x1b\xe8;\xa3su~Mo\x12\xd9>A\xb1\xa5\u0565\x98\x814\x1dq\xc5}V\xb8\xaf\xef\xc0\xb5f\x0e\xc5\acO\u0343\x904\xfd\xda\x17\u04d1\xcd\xdba\x81L\xbe\xa6\xff/F\xb4A\xbb\x1cN.\xbd\u015e\u0725V\xb016g\xb6U\xf4\xab%-\xc1\x95\xd6Lf\xfc\u05b6\xcb\xd1kj\xe1O:\xfeTYN\xec\xe8\x96V\xe1a\xad\x8b\x96\xb3\xac\xa9AI\x8bk\xf7\xf2k-\x19\xd9\xcd^\x9c\x18\x91\x03\xf8z\xf8\x06O\xe88k\u0727Z\x96a\xa3I\xea\xd6\xcdv\xb2h\xad\x9c\u04f1\xb1EY\u058c\xaboZ9a\x0eL\xe2A\xfd)\x06\x96u\xbe\xec\xcd`\xbes\xaa4o\xe7\nr\x06jv\xe9c5P\x91g\u075a\t\xff\xbf\x04 O\xf09\xe7\xcdP\x8f\xb87u\x002\xa5\xcb\x15\x8a\xd1x\xa8^\\k\x9d\x12(\xf14\xb6\xe2\xe9p\xa2X\xde\xcbD\xee\x0e\x02\v.\xd5\nPV\x87d>g1\xccf\r\xfc\xb5=7\xef\xf2u\x9e\xa7\x9e\x8fK?\xf2\xb7\x97\a\xa6,W\xc1\x1f\x13\xea\xbd_OG\n\xf9\xae\\kt\xb4\xe1\xeb\xcag\v\xc5\xe6\x8a\xd3\xcc\u011b\x8e\u0280\xf5g\x8fL\t\xa4G\x10\x8d\nM\xdd/\x12jI\x82\x86\xfc\xc5x\xcd\xd5knj!v\xce\xfbb\xf8\xf4R\xb8\x84a\xea\xa2!t\xb6\x14B{w\a\xadb4#d\xb4Q=MR\x83q\x12\x19n\t\xcdq\u050a\xaf\x00i.MeS\x9c\ub7fe\x9db\xd1T\xe3\xb6\xd2\xd1\xf9D$\x1b\xcfGvR\xa2\n\xc1/m\x90\x94+e\xb8!\x06Z~\xcc3\xb8\x8d\xc8\u010a\xabq\xf3\xbd\xbe\x11Z]~\xd2\tg\x19\xe3\xd1\u007fSGr\u0758\x92\xba\xab\x17\xaa\x91\x9a\x9f\vr1\x93\xf6\xb5t\xdfV\xe0{\xaa\x16M9\xcaI\x05\xed,\x86v\x01\x99\u06eb\xbd>U\u0156\x06\xa8_\xb3\x15\x88\x9fW\a\xf1\x9cV\uccfbJ\x19\xfe\xdb6B\xac\xc1\x16r\xbd{1\xbfl/>\u007f\xe4V\u0373^\xc3\xeaq\xbfK?w\xbc\xae3\xea\v\u06cf\xd3\u063f\xd5\x10\x04\xc2\x0e\x93\xb5t\x90\xad\x11\x85C\x1e\"\x9dnd\xd8\u007fx;W\xf4\xa3\xbe\xf8\xe4x\xbc\xdc]ll6\at\u0657\x04\xdc\xf8E\x02c\xf4!!\xe0\\\xf2Y\x1b\xb9\x15\xe2eR\\\xe5d\xe2Fs\xcb\xdc\f\x8b\xa7+\x8f\xbf\x8e\u02bdH!Q\xb7K\x14&l\x14\xcbrc9||\x97\xa7\x1d\xaf\x0ef\u0772\xbb\x1f\xcet\xa2Uj\x8f\xb4\xfatEg\xef\xac\xe0\x1cx\xb5\xff\xe2\u0116\xa9\xdd\xe2\xb0t\xec\xa8\x107\v\x84u\x01P:\xa29s\xfd2\xb4\xd3\\;.=\x8f~\xf5}'\xf6\xf1E\xab\u014e\xfb\x87\xfd\xcd/^\xfbmT\xf5\xbf\xb1$\xc2\u040fI\xd2`\x8b\xf6U\xa2\xbd~+)\xe8\xf6r$\xdf\x10Gh+\xb9\xa8\xe6n\xa6E[\x1d\xbfP\x05\x06\xc7;Zv\f\x01&\x9br\u078a\xbc\xf1\x14\x86Y\xf2\xf5y\xbd\xec\x8feU\xde\agx\xf4\x1c\xbc\x18\xeb\xcf\x1e\xe0\xc1\xec\x97\x18\xb2\x10\xabY,\xd4j\xc2\xec\xf3\x82\xac\xef\r\xda\xed\xc5\xcf#\u878b\toj\xf1\xfd\xa8\xa6\xf7\xc4\xcc\xf1\b*?\xe1\xd5\xc7\xd8\xefI\x17\xa3'\x01\x1az[ rP\xc5[\x95\xfc\"`\xe3\x85[\xe5%n\xe16[\v\xaa\xffJ\xa3[\x0f\xf9\xa1\xab\xba\v\x85\x88UP<\xb9\x16\u2f46\x82<\xe2\x16t\xa1\x99\xe6\b\x944b\xeavI\xac1\x03\xc1\xef.\x8a\x8f\xfc=)3\x96\xe1q\x05`\xe5*+\xa7\xc3]\xc7mE\u0511c\xbb\x8d\xa2\xea\xe3\x19A\x1c\xc4\x18\x1f/\x8afX\x02\xa6\x16\f\x05\x97\u067e\x8d\x97\xad\xc0\xce\f\xfb\xd1=\u074c0|4\xfar?\xee\x16\x14\xbd\x133\xe8\x828\u007fj?!Pt\x89\x96D\xf7\x83\xf5\x9e\u019a\x11\xa4\xad5\x9b\xc7\xdd5\u01f2t9\b\xb1\xd4fx\xef\x9d\x1ep\x96\xab]y\xbck9`\u02b6!\x99\a\xd3_T\xe6\xf3\x14\xf8\u007f\xf6\x90\x0e\xae?m!z\fH\x8b\u052c\x0fzb\xd1\xdfZ\xc8;\xd7\xc0\x00G\xf5c\n\x9d\xe8\x8eF_j\x05q\x1b_&wL;\xf9\xd76\xde\xe1i\x8al\xfc\xe0\xe9\x1a\xe55\xb4f_\x8d\xcb\xd7;}\x13\xa0\x16\xe1\xa6i\x94\x91,\x9a\xc8(\x1b\x9b\xefu\xcb\x1e\x96\x0e\xef\xd0\u007f\x06\xa5\x1a\xb4\xca8\xad\xa5\x13\x15?\x82h\xf5\xc0 \x96\x8a@\x87^Wn\n\x8e~l\xae\xb5Xl\xc60\xc1\u47f1\t\xfa*\xcdt0\x05S4\x8b\r\v\xc2\v\xb6\x123@c\x04\x92\xba\xd2X|\xfb\xfd\x8e\xc5\x06\x9eHYPp\x8c\xf7\xffx/c\xb9M\x98\xb5\xd4\x1d\x03\xd5C)\x83(\xce\uce3a#\u02f5\u049a\x9c\xf2F\u0492\u032b@F\xb3&\x9f,\x14\xc5)\u058a[\xfe\xa4\xf8[\xc1\x11)k]hT\xc9\xc9A\xddo*\x97\x93\x1co\xad_\xdaq4\xad\x8e\xd6O\xb0\x1b\x8e\x0e\tD\x1ek60K\x19\xdb::\x1c\xaf\xc1\xd6!p\xee\x8b*R\xae\xcf\u6934n\xdaw:y\xe4\xec\x1b\xf5h\x8b.\xa9QZ\xb7\xad=\xe1\x98\u069e|n\xdaX|\xc1\x89uu*\xef\xfcM\xa5\xed\x8e\xfc\xe2\x95\x12\xdb/\x1e\x11\xf3\xe7fv\xa3\x0fq\xd8c\xd5\xd9\xf7\x9a\xef\a\x9cH\xc72\xd3>\xbc\xb7\x90+\x1eR\xdeE\x11?=\u05c1\tg\x11+\xbac\xb0Y\xb4!\x0e\u03c0B\x152\xb0\xb1.\x87\x10\xb3f\x11\xc7su\x01\xfd7") + +func staticJsUplotIifeMinJsBrBytes() ([]byte, error) { + return _staticJsUplotIifeMinJsBr, nil +} + +func staticJsUplotIifeMinJsBr() (*asset, error) { + bytes, err := staticJsUplotIifeMinJsBrBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "static/js/uPlot.iife.min.js.br", size: 14165, mode: os.FileMode(420), modTime: time.Unix(1612357325, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _staticJsUplotIifeMinJsGz = []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x02\x03\x94:\xebZ\xe38\xb2\xff\xcfS\x80\xcf.+%\x95\x1bLw\xcf:[\xc9GC\xd30\x03\xdd\xec\xc04\xcbdr\xf8\x9cDI\xdcQ\xe4\x8c,C\x02\xe4\xddOIvl\a\xd8[_\xecR]\xa4R\xa9TU\x92\u04e8\xec\xeeL\x8dY\xc4~\xa31\t\xcd4\x19\u0507\u047c!\x85\x88T\xb8\n\x1a\u0265\x8c\xcc\x0e\xbbo\xd5\xdf\xd7\u007f\xe0;\x95\xc6\xff\xdc\az\xc7aq\x9c\xa8\xa1\t#\xc5\xf8\x93\x97\xc4b'6:\x1c\x1a\xaf\xbd\xc1\xef(\xa6@\x80\x06\u00df\xac\x94lk\xd4\xcf\xcf\xcd\xf68\xd2\xcc\"B\xdco\xfd\xf0\xe1\x87\x1f\x0f\xde\xff\xf0\xa1\x83\u0320y~\x16u)\xd4\xc4Lk-\xde65\xddi\xb5\xb9\ua21e\u0130\xab\xab\xa6\xd3i\xf9S\xc6\b\xe2\x8d}\xde\xefj\x94\xbeA\xeaX\x98D\u04c05\xd1\xd3}b7\xfd\x9a\xea\x1a_\xafs]D\xa1\xcbfx\x89-D\xd3\x15\xben\xcb\x0e\x8a\xbd=\u0761\xaed\x15\r\x0f\xc7L%R\xee\xa2\xea\xc9>\xcfz\xdf\fSk\xad\xad\xb8\xc6^\x13\x9a\xfdb\xba\xc6\ra@\xf2\xa7LB\xf7\x9a}lvL\xf7\x90H5\xc3}\x05\xba\u05f2(I(\x015\xc9}\x01%-e\xa6\xa5L-\x16B\x00\x11\xc4\xd8j\"\xea\xee\xc0\x9f\xe5\x13E\xab/S\r\xd4 *\xa89\xc8.\vq\xcab\xa68\x87\x00\xe7\x04\t\x82\x14\xb2\b\r{`\x1aB\x0e\xf6\x15p\b\xe9\xc1I5\x10\x18\x91:\xdc\xdf\x12\x9d\u6897\xa4\u037f\x10\xe7$\xff\x89\tp}p\xe8\x91\xea\xfdu\xba\xaeO\x8b`\xe47!\x8e\xc6\u01b7\x86\x84y4\x12~sM\xdd?\xcdC\xe5\x870\x0f\x96~\xb8.\x8c\x17\x15\xeb\x93\xcd\xf1\x8ci\xdeMR\xb4U\xb1N}\"\xe9Q\xb7\xbd\u04ba5]\xcf\u0536}S\xfb\x80\x06t\xecV\xbd\u00a4\xb1E\xe5\x9dZ\x11DE\x8b\xae\n\x96\xcd \xce\xe6\x06u\x9dT\x04IoR\x12B\x8c\x99\xb1cC\x93\xacC\r\xb9iD\x8e2\r\xf4\bj+\x0e\x89\xa3\xb9&\xb5\u0196\xe8T\xb5\xad\xa1\xa3\u0656c\x1dY\xa2\xd3\xdb\xf63\xb7\u013c\xb5DQS0\xc3\xe5\xf3\xf3=\x13\xfc\xf9\xb9%\x0e\xe0\x0e\al\xc6\xe1\x02\x1fX\xab\tSv\xc79\\\xe1!\xa3\x15\xaa\xcd*\xac\x89\xb8\xec6\xed\xbc\xea-\xbf\xe5\x87\xc4\xd9hQ_\xef9<\u2e23\xa8\x93]\x1c\x91\xc3\x1c\xd0\xeb\xf9\xf9\xaa3\xe6\xd4\xd8w\x8dq\xe7\x8awW\xfe\x18\xaeq\xc2\"x\xec\\\xed\xed\xa9\x0e>v\x1f\xfd\x05{\x84+\x1a\xe9\x98F\xa2\x85\xae\x96F\x12\xe9HAi\xa4\x1b\x14\x9d\xa1\x1bi\x9e\x8e4\u007f~\x1ev\x8e\xb3\x91\xa8q\xdc\x19\xf2nm\xe5\x0f\xe1\x16\x17,\x81\xe3\xce\xcd\xde\xdeM\x87\xfa\xba\xf1'\xec\x06\x8e9\xdf\xf8\xf75\xe2\xed\xde\x1e\x8dsM\u04b7\xe4\xff4D\xef\x1anS\xff\x1a\xa3\x12\x0f;g\xca\xc8\xfa\x97d>\x10\xfa$\xd2\xf3\xc00\x15\u0707\x93\xc0D\xba.\x035I\x82\x89\xe0\xf5\xb1#\xc1\x10/\x023\x85{\x1c\u0583A\fSz\x8fe\x14i\x18\x11\xa4\xa3D\x8d`N\xd0P\x84\x12\x16\x04X\x0f\x98\xd87y\xc0\x03\xbd\x17\xd1\x03,\xe9\x1d\xff\xa1\r\f\b\x90\u0444Vb\x96B\xfbpG\xc0\xe5\x19\xac\xb0\xd5h\x16N}\xb1\xe5{#\u06af\x82WD\xe1xW\xa9\xe3\xe5\x1c\v6q\x12\x84*\x98\x1e\x99\xda0x\x1b\xa4\x87hV\v\x11\x8dwTW\xf9\x8ccG9\xcb\\\xa3\x95\xa7\xa6\xa0Esh\xf2\xf7B\x9fO[\xfa\xcc_\xe9s\xb9E\x9f\xbe\xa2\x1f\xbe\x9cO\x85\tgX\xb2\x8f\xf3L\xc19o\b\xa7\u028d[\xa4\x8b`Q\f\u007f[\u03041\u03eb*^\x8f\x1724\u032b{\x9c\x82\xc8\xf3\xb3\xe7\xf1,\xfe\x17\x83\x1e\xbd\x15\xb9{}\b\xd1\xd0\xf2,\u062d\u0756\xa2\xad;A;\xa8V\xf9\x86'\xc2{\x16p\x88\xc9w\x1f\xa8\a\x02#\xbbG\x9bm\x93\x8d\xd0I\xda\t\xf1?\xa5\x1eezI\xbf\x12\xc3\x10Y\xb33\xa6$\xd5\t\xba\x91\xdf\xe4U\x16\x12\x81\x1a\xf6Em\x98R\u007fc\x18\xf26\x85\x81$\x9e\xb2)9~=\x16\x86M\t\xb9\xded\ng\x81S|Z\xc3\t\x1ej\x1d\xac\xeaa\xec\u07851\xbe\x94\x96\xd5fN5)-j1\xfb3\xa6R\x15\x05\xee\xb6\xdaE^J\x91\x1a\x15\xe5kE\xf2\u0250\xfc\xbe-\u0412\u0466Y\x8d\xf8u\xf0]\f\xcdF\xa9\xd2:\x9e\xe7\x9d\xda\x1eO\xa8\xc5I\xd2Y\U000dcdc5\xa4dNx;tnN\x8a\xea\u0505\x9d\x91\xe26\xc9\"\xf5A\xaf\x8c\x9b\xa4\u06ef\x87\xf9\xc6T\xb1f\x02\x03=I\xe6B\x99\x184\xb6\xdab\xb3\f\xba\xad7\xcb`\xd0v\xdd\u0397\u064ei8\xe9a\xb3p\xf7\x9b{\xc393\xb6\xc9}\xdb\u00b4\x95[\xbed\xb9\xaf\xa9\xdf\x14\x1a\x18l\x82\xc4\xfb(\x1c\xed4!\xc4ZI\a\xd36\x1b\x1d\x02\xb4\u50f5K\xd0\tSa\x89\x011\xcb\x0e6)4:\xfb\u06a1\u06dc\x9e\xb5Z\x1f\xdd\x1e\xcb\xf8\xaa-rD\xf9\x92-DY\xad\xa6\x8c\xeb\xb5\xf3\x8d\xef\xe8Q\xcc\x11\xe3P\x89Q\xb1\xee\u007f$\"\x11\x17\xe1PG&\x88g]\x85\x9dK\x1d\xcd\xc3X\u0535\x88#y/\x18\xaf\x9b\xa9PdW\u007f\x9b\x17>\xa3\xf7\x10\x8e\xcc\u0503\x8f\xe8ME8\x99\x1a\x0f~A\xcfD\v\x0f~Eo\x10\x19\x13\xcd=\xf8\t=)\xc6D\xfb\x03=\x9dr\xfd\x86\xde\xff6\x9bM\x0f\xfea\x01\a\xfd\x8c\xde<Jb1\x8f\xee\x85\a\u007f\xcfZ\xa3\xe8Ay\U00027b15P\xc7Je\rZV\xa1=\x10\x9b\xb6\x14\x81\x95\xd4\xd4\x1e\r\xe4P\x86\u00d9\a\x86Z4\x91\xf0\x91(\x92\xe0\x98\x94\x97\u0483\x80\xe0\xa4\x16\x8d\xc7\x1eD\x0e\x94\xc1@\x10>V8\x8a\x86\xceg Q\xf8\x10*\xd2\x00\u0184\x15\xf7\xe1P\\\x86K!\u007f\th\xb1\x8b]5Ti\x88Jw\x89\xa0\x85\xa8\x0fe\x10\xc7\xe7al\xea\xc1h\xc4D)\xb2\xdeg\xcce\x1e\xed\xe6\xbc\xc56\xcd\xeaX\xcb\x18\x9b\x95\x14=\xd1G]\xf5\x16K\xaf`\x1a\xbd,v1\xa6n\xb5\b\x8c\xf8$\x85\x9d\x02Syz\u02f5#u\xa5\x8d\xf7)BS\tZ\x0fU,\xb4\xf9(\u0221\x04\x11\r\aY\x8c2W\xdb\x11X1o\x14\xde{`\x91\x05\xd7\"\xd7\x05d\xaet\xdd\xe8@\xc56\x1d\xa2\xe7@I\xaa1\xaf*\xecD\xc0\xab\xba\tq\x0f\x9a\x1da\xc3\x1fE\x10\xd11\x14F\xa8TuF\r\xc8\xe7\xee3\xc0\xb9\xf0D\xd92/\x8e\xc3{\xe1\xef6K\xa5\xdcCn/aM\xfe\xe9\x9e&om+\x94\xd0D\xd10Q%e\x97\x05wf\xfc\xb7\x05\xec\x90\x03\x85=\xef\xa7@%\x81^y\xe0\x9d\x88\x81\xce\xc0\x8b@\x0f\xa7\xf4>\\\xe8P\xba\xb6\xc5\xfe\x94(\xe1^\u04b6\x0e\x93I\x12\x1b\x02\xae\xc4\xc2\b[7\x10\xfc\x95\xe2f\n}\xa1\xa13\xe4\xb1\x18\xa6`\x1ffv\xc8+\u06ab\x81\x1b&\u0280\xebD\xc4)t#Fj\x03_O\x13\x9d\x81':L\x81\xab\x80\x96\u0282\xa5\x93\xc2\x1d\xcd9_DZ\x1fI\xde\u031ap\x90\xcer\xa5p\x96\x06\xe3;\xc5\xe1B\xe1\xa0h]\x91\xd1/\xe8\x8f?P`_\x17\nn\xe8\x8f?so\u007f\xa5J\xeb\xf0X\x1a\x85\x92sGu\xbd\xa6\xe7S\x8a\xadf\xc5\x02\xf5uK\u007f|\x85\x1dU\x9f\bsB^x+\x02\xcd8\xa4X\xf6\x02]%\xe1L\xdb}\x0eN\x8fM\xbdQ\xb7\xad\x9e\xe3'#\x99)\xe3}xI\u007fE\xb6c\x90\x96et\xb5\xc5\xc1\u1dd1p|\\f>\xb6\xbe\xcb98d\t\xe3\x8cQ\x8ci[\xbd\x8c\xbc\xb2CnS_\x10OO\xcbC\x9cF\xb4\x96v\f\x87-\xa3`j1YR.\x11\xf2\xed\xed\xea\xe3\u05be/:\xad\xfd\xae\xa8Yh\r\x87\x87$E\x88\xad\xae\xba\xde\xe1\x05-\xc9\xe5\x85\aA\xf0&=\x98\x13}1'\xfa\xdbdK\xf5`>\xdf2e\xa8\x12#\x9c\xf2\x0e\xbf\x8d\x848.3_\x89!9\xb5cv\xf8m$\x8c\xc7c\x8b\xdd8\xd5k\x8f\"\x97j5\xb7\x9dk\xa3\x85\x94a\x9c\xf7^r\xcc\xe3,\x8a\t\x14t\x18Qy\xbe\xd7`la'\xb1\xf1\xfb\x13\xeb\x05\xb5\xc7~\x95\xff\xbe~\xee\xfd\xdfS\xbfJ\xb7\x13m\x8d\xb2.\x96bh#)7i\xfd\xe5=y\x88\xf6\x9cM\xff\xba\u05eag\xcf\xd7}\xdf\"\xf2\u5c0b\x95\x0f\x81\x9e\a\xb2\\\x05\xda\x13\u007f\x95\xeb*\xbe\xaa\xc2la\u0475\x0f\xdf>\xac\xcay\x97:\xcd\xe2\x9f\x14\xb2\xfc(b=\xf0:\x9c\x8b\xf40\xc27){\xf4ua'\x1d\xdb\xd4M\xd4\xdf\"%\xe0R\xa1\xb5\xf4\x9f[\x88M8T\xd8k\xc1>\xec\xd7\xdf\xc1;rQ\x85Gd[\xa8\xb5\u0783%\xd2^L1\xd4\"\x94E\x1c)\xbcU\xf5q(\x8d\xd0\xec\x92\x10\xa7\no\\!8\f\f\xbb%\u0109B\xcf\xed\xed\xb5\a_\b\xfe]y\xd5\x13\x05g\x16}\xb1n<\x1d\x13\xfe<\u00df)\xf8\xa6\xf0\\U\xbd\u0193\x13\xf8j\xb9\x82\x80\xa0\xef\x16\x9a\xae\xfd\xa7\xf9|\xedU\xbf*\xf8\x9c\xc9|W\xf0\x91@\xff)\x8e\x89\xed\x17\x85\xdb\xe7\x8c_UQ\xb5\xd2\xf1\xb5\xa2@\xe3\xfbfE\x80\xb1/\r\x12\xf7\u007f\xa8\x18\b\xf1\xa0Y\x91\x10\xe0\xc1\xfbw\x95\xcd\xedJ\x8f\xb5\xecA6\x9b\xf1\x81\x9dpi\xaa~j\x9b\x83\xd44|3\u7780w\xd4}\xabi\x1f\x16:\xb0\x90&\xa4\xb6HzX\xe8\xc0B\x06\xf6i\xe8\x03\xfaoUxO\xff\u007f\xa4\xff-\x8b\x94D\x92D\x92D\x92$+\x89,\xe1\x03\xfd\xff\x91\xfe\xff\x95\xfeS_\xf4\xb0\x94\x90xC\xe2\r\x897$\xbe\x10\x02\xc2\x04$\x15X.jX\xe8]\xd35\xe9\xd9\xe7\xd0\xeb\x05@\x8b\xf0\u02eb\u007f\xad>\xf4\xf6\xed\x10\x9e\x8d\xedv\xc9\xded\x91\xb4~\xff\x84dHt\x9a.\xd17\x87<\u007f\xc1\xa0\xe1\xfb?#\t\xf8hIUo\u01ed\xab\xe5(7>\u7334\xe6D\xa8?QH \x1d\xff\xbdD\x1f\xf2\xa8!\xf2\xa8\x11A\f\t\x8ca\b\xf7<\v\xa2#\xbb\xe9\xe78\xec`\x00\v\xfb\n\xf7\xf6\x82\xce\x10&(X\xc2\xe1\x01'\xe4@K4\x82M^d\xa99]\x02MJy\x02\x16\xcf\xcf\xf3n\x8bp\xa5\x1c1\xc0eE\xd9z\xde\x12\xf3\xf3\xcc\f\x17\xdda#\xf4\x9bp\x87s\x82\x02\x82V\xf8\x808\xe8>\xf8$\xb8|\x91\xf9\xee`YNH3hq\xd2\xea\xc2\x1dr\xddH\xab\x86M\xcfx\xf1B\xc5G\u0094\x14\xbcF\xba\x1e\xe8\xe0\xaa}\xbd9o\x1c\u06c9]U\xef*\xd7\xf0X\x9d\u0473\xc5\xdbl\x85\xacz\\e\xc75\xc1\x8e+\x8asN\x0f{,\x1d\xa5Ao\xc5\xd7\xf6\xd8\xe5\xe4/Qv\x86\u0761/\xe1\x06\aU6%\x93\u0566\xec\x81\xf3\xea'\xf6P\x1b\xc0%ogR7<\x8f\xb4\xb7(\xa8\tGx[\xca&\xd5\u06ed<\xd1\u0404(\u7086\x81S\x1c\xd2\xf3\x04\xef\x1bQ=X\x8a\xb8\x17\xf7\xebw\xf1\"\x18\x8a6\xbb\xc1CvS\x1d\x82\u06feM\xff\x80\xf3\xbf\xe1\xb8\xcd\xc9\xf0\xa7\x9dV:\xd7/8e\x87\xec\xa8z\n\xef9\xff\xf3\xfe\x0fp\xe6\xf4(\xe9P\xfb\xd2>\xeb\xb4\xe8\xd2\xe7\fk-\xab\xa0\xe5v\xac\xf5\x0f\x9dC\xc6\xd8M\r\xcf*\x86\xd7F\xbdQ~S\xdc\xe7\x8d!\x1c\xf0\xcaIn\xa0\x9b\xd4@;EsS1\xaf\xd7\xe9\x1d\xd2O\n)J\xd1\x10\u007f(\xfcI\xd9\xcb\xd0\xdf\x1c@\x8e\xfe\x0f\a\xec\xf7\xe1g\xc7So6\x89\xed\xef\n\u007fvl\u007f\"\xc0\xb1)a\x81\xfdRY'\xc4Vu\x9eVmLa'\x83\x98=\x1d`\xa7\x89\xf6\xa2\xfbG\xf7\u030e\xeb]\xed\v\xd6r\x18\xa2\xaa\u078f}\xc2\xd8Q\xaa\x9as^\xbe\xce\xd4[c\xd8\x1e\xc1\x06\xa3`\xb3\x99J\xfb\v\xa6((t\xaa\x91\xd3!\xe8\xa0\u055fs*\xec{\xa2\xb0\xdd&\xa5\x99TG\x91\xf5\xa3\xd1\xeeZ0\xa8_8\xb4D]v\u841aE\xf9\x15\xa0.\x17J#\xd4\u06e5\xc7\x1c\xf5vy\xb1@\xb3\x8b\xd1\xde\u0794\f\xf9\xfc,w1\xb6\xf0\x01\xc1\xe1.&\x16\xfe\x81\xe0`\x17\xc7\x16~G\xf0h\x17\x87\x16~O\xf0|\x17\xef-\xfc\x81\xe0i\xaf\x98K\x84\x06b\x94\x90`\bc\f`\x88#\xb8\xc79,\x98\xe6k\xb2faN#^\\\xc1\xa5\xfb9G\x17\x9cr{q\xa9U\"\x86[\xc4l\x9d\t\xc7Ly\xed\x02\xc7U\xdc\xdc\xc4B\x87\xb4\x87D\xae\xb7\xae\xbb3|W\xd7c\xa3\xa3Y\xca\xee\xeb\xfa\"\n\x95\x89sb\xd6,\xf3X?*\x06\x8a\xb6u-\x8ddS\xa9t\xc4\xf5\x11\u06c7\u06bb\x03\xa0\u007fd:\u07b6Z\xc5\xe2\xe5G\x8d\u4541\xc8A\xac\x8f\xd6\a\x891\x91\xa2#+Se\x8b\x8e_\nh\xb7\u07c6\x02\x9f\xe2i\xf4@GEX\xda\xc7\xca>d4\x9c\xf9\xbb-\xb0\xc7>\u007f\xd3\xc5\v\xf9X\x90\u06e2\x80X\x90\x9a\xa8\u9f46\xd4\x02~\xdacY\xaet-F.\x18ml\x05\x06\xe7\xca9o\u0674\xce{\v\x8b\xb4MvR\x1e\x04\xc3\xd9\xc4]\ncHN\xe9,\x13X\xc9\xf01\x93\x8b0[\xaa\xec{C\x9b\\\x98\xe5\xe2\x91\x1e\t\x8d\x91=P\xef\u0111\fG\x94\x1aef`\f\x1a\xb5\xfd\xcdzO\xc9A\xe03\u0243\x83>\xe6\x907\x0f\xf4$T\xe7\xee\xa6&\xdeF^G\v\x873k \x85\xb6\u0356\x1b\xedX\xb0\xf2\xaa;]\xa1\xc5\xd7\xe0 \xcau\xa9\x15\xde\x16.K\x16\xd6\"ak\xaa\xffNd\r\x03\n@\xfeS~\u007f\xe4'\x02\xb2\xeb#\v\xba\x9b!\vln\x89rz\xea\x12YC\x8a\xa0\xd4r\x97M\xd4Z\xc3H\a\x13\xf2\x02\x8a(\xc3@\x8a\xb2o\xb5`\x14\u0186&\x9a\xa80\xfdPt\xb7\xb4\xd8;K\xa3\x99D\u00c4\xfcg\xa1\xa3\xa5_\xa3\xb6$K\x13\xd0\x04\x13-\xdc;\x1c-S\xb1Q`\x823j\xfc\x13\xef\xd44\xc5\xfb\u0737s\xbbzz2\bX\x13\xdc\xdfz\xf3\x03\xf72\xcb\xef[#Z\xf5\xaf\xd70\x15\xf8\x8d=YyxrK\xd9j\xae9\x8c\x04\xfe\xa5\xb5o]g\x15\x1b1\xaf%!\xec\u0502\xc5B\x8aZ\x8a\x81\x1d\xefJL\"\xb1\xf3\xeb\x99\a;\xbfD\x83\xc8D\x84;\x15\xf2^\x98p\x18\xec|\x11\x89 \u02a1\x0e\x03I\x84/D\u07f9\nTL\xb8\x98^5\xbbTc\"\x1c\xdaNw\x8e\"\x19\xd1Qf\x1e}\x0f\xbdR\xd7o`\xaeV\xf3A$\xbdM\x97e\xc1\xbf\xc0\\\xa0GT\xeb\xeb#\x01\x8b\xb2I\xdc\xdaxKoc\x9c\xdf\xc0\x95\f\xfe\xbb&L\x82\x85\xff\xce\xf9\xb1m\xb9{\xbf+\xdb8\xc8\x1a'\x912\xfe\\\x10\xc7H\x90\xed&:\x1c\xf9d.C\x9e\x12\xfbS\x01cK\xa7\xf1\xec-\xa8q_\x18'o\x8e\x1c$&\xb2\xcb\x1fG\u0688\x91\xdf\x02\xfb\x15r\xe5\xbeB\xd6Vv\xb1c\xbf\xd7/\xdfa\xbd\x88\xf6E*\xcf> z\x9e?fj+5/\x9d\f\x14)9?uF\xb6\u008d\xf1\xc6\xe6>&9%yHPc@I\xde~Y\xd3 9\xc4\x14\u007f:\x98\xb4\x13<dIUR\x9bGi\xf5\x92^\xe3\xd7\u00d8%Pkr\xaa\xad\x12\x9eg\xbab\xf8A>|\xfe\xf9\xd8\x0e\x1b\xa0\xaa;;\xc4=\x95\xd6l\xa2\xef\x10\xf4\x92\xd1\x04\"\x9c2f?0\a\xf6\x033g\x9a\xf3\xb6\xc4\a\x16@\u0121\u0671\x81M\x92J\x12j\x11\xdf\xc40\xdd\x1eEOa\xaa]\xccAV\x82\x0e\x8b\x89)&\xbd7\x93\xb4\x85\x06I\xc6|\xfd0\r\xa5`4\xb98W;t9a&\xb0Qo\xc0\x1d\xbdz\xad\xfd\x83w\x1f\xfa\rX\xa5\x8dw\x04^\x10\xd8j\x14kr%\xb6\xbf\xd3f\xd3\xd1\xf6\xc6\xc0\xa4S\xb2e\xfe>\x163\x96n\x8e|\xb3\x8aN\xfd\x90\xc8\xf7\x81\xbc\x8e.\xa3\x18\x024Y\x01\v\x11\x86d\a\xb7\x14\x04\xfd\x95\x80Z\xf4\xb7\xa0\x1b\xb2\x0f\x05\xf8n\x03^\b\u007f%\xfc;\xe1\xcfD\xfb\x95\x8f\xc4u#b{\xdf\xdbU.\x86\x94\x9d\xe4Q\xbc\xf1=Z\xa4\xee$xz/\xf7\u0683W\xaf\xf6\xce\xc1\u007f\xb9w\x0e\xfe\xfd\xde)\xdf\xd0lkI\x85\xf7Au\xbf\xc2\xec\x87d\xce\xed\xf1\xba4\xa3O\u5aa60}\x9e\x11rw\x03\xbbd\x83@\x8d\xa8\xc6\u02c0z\x1c\u0345\xb3Y\xceN\xb9\x1eE\xf1%\xf8\x00Q\xd7m(\xa7\vi\xd3u\x9f\xe6ISw\xf0!3\x15\xe6I7xs\xb3\xc1\t\xc8,h\xc7q;\u007f\x11\xa8\xcf\xc1\"\xb6p \x17\xd3\xc0o\xfd\xfb2\xa2\xa4U\xdd\x06\x89L+\xd6\xc47&\xda\xcc\xf7U\xa4\xc3.\xcdp\x10-\xd3\xcc\xebg\x8d\xf4\xbb\fo\x94ss^\xcd\xd9e\xad\x8c\x15\uf83d\u00eai\xea\xcf\xe6\x96@&\"vn\xf4f\u0302E`\xa6\x8els\xe9\xc2A\xa5\x85<|U\x8d5Z\xa9\xf9n\xc8|\xf6B\x8al\x94\x1b\xcf\u0659\xecB{\x86r\x91\x1d/\x1b8\xd8$\xc3\u0412iz6\xd2\xdef\xe9\xebF@\xd6SJj\xad9\x1cQ\xef%5N\x05KM\xaa\xb0\xb7\xa9v\x9f\xe2d\xe0\x97o\bT\x1aPl\xa1\x91\xa8WD\xcco\xbc\x9c\xbb\xec\xa2\xe0\u0138(\xb3\x95b/D$\xb2\xb9\xe2kY\u007f\xa3X\xfc)\x18N\x9d\xf4\x13\x89k\x8b$\xf1m\xa9\xf4xP8\xf7\u026b\x98\x93/\x1c\xc8\xdc\a \xc4t\x85]\xb4\xbd\xb3%\x83=*Fy\x83\xb8c\x94o\xb8\n$\x846\x9b\xc6\x18\u00fa\xadD`H\x80\x89\x16p\x8faV\xbbM\tJ\xdd\aF\xa5\x00v\n\xf3R\xeb[\xe9\x06:v^\xa8\x99\x81\x00\xd2C\xe1\b\u66c3!|\x13\xf0]\xc0G\x01\xbf\n\xf8Cp\xbf\xcc7'\xce!qN\x89\xf3\xab\x80\xcf\x02~\x11\xf0\x93\x80\xdf\xca\u07d8\xbele\x1b7ln-\xe6\x9ea\xdea6h~\xdfC#,\xd0f\x1c\xa7\xe2w\xe1\u007f\x16\xed\x96m\x92{UXNhQ!\u01bbl\x84\x9a&i\xb8O\x90!H\xa7Yh\x82\x17,f\xa27\xa2\x14G\xbd\x8f9\xd4\xdfqx l\xc2B\x8b\x8dh\x02\xc3\x14\xbb\xccx\xe7[\xbc\x03\xc7\x1b\xd5\u027b\xcb\xcc3w\xa7sI\xdbj\xff\x98\xc9<\x10-\xd8\f\x960\xe0`\x81I\x01<\x90\u013a\x1c\xe1\u03f6\u0280\xcdGe\xbb}lv\u029d\xb2\u025f\x82\xd2H\xed\xa2Vp\x9f\x0f>\n\x9f\xac\x1e\xa3v\xbfYPo\xfefA\xf5\x92~;b\x01\xc44\u0598\x9c\xaaF@5\xe4$6\xa6\x10\xb2\u0790tU\xa6\x94\xfc\x1a$(\xd4=\xcf=\x9c\xb4\xd3\x1d\x91{zO\x95.\t\xcc\u079eICs\u05f8c\x98\x9f\xed\xd6\x1e\x89\xf6\xcb\xe7\xbfoy\u007f\xaank\xf8\xeb\x88m\x1f\xa4\xbf\xbef\xd0Pv\xad\xef%\x06\x19\xaa\xd7=|~\u0370\xdd\xc3G\xb1\xfd\x01T\x8b\xa1a\x9bv\xc1\xf6\xcb[l\x9a0\x12L\x89\xed\xd7\xed\x05%\xc6@\x0fY\x81(8\u007fz\x93\x93z|\xc5\xf9\u01ebZ\x91\x02\x88x\f\x85>J\xb4\xb3I\x99X\xc8\xfd\xf6o\xe52\xfd!\xd8\x1a\xef\x1f\xa2\xf4\xe5&\x97\xb7;\xd2\uc8a4\x1a/\xc3rH\x01\xb9\x01B\xce\xd3o\x1d?\v\xa4N\xbe\v\xba\ns\xd0g\xc1\x8b\xf8\xfe'\xc1\xf2\xdeUfP\xec\x9c\b\xd7`\xecU(\x809<l\xc2\x01m\xaav\x1e\xaf\xd8\x12).\r\xf0g\xc1}\x82?[\xf8\xef\"\xdd\xf13\xb8\x83+x\xc48\x8f\x13q\x11'\xe0\x1a\x9f\xb2\x12\xa9\xd8T\xe9\x81u;9\xba\x82\xc0Ak8\xc6\xebz*\x04\x9fp\x05\x97Hy\xf5\xd0\x16\xcd78bc\x16\xf4Z\x88\x8f]\xe3K\n\u07e4\xf2=\xe7p\x8b\x94\xe5\x8eP\xb0\u0219\xb0Uy\xe4p\x9a7k\xae}\x82\x17N\xfah#\xe6\xe2\u0297\f{Z\u01b6O:t\x83E{\xf0\x90\xccrR\\\u041e\xe1fh\xba\x0fE\xda}\xb2\x83g\xed\xb3*>\xa6\xfb\xf3<S\xf0,\xd7\xcc\x06\x97s\xc4\x1b\x9e\xfe\x96 \"R\x97\u0348m\xc8,L\xb6\u007f\x80)\xe74Q\\\xed\xed-\xd91\x9c\xc3\xcc6m\x18\xfb\xc4i\xf2\x13\x02.9\xf7o\x9f\x9f\xd3>\\'T\xc5\u04dc\x9b\xbc\x9d\xdf8\u007f#\x13\xb4?\xed\xe2\xaa\xcb\x06\xd4\xcd\r|\x82K\xdb\xd5\x1d^\xe1\r\x89\x937\x11K\u04d9\x8aCY\x9dt\xd4\xd7JY5.q\x06\xe7\xb5\x1b\x97\xacI\x04\xdd\xe8\xf4\t0\xeb\x8d\xf4b\xf9\x1a\xbd\xad!\x87o\x99)\xef\xe0\x9c\xd3\x1a\x9e\xaf\xd7d\x14\u0494&L\xcf\u02fd\xbd\xab]\xa4\xdf\x1cni}_\x9dw\xbedr_lk\xa3r\xe8n\x86Rs\u007f\xc5k\xd7*\xa7\x86c\x0e\xdf\xddLR\xc6\xeb\xc89{h+T\xfb\f\x96|3\xbd\xf6\x92}\xa5\xbe\xbfs\xb0\xc0\t\x01\x9b8\x1c\xd67e)M\xe2\xban\x9d\x14\u03ec&\u03b3\xf3\x9d\xc2!\xab\x97\xf3\xe4AV\xb9v(\xb4\x898\xdb\xcf\xc7\xc4x\xbd\x95\x8b\x94~u&|c+.l>\x03\xbb\xbdVpa\xb7\x18\\\u00f1\xb3\xcf!\xd9\xe9\xb64i\xf2\xfcMVh\x1bv\v#\xe6\xee\x94\xe9-\xec\xbb\xf0\xdfSJZG\xb5V\xe7\xb4}\xba\xc9W'6\xb1\x9d\xd2\xe9\xf5\xb4\xd6j\a(z'\xb6(\x12v?$\xa8z\xa7\u0556-\x80D\n\x1cuN\xab\xfb]6t\x84\xfd>\u0723p\x00\xf7\t\x97Ps\xec>\xec\xb0\a\xc6BT\xd4\x15\xaf\xb1\xc82\x932\xfb\xbc\xfa\xc0\x82ZL\x00\x87\x99c\x8ajI\x8a\x8ekc\x87\xbes\xe8\xa46L\xd1\xe3\u06bdC_\xe3\x03\xbb\x03M\xfe\xe8\x80\xfd\n\x81\xc7\x04\xce,\xee\xd2\x01\x0e\u01ee\xf0\xa0\xc2n\b1 \n'\xb0J\u01b7\xcbB\x94V\xe3\x8a8\x1e\x89\xe3\xba\u00aes\xc2#\x11(8\u0311\xd5.+A\x95\xad\x90NT\x87\xae\v\xdb'\xaf\x1eTn*\xc7\xd5K^\x89\xab\x87\x951\xaf\\\xc1\x04\xd9'j\xb1\vb\xfdD\xf4\xeb\x94>\xa6\x0e\xeey\xe5\x11\u0220l\xea\xfa\v\xab\xabJDb\t\x89q\xf7\xcb\xd99\r9\u0148\u018b\xb9c\\Pg\xc4sQI\x88\u007fH\xe2)\u07c4\xf8\x16d\u04895\xa9d\xb7\xb9G\x90\x87\xe4~z\xebR\x80\xd0H\x81\xbe\x14\xf6u\xee^y\xf47\u075eu\tP\xf6;\xfc\xe6\xf3\xac\xca\u007f4\xc2}K~Miq\u03b3\x8f$\xca]\x9e\x1bm\x01\x97\xe5\xcb\x0em^\x8d\xb8\xe3\xce \xaef\u04be\x81\xec\x97BRc\xcfE{\xfb(]g\x87\x99\xfc\xab\x03\xb8\u053e+e\x9ct\xa01\u0505P\xf4/\x84\xd2D]o\xc1n\xb3\xa4f\xfcJ\u0372\x8ct2\xf9\x01\u04a4\x171\xbb\xadT\xf5Dc\\\x1a|\xac\xf3o\xe9\x9b/\xe4\nm\xad\xb2\x90\x01\x19\xae\xc1~\x1fU\xf9b\xd9pU\xb7&\xcb1\x81#\xa6\xedI\x92\xbb\u07e8q\x0e\xa2_\xa86\u052c\xf43\xb5p\xeb\x98\x16l\x9d\xfa\x0f\x10Ez\xf4\xee\x0e\xa8\xf3N\xb3\xab|A1*\x98/X\b\xc4\xe9B\x9d\xb0\xa1\x8e\x9e3\xb1\xe2\xbc\xe1p\xbc1`\x0e\x9d5}\xa6j\x19!\xc5g\xadB\xa9\xe4\xe5\x8f\u70ad\x9f[\x98*\xe5\xfbZ+\xd5Gw[5\xe9\u02d2\xf4\xf8\xbf\x92\x96>\u0257\xa4\x87\xaf\x96\xca:\x93\xab,\n\xb5\xfcb\x8cuX\x9c\xbe0\x81\xa2\xf5\r\xc7mW\xd0\xd8\xfcH\x91\xdd\x04&\x89\xb1\xe9p3\f\xeb:\x8a\xdcg\b/Y\xc8\xc8x\xbc\x9d\xe6\x19Q\x0f\xedO\xf3g\xf4r0\x87\xa1b3p\x96\x8ecN\x80\t\x8d\x14\xc4\xe2dk\xae\xe5\xc1\x8c\u05cdX\x9a\xa3H\x19\xa1\ff\\\u070dv\x89#b\x1d\x06\xea>\x88=\x0e\xb74\xf8\xd0,\xf1\xb2>\x11N\x80\u4637?\"\xd2\x11\xa6\x9d>\xe8`a\xfb\x84\xaf\x19\"Q#\xa1=8\xe2\xed\xa3z\xb0X\b5:\x9a\x86r\xc4.\xd3\x11~\xcb\u0622\xfb\x94\v&\nc\xc6\x04\x9e3\xc1y}\xb1<\x94\xe1D\x81\xad\x1bh\xc9\x172\x99\x84\x8ar\\\xaf\xcf_\x1c\xc4\xeb\xd1\xc2\xc4\xff\xdf\u06577\xb5\xb1;\xed\xfe\u007f?\xc5=\xdc\xdf2\x13\xcb\t\xe4\xdd\xed\x12.\x96\x90\xe5`\x92\x00YH.\xe5\x1a\xf0\x18\x1c\x9b\xb1#\xcb\xc6&\xaf\xbf\xfb}\x9e\xee\xd1,\x86sN\xbd\xb7\x8a\xf2H\xad]j\xb5Z\u076d\x06cK\xad\x06\x81Y)U\x94\xbc\x88\xb7s\x9b?`\v\xcaR\x0fKs\xbca~\x89\xb6\x0e\x98\xaca\xa9\xd9\u0724\xe6C\xcamdz\u0315,C\x1e\x86$\xc745\xe7);eV\u0321\xfb\x8f6\xcd]F\u5135\xa9~\x99\xbf\xdd\xdd\x14\x1b(\x13\xf0\x10i@\xb9\x90\xa2\xa7g\xb4\xdb+\xae\xf6\xe6\x01\xe6ul\xb9Uy'\u056bT(8\x8aJ\xe5RH\t\x14\x05\x12=\x06\x82\xf4i\x85\xad^\x95\x9dQ\x90GY\xe7\xdf_\x9a\x84\x87\xe9\xb8\xf3:m\xe1\x0e?\xd1\xc8q\xda\xfa\xc1+c\x1f\xf5A6H\n`\xe6(&\x02?3\xb0si\xa5\u04cf\xe6\xa2\xc9b:\xe4d\v\n)\x06\xf2\x02\xe2\xd6.H\xba\xef\xf0\xd9\xc1d1A\xec\xf3g8\x1c^\x16r\xb8\u03b4\x10tv\xdd\xf7\x8c\x96\xd8Ss_\xcd\x00\xf0\x94\xe4\xbf\xc9\x00\xa9}\xeb\xd6,Y\x9bJ\x1a\x9f5{/v\xfe\x13\x929\xe9io:\x99IWG4_\x184f1Y{\xdeITO\xbe#\xe1\u007fA\xb8\xd3\u0113\x13,\x9d\x8ev\x84\xbew\xedN\x1el_`b3N\x12?\x1c\u0145,\xd1\x195r\x80*\x97/\u0205\x14n\x00AP\x96\xc7%\x8d\xc1\u03bb\xd6\xcb2\xf2\xb3\xb5\xdc\xdd\x06h{w\x89\xb04\xb8u\xadF\xce-\xf6\x05\xc0wyE\xfb\xc9,\xe5-\xd4.\xd9Yf\xbc\x1b\xf6\xfb\u0622\xa8\x0f\x19O[\x9f\x14;\xec\xce\xf3\u007f{\xa6\xfd\xe3\xf4>\xd8r\x1e\xc9Ef\u0189\x00*\x16V\x9e\x13\xa3\xa2\xbf\xc7\b\x93\xbf\x00\xc0\xa6\x91~u\xed\x03\xe4K\xad\x95|L\xed]\u014b\xff\x9b\xbd\xb8\xb9\x8b\x1fW\xb1\xecD\x17\xcfg\t\r\xca9\x8a\xc2\x1c\xb8kV\x8d\xf4\xd9\x19\x81\xbaV\u0452a\xe1oI42\xaa\xb3$5\x9dy\x1a(c\xf1k\u0261\x825Om\xe1[E\x14\x1d\xff\n\xcd\xc9\\\x9c\xeb\u028f\xf3\xa5o\u02f4\x81\xcb\xc1\xd2\u05basn\xfa\xb8q6\xf6S<\xf6\xab\xf4)Rl\xe8\xb5z1\x13Z(\u064f\x8e\xd3\xc6k\xe4#~\x9c\u01e6@\x87 \t'N\xd4V>,\xe7\xe6*\x86E\xab\r[\xab\xe1\xe8j\x83_\xcf\xf3\x8d\xfb\xc1E\x0ff\x1e\x04\x94CscRa\xdc\xe5&~e\x06\x06:\x1d\x15\xe4a\xbc\x90\x9e#o\x89\x91\x8c\xf5\x93\xd9->\xd7\xc9Tg\xe8\x10]\xa7\xc0\xbe}Xm\xe1\xf0\xc9\x16\x04\v^\xb6v$@q\xdaq\xaa\xc1}J\xd6\xd0\xf4a\xad\xe9\xc3Z\u04c7\xda\xf4\xa14\xbd\u649d\xe3l\x80^\xf5~o\x99\xe2\xf0X\x1bR\xd8:\x15\xbbw\xc2\u040e\x9e&f)\x13\x03ES\xae\akM1\xf5,\u0216B]\xf5\xf7!g\xd1\xc851\ns\x8fOl\x1c\x00=\xd7(\x00\xed\xf0\xa6\"\u015d\x10\x8d\xb4\xe3\xb4\u0654\vG\x91\xe2\x90\u00bc\xbb\xae\x1d\xbbF#\xf0K\xc2\xd7E\x0e\x05\xe3v\xe8\n\xfa$_\u0382\x11\xe4\xe0\xae\xd4\x19xj`\xb5QEy-8\xb8\xaaC\xd1a\x8c2\x10E\xf4>\xcd\xf3\x18_\x18\x1d\x98qno@C\x19\xb9\xed\x99\t\xd4fim}fv\xf2\xf7\x97/^\x9a9k\xd0r\b\x15k\x96\xc5f\xc0\x14V\x83/?\x02\x05\x05\xbc\x19O\xae\x92\xf1\x1e\x95\x1bHI\xf8\x15d\xba\xb67\x19\xa6,\x9c\xcam\xd8\xcfTw\u064c\xd6\x04\xb5\xfd\xb9\xb0@\xa1[Jb\xfa\x14\xc1\xdcY\x1c2S;A\a_\xbc\xa4\xacF\xd872$\r;\x8d\x8d\x02\x92%/\x1cM;5\x84\xb2\u00ab\x14\x87>\xef\x8d$2*\\\xc3}\x93bh\xc69z$$\uc2c4\x93\u0604\xc9,/\xadz[\u0569\x9d\x93\xaf\xaa\x1e\xc9\xf2\x10K\x91nPU\x1f\xe5K\xb1\xe0R\x84\x04\x9eG\x18R\xb4\xd0U\xc1\xf9\xfe&\x96\x93\xbe]\x1by_\x05\xb5\x8b|\xa1o1\xa6\xbe\x1d\x84Y\xbe\x06g\x92\x84\xbe\x8b0\xc5\x15\u00b4>;Z\xa3\x0e\x06\x1d\xde\x16\x84\x9a\xff\xf7\u007f3gmHk\fr\x8eP\xaa\x1b0\xe5\x064\x03f\xa8W\xb2\xb1X\xb8\xd66\xd9Lm\xb1w\u05b4\xd5\u0282*\x89}\x17\xbc\x1e9\xd3s\xf1\x1f#)\xd9F-c\xa8\xe3\xf55<L\xecX\xf0pbs\xf8\xee6p\x13\x99\xc8<4s\x18\b0\xb3Si\xfd\xf2\u064c\xc5\x06\x1b\xc86\xa8\xf7?1I\x89lO#\xc9q\x8a\xdb\xfa\x0f\xfe\xbcN\xa1u\x9c\x9b}\xf9T\x90\xe6OP=\x884\xaaB\x8b\x1brRi\xceI\x11\u007fO2\x156^\x13\xbb\x15\u0649\xe2w\xc0x\n\x18\x18^ \f(\xb1\x1f\xe9\xa5`\xe3\u078e\\\xbb\xe7v\xed}\xfb\xbe\xd1(\x1f\x8a\x93\x13\xfa~\u007f\xa9\xf3\xbb\xc4y\xb4\x97\x81\xe2l\x13F\x9b]\x9a\xbb\xc6\xc2\xf1|!<\x13\xf8\r\xbb\x1ac\xe7f\xd1\xd4,\x1b3*\x15\x8e$\x8c3cf\xb6!\x17\xe8\u016a)\xb7\xbe\xa0\x05\xbeF\vV\x88+-\xf0\x15Zp\xe8\xa2\x11\xcf\x1e\xc5-/\xb8\xb5\x82\x88i\xd2\xd9\xfa?0\xdf\xddj\x15\xa4%\x0e\xe7{\x84=;\xe1Z)\x9c\xd1\r$\xab\xa1\xe5\u01b26\x13\xd3LbA\xc3p~\x9c\u027e\xdb2i\xac\xdc\xc0\u069cg\x16\xb4\x8ei\xefi!\x05\x16{+Y2\xcb\xd6L\xf3^\xc6\x05K\xf4\x90\tkYy\xbbJ\xec\xad0\xc6\xf2DO\t\u007f\xa1\x9d\x8b\xf2E\x96\u074d,\xf8\x14O&9?nr\x17\xa3\x9e<d\xa4\x1a\xd1a2\xa8Pl\x8a\\\xd4\x199[\u0250Y{\x96u\xbe\xa4\xad\x8b\x149b^wm\xd6\xd6\xeb\xa6\x13\xcb~3\xb4\xa5\xb2Z\b<f\xe7&\x95\x0e\xfcf\u03f0)~;\x8a\x12\xec\u01b7\xf8\xd5\x1e\xcfl\xd2N\xacR;\x10\xb2M\xb1\x02\xa9D^\v\xee\x1c\t\xed):\x89kiWp;u\xad!\xfe:3dwXG\xf7\x9cz\\\xe4\xd4\x00\x01rY\x17\bC0\x80\xdeK\xa9\xde\f\xc8\xfc\x01\x02\x11\x99Y\x98\xc8\u0106\xdf\x15\xbe\xa3\x8d[\x0f\xe0\xf95DX\xba\u079f'\x87%\xe0D\u007f\u0214\xaa\xeee\xe6Kf.2`76\x03\xa7\xf5\f\xd4\xe7m\u018d(\xd3U\u06d4\xbc\xfd\xe2jy\xfb\x80\xbe\xecev\x8e\xb2v\x80\xd2\xf6s\x8a\n\xec'\xee\u0450i\xe15\u04c0\x99\xe6\xcc\xf4^2\xbdK\xb5\xe5\xe3\x8c\x02\x8e0\xde\xcf2\xdeU\x8eG\xef\xa5'\x9f\x81I:\xf1\xef3=\xd6\xcaX\xb2\u011c\x1fK\x1e\xf5[\xa0YD\x1f\xae\xe9k\u075f?h\xf5\xce;\xf8\x03mGQ\b\x13SZ\x92\xbe\xb8\xa2g\x85}f\x18\xdcy\xcdqH#y^?\xae\xb2\xce\xd7,z\x9d\u016d,\xe5\xc7|\u02acc\u0224i\xa4\xe9\u07f2\xd6\xdf2\xb3\xcfJ`\xb6<\x94\xc4q\x1a\xe5/<\x9ax4\x80\x9f\xc3\xc3\xf5\xff\x0eo5\xe4\xf5\x86\x16\xf8=#\xfe\x06c\x88q\xfeX\xcf\xd0\x00\xf8\x06\x97\xfa\xd8x\x9a1\u02d1\xd1\xc6W\x88:\x10f\x16\x85\x88y)\xb5\x90\x920!\x0f\u1a76X6nI\x9a\x92\f\xa6\x860\xce\u0254I\xe1\xc2\u0310\u0718'i\xb045\U000d4a96Ax\xd8\xec!y\xfa\x91\x89\xe4\xc2'W\xb8?q}\xb5\x97\x94L(c\u0093\vGyG~\x9fW\x8c#X\x03\xaa\u04ad\xbe\u0235\x98\xb7\xa9V\xe7\xa4.\u007f\x9b&}>j)\xa9y?%B0\x0f_\u03b2\xb0\xb9E\xbfg\xa9]\x90\xbe\x82\xf7\x8c\xe3\x90:\u0258V\x13\xba\xf4S53G\xfe_=\x9aD\x00-\u007fdlk\x98\xf12\xa1\xb3\xc3I\xc7S\u03d0\xc4\u85a2\xcd]\xfa\xf8\x91\xfch\xc3\xe2\xe0.\x15\x83*\nE@\x86\xc66s\xcfiR\t\xc2\x14\r%_\x9b\xea\xbb\xfc\u0365\a\u060ec\x83B3\x162>\u0596z\xa9\x85Y$\u007f\xba\xfc9\xe2\xcf\t\u007f\xde\xf2\xe7\x98??\xf8\xf3\x9a?\xfb\xf8i\x0f\u0160\x81\xbb\x87\xe5O\xb9J\xe6\xa7\xfc~\x93\u07ef\xf2\xfb;\u007f\xcb\xce\u007f\xccm\x812\x1b\f\x17\xc0\n\xd8`\xba\x80\xdb\xfc\xdf4\x83\xb9p\x11\x055\xacj\x1b\xd5\xf2\xf7\xab\xfc\xfe.\xbf\xef\\T\x91\xd0\xe5\x85~\xe5UZ\f\x06\xa3\xc8L\xa8\xd6b`\x18Q\xca\x11\xc9xB\xc9`t\u009eJw\x1d\u007f<\xbb\\\xa5bc\xe5!\xc79\xd37\xaeJa\x86v\xacr\x97\xc4\x0e\xffNf\x88\xa9`\x80\x1a\xc8\x1eL\xae\x02\xda\xe5\x90N\x99\x82}\xf0/\xdb-\b\xc1&rcJp\xc9M\x9bvbpP\x80\u049d\xa4\r\x84=uW-'\xbf\u0451$oK\xf2[I\xce$!\xe5\xaf\xdeN\xa6\xe2U&\u35cax~_^\u0694\xdf\u007f\xb9\xb4\u07b0\x85+\xa65\xae\b1lECG\x9a\xf2\x92)\xbc\xf1\xb0\x01\t\xad\xa3\xf8\xf1\x9c\xa1\\75\x9c\xd1\xc6\x11\xf0\fq\xe3\x11iW\x9c\u0548\x92{v?\xf4\x98E\xdc\xf1\xaf\x13\uc15dV\xd0\x037\xec0n\x0e\xdb\x02}\x19\xa0i\x15\xfa/\x01\ua6806r\xe8v\x80z\x85\xae\xd7\xf5#\xe7\x8fEfi.$k\xabX\xc9R\u041e\xe9z\x05\xad^~\x95\xd7;\u0738\xccT\xac\x98\xce\xf2:\xbf\x0f8\xab\xfb\xa0\x8d-\xe2\xc46\xc7v\xb1n\xe4y\xa9\xd3\xfdA(\fu\x00|[\x00_\xa7\xc1:\x1c\xe0n\x01\xde'X\x11\x16\xf0\xa3\x00_\x0f\xb9U\xd9r\xedZ\x8c\x9d\x14\bp\x16\xec\xc6t+f\xec\x93Z\xb7+kr\x8dU\xca\x01q\x1b\xe4\xa1G\xabz\xe2\xb80\xc4\xcef\xc1\n\xbe}\xedd\xd6@\x8f\xf3Pl\x18`\xdb\x04IHA\x81\xa0\x87\xb0\x82\xc3\xe9\x10\x82\x04\x06\n\x9f\x87r:\xcd>\x8a\x8d\xb5v1\xd5\bH\x98\x9a\xde=\xff\x17pTN\x81\xb1\xb9uv\xe1\x9e\xd3\x16{\x17\x9b\xb7O\xd5M]ks'\xea\x94'\u0122\xcaxy5\x81\x9a+\xaf\xa5A\xeb:'\x91\x8f;\xc5i\xe9\xe5<l\x81\x06\xbd\xcb\xf8\xfbP\xacz\xc0\t\x1c\u06ee\xb3\xc5'\x9cx\xc8\xfa\x19\x95\x90~\xa74\xd4\t\xe7\xa2r\x06y\fv\a\xe5\nUe\n\x18&\x99\xdbC\x80U1\x8c\xd9\tA\\\x04\x89\x8a\xe1vdgH\xa9\b\xcbM\xe5,\r\xc1\\\xcal\x9e\x16>\v~k\x11\x84$GE\xc4\xd1\xd35`\u039cW=,\xf1j\x87w\xbcpi\xd4uR3\xf4qn\xab~\x13\xed\x98\xe7x\x12\x19\a\xe3\xd3\u0425\xdc\x06\x15I&o<7\xb1/\xec-\xd6&T\x1c\xb7\x93\x80t\x1a@\xaba$\x1a \xa0\x18u\b\xc6T\xdd{\x9c\x9b\xf3\x94\xc2L\xea\bS\xb3m\xeaF\x9a\u0232\xad\x9e\xb0\x06\x98\xa6\xdf\xf2\xb36\x0e\xf6\xbe\u0170\x1d\x19\r_\xe5\x05\xf4\xc2Af\x00\u007f\u03ef\xa9\xda8\x99\xf4\u04d9\u0208pT{\x93\x05\xfd\x8bR\x1a\xf82\"4\xc9\xe2|\"kL\x83\xe7T\xaaF\xe4.q#\x8a\x15\xc7\"\xc6\x15\xf4Q\xb3\xae\xc0P\xf1\xd8\xd6\a#\xc9S\x0fF\xb6\x1a\xcabi\xbe\xc6\x16\x015\xf95\x9az\xfcN%\u7bd8A\x0f\xfc\x19\xbb3\x01\xe6\x97\xcc\u039c\xbc\u03ac\xc6\xc0\x04\xc1f\xaa\x02=\U00014e6b\x8e\xb1\x89\"\x8aV\x029\x01\xe3\xe6)\xf0\x03\xe7\x91.\xdf\xd3\xf2\xdd\xe4L\xa5N\x0fli\xbc\xd01\x99W\xb9\b\xdc\xc2\u0092\xccL\xf6\u05d5\x11\xc1\x1eU\x00`\xbe\xe5\a:\xd9}Y\xb9\x85lL\xe31\xae\xdaP\xb6\x9a\xcd-\xe3\xd4(\xadT\\\xbb\xb5`\nVQ\t^X\x8c:\x1eU\x17J\xe9e]\x90\"K\xe9\x02Z\x01\x11\x1c{\xa2$\xb79\xe5\x15\x84\xb0\x12e\xa6\x8c5\xe5\x117\x19.\x1c\xbc`u\xea\x9e=\x9c\xe9\x8b@\u04b8\xb5v\x91\x18\xd1wU\\\x9f\xe0$\x1a\u0483\x86\xce\xc9F\x9f3\xab\xbap\x1bn\x8d\xa3`\x99\xd1JU\x15\u019b\\\xb5>L\xf3\x9d\u00fc\xa3Yb\t\u0627~:~Tw\xfc\xab,\x95\x91F\xd47!A\xfa\xda\x1e\xb4\xcea\xe2\xb9m\x82\u05d4\x18\x83\xaa\x18\xdd\"R/U\xe4[W/\x99w\xb9E\xe7\x14\xdb\x14\xecY\xf8\xab\xd0\xff\x1bW\u7245{\x19\x8b\x9d\xb4\x19Zr4&\xb1\xc2\xe2Ll\n.\x8dZ\xd7R\x97+[\r\xef\xb8b|\x91\"\x04\xe37\x9c\x00/54\x84Fl\x9a\xca\xd9\xf7\xe2_b\xfax\xda\xd12\xc82\xd42;\x9as\fnNC\t\u029c\xe7e^J\x99Y\x8dIy\x84^9\x9bbu\xb7\x18\xfd<>\xd0\xc2U\u0521\xd9\x1c\xa4,\rF\xa5w\x1e\x05\xb6\xce2S+\xa73\xe8sQD;\v\x87\xba\x06H\xc4H\xb2\t\xd1\x10A\xaaN!,\x04\t\x1cf\xd7nF\x98\x86p(V4{\a8:;z)\xfd\x99\xb5>f\xad7\xbcc*\xbex\x96\nA\x14\x83\xd1\xdaNY\xf24k\xfdK\x19\xbbJ[\xcb4~\xf2\xb8#\x90\x9a\x8fj\x8a\xc6C\xb2*4\xab\xe9U@\xa0\xcfY~;l\x87\x80\xf5\x9d#p\xa9\x9d\xe2r=V\x8e\xe0\x84\xc0\xa7\x8c\xff\x0f\xb3(\x18\x11 \xa4V)\xc5#Y\x171\x95r-\xe1/\xe2\x16\x90\xe3S\xc6\xdf\xfb\xd4\x04Sut.\x041!\x95\U0005f96ds\x0e_\xb5T\x03\x17i\xa8\u0417\x1d\x05p\x19\x8d\x03'kuM\xa3\xa1\x1e=\xd8\u065a\xc4U-\x95\xac\f\xe9R\x06\xf5n\xa9\xcee(\x9f\x13V\x11*\x963`J\xaadi\xcc\x12\xd4\xda\xf7\xce,\x9d\x15\xf7\x8b\xfdavc\xa34\x04!\xc0\xbbq&\xfcU\x85wt&\t\x10\xe7\xc7\\\xb1p/\x94^:\xc9\x15\xf4*\x99\\b\xa7\xcel3\xeb\xc8i\x87z\xf9w\xe5\xec(\vo/L7\x87\x9e\xb9\u069d\xf3\xc1\x85]\u01b6312\x90\x1b\x12~\x18!\x9dK|b\xb9c\x82\xb9Ql\ue74dP!)Ip9g\x80\xe8o\xa9\xd6 \xd0v\xeb\x1d\xe5Z\x1b\x8cC\xaarr\u007f\xddVY\xe7L^?'[1h\x16,\x12\v\x03\ua4ec\xedE\x10\x17\r\xd1\xe5\xb8s\ue8b8\x95\xf8\b[\u05cb\x14\u026b\x91\xe0\xa3{oy\xf1e\x11\xa9M\x1d\x8b\x0e\xdbg\x8e\xb9\xa8\u007f\xebD\x98\xac\x95:\x185=\x06y\x1b\xa4\xf2\xcb(}\xfc>r\x18\xba\x06{\b\xca\xe0:\x91\xb7#\ap\xcf\u016d\x1d\x8b\xfct\xd5\x18R0}\xe3\u0223\xa1\x93,X$q&\x91=\x137\xa1\x00\x93\xbat\x86\xd67\xfe\xf3\xdf\xffu{\x1b\x82\xad\x16\u02e5v\x82rC5\x83\neR\x96\xc1\xfe*;\xea\x8b\xd5\xd5\xde\x0e%\x1e\x9b|Rj\x06\u02c75\xcb\xc5 \x95\x16u>\xd7\xf8\xab\xb9\x10\xd3\xef/\u0097\xa7y\xec\x1d\x8em\xbb%\x1c\xd1V\x0e:H\xa6\xb4\"\xd8\xe2ke\u00b0Z\xc7\x00\x1f\x92\xc1r\x82+5K\x811\xaa\xae<mr\x9b\xd6\u05b5n\x19\\#E\u007f\xc5\xf2\xd4_\x01y\x86\x10xT\xa4\xe8\xd5!}\xa8\xd5\x16\xec0\x03\x8b\x93P\xd9\u04be\xc9\xear\xf5\x01\x1f+\xa0\xd1\t\xb23s]cRQy\xd0\u007f\xe5\xb8\x11\xa9\u0344\xea\u01c7\xada\xdc\x16\u03f1\xd1\xc2BAe\xef(8E\xe8\x16!S\xd7q\xfa\u04b0\x80\xee\xef\x80\x15R\xf0\xda\xe2\xd2\xd3ZX\x10\x0fs\x11\xac\xf5\xa9\xcb\xd0\xd9e\fM\xab\xaa\xbf\x18sl6G\xd1\x1c\x98\xe6\xa02\x13{\xae\xe2\u05708\xaa+\ahp\x95\xc0M]e\xdc\xc6<\xf3\\8+\v\xd1\xfeX\xcc\xc9~9=dAjU\u0623Q\xb4\x90\x8b\x9b\xe2\xf0\x92[%:\x13-gf\xfc&K3\xafrXU{2\x93\xd8^\xd08\xf8\x92\xa1Or\xa2\x8b\x00\xbf\xa4\u0221\x1c\xeaL\x94\xfe2 \xdf2\xd5L\xf8\xc22\td\xf9\xb1\u04b3T\x8ac\xa7\xc1d\xae\x99\xf1zA\u02ce[\xcc[A\xae&\xe4r\x02\xbb5iO\x82\xa1\xed\f\x9b~r\xf9l\x88\x01\xc1G\x13\xc3\x1d}\x94\xc9 \x98\x15\x0ec\xb6K\xab\x9a\x9d\xff\xd8M\x1a\xf38W\x933\xd9\xcc.\xd7\x1a\x15?\x00kUCH\x9fU\xd49\xce\x1d\x04\x14\x9e.#/x\xbcm\x89\xc1|\x17If\x17\xc6F$\x02\xd7\xf8\xec\u0234m\xc3kC\xd0\u02bap\x0e!$\x01\u038d\xd6\x02\x85.\t\xd5X\x8fI:\x90(c\x9d\xc5#\xbb\xa3\x85\x99V3\x00\xbc\bvG\v\xb1;\x1a\x98\x1b\xeb\xc2a\x87\x90\x04\u061c+-)\xfa\u01a3\xd5i\x9c\u007f\xda.\x1c\xa1\xac:\xc1\x93C\x8d\xd1\xe6\x82Y8\x81\xaa\btzl\xb6\xf3\xaf\xbd\x03\xaa\"\x10rfq\x909AL\x95\u7470`g\xbc\xd6\xf9T$%\xb4\x8e\xb3;\x01gE\xe6Wq\xaa\xf9\xe5\u027d\xb3t\x8f\xf7N\xae\x9c\x92\u025d:\xaa\x05\u0457+\x87\xed\x1d\xfa`$f\xc7\x1bM\\H\x13U5\x10\u0440U\xaa\xe1G\xb0l\u0239\aB\xb8\x91$\xaa\xf6\xa0\x12\x14\xb2@\xf1\x96\x1e\x90\xf6\xc1\xc9\xc4\x1d8\xf3\u0199#gN\x9cy\xeb\u03313\x9f\x9dy\xef\xcc\x0fg^;\xb3\xef\u03293\x9f\xeaG<\x8f\xc5_\x9f\xc8C\xfd\x88~\xba\x98\xc95s\u06dfL?\x159@]\x8aI{\xc4UE\xde\xef\u014bi\xa0%\xa4t&\xb1\xc7\x19\xbe%1\x01E\xcf\x03BU>Gc\xaa\xac\xbd\x15\x15\x9e\x9e\xfb\x85\x8bTO\xc5^L\xfc\u05b3T\xb9\xf7\xb1h\x12\x03\x99\x18\xab\x06/\xf0k\xf2\xe3\xb1\x162e\x13n\x13!?\xe2\x8a[qB\x93V9\xbc\xb9\xa2(\x84g~\x1c\x861\xe30j\xeb\x03\xaa\x11\x96<\t\x8f\xa1\xcd\x04#L\xb0\xa59\xc2D\xb7!:\x17\x8c)&E\xbf&B\x06\xf5!\\\x12\xb7%*\x1bXa\xb2\x89\x857\x8b4\xa70M\xa6\xa7\x00\x16R\x80$\xee\x06\xde\x03\x97\u007f\x98\xe0\x98\xc0\u007f\xecN\xd4D\xa4\xe7\x9aM\xe5\u007fl\xd71\x9f\xb2A\x880\u05fa\x98\xd8\\\xbc+\x1c\x14.c\x93\n'\x85e\xd6y\xc6-#\x0f\xc8J\x85\x93Ta\xd2F\a'\xe1$\xa7\x0e\x015\x1e\xb9\x85\xe5L[\xbe\xa8\x15/\xc2v\xd8\x1e6\x1at\xdaz)\xc8\xee\xed\x14\xb3\xcbh\x8cl7\xd1X\xc3q0.\x02b\xac \n\xf4H\xb4M\x84\xb6[c16\x1a_\xe6\xe6\x17\xad?8U,ZD\t.\v=\xff\xc4c1m\x02\x8cvL\x05\x865\x8b4\xa7ii\x9e\x16\xba\x9fh\xaf\xd5\xf9\xb1\".W[\x9e\xedO\xd1[Fb3D\u03c7\fWz\x0e&\xa4\xd6S\xac\x84\xbe\x9e\x86\x91~\x85C\xbdT\x84@e\xf2\xcd\x17o\xa0K\xce\f\xa8Z\xbe\x9a\x1d)\xb4\xa3\xf2\u00b3#\x13\xf9M\x8d\x00n{NhM\xc0\xc1\x14\x0e\xa4\u0300\xf89\xab\xe8\xf3\xe7\xb2\u007f\x8ae\x1e\x84e\x1eT\x96\x19GK\x81\xbfs\u00b9\f\xcc\u0592\x18a\xe8\x8bm\x06 \xa3\xf4\xb1\xa0y\xaf\x89\u071a\xe5\x1a\xdd*5\xe2\x8b\n\x81\xb8E\xf7\x16\x15\xc2p[\xd9\xd6}\xa4i\x9c\xf6\xb2\xb7EW\xfa\xd2x_Z[\xc4\xed[i\ud3ad\xdd\x12\x86 [\xd3\xf3\x03\xf2V1\x15\x0fm_U\xda\x1e\xa1\xfe\xabK\xd3\x03\xbf\x83o\xbb\xa7#\x1c\xf1\x83=\u012a\x18S\x05\xb5$j\x9a\x91$M1\xf7(i\x97B)1\x86e\x89\xf1]6\xb4\xa9\xe5\xbf/d\t\x15\xfb6\x1b\f\x9c\xcd},\xba\xbap\xe39c\xce-\xd3\x15\x85C~\x80\xc9E&.\xa6\xf2\x8c\xad\x1cg1\x16\xf7,\xf7}\x1c\xc5\xe6T\x0f\x9eoub\x1d\xba\x16Tu\xdb\xed\u07f2v\xb8\x87\x83[l4\xc4\x17\xd5\x17\xc7\x1by\x94Q>\xe2c\f\x1d\x9a\xc1\xf0@:(\x03c\xf3S\xfb\xc1\xd6DUI\bm\u04f2\xe8\xbdygNP\x93\x04O\xcd\xdb\x10|m\xba!\xb8o\x8e4\xf8\x8dyC\x90y5\u023c!X\xe4=\x00\xb4\x97\a\x01]!\xf8A\xbbe\xfbQ\x8f\x9a\x1e\x02\xb4\u007f\x80\xac\x14r\u38f8\x98O:E\x96\xae\xb3\xbf\u015c~\x15\xb3\u007f\xe6\xfb\xaa)=\xb9\xa5\xaf\xe47\xa2=T\x9a\xb8S\x1aM\x81)\vm\x16M\x95\xb68\a\u0337\x85x}\xd11\xf3q\x99i\va\xe2\x13Q\xc6\x14\xef\x17v$\xddAu\xbeb\x06\xb9|\xeb\xf9\\y\x95\xea(\x1f\xa9\xb0\xe8\u029c\xd7O\xc3pJj\xb6\xa4r.V\x88\r\x05\xa1\x12\xb5|A\xaf0\x04\xb1iP\\\x12v\x05\x16\x0eW\x01\xe5%|\x85\bM\xf23s'\x1c\u64a5\x12\xe1Y\xb4\x93\xc2\u0266\xd6\u05d4\xf4\x9c\x13n\xa7z\u0617\xac%\xcdJ\xf54PF\x87\xdfp\x10j\x8b\n\vgal\x8e9\t\u059b\xd3\u02bd~\b\xf9''\xda\x06\xa3R\xa0'\xf5\x16;*9\xc8:z\x11>\xc9X9?\x1chK\xcab=\u00ae\xb3\u07d4\x8f\xfa\xeaD\x01/\xf2j\xfaA2\x1f\x9d\xfd\xdd=_\x9a\xbf\xc9wU\u0659\x19\xc0\xf8\x1c8\xd5Q\x04\xc9\xf5\x12\xbe\xbfU4\xbeB\ua6cd\u0515\xa6V,s\x8e\x9c= \xdbf\xdf8\xaa\xaa\xf1E\x8c\xb0\xd8\xec\xb3\x1b\xea\xbb\xe0T\x82~\x92[2g\u07a4\xde8o\xbc\xb7\x1c\xc4\x18\xd8Z5I\xe1\v\x12~Y\xb6\xb5]\xf8\xa7By\xfc*\x1e\u04f2\"\u034b\xe2\x10\xf6\xd6+{\xd0\xd1\xfej\u0096\x01\x94\x95u\xbe\xb5\xde\u01ed\xbaC\u04a1/dDy\xd9\xf8W\u0373}\x16c\xef\x8e=\x8fgO\xef\xf6\xea\xdb^\x96\x05[0lRm\xa8*\xa1I|`'\xbe9\x84\xc4H(\x15\xfb \x1cte\xb6\x89\xaf\t\xb0\xd5\xfc2\xbc\xffQ5h\xddJS\x8d\xc6\\\xbe\xa7\x82\x90?k\x8f\xb2?\xe0\xf3\x89Hz\xf9\xf7\xcc\xe7\x82\xea/\xd5\xf3o\xbc\xa19\xfb\xad\x1e\x95\xfe\xa8\x19\xa5MK\xf2\xd3w\x00\x035\xe4\x9b+\x9d&\xb8\xea\x0e\xfd\u02a6A3\xa0Y\xf8\xdd\xd4\nl\x16PE\ao\x8ccpL\v\xa7\r\xca\xf1\xe2\xbc\xcdt\x97 S\xb87\xa5\x01\u007fu\xc9\xf2\xb8yl\xcd\xea\xd3\xce\x13\xed+\x0e\xc8\xd0\x14]\xd0\xdd\x05%\xb9\t\x9f\xa4!r\xad\x91\r\xad\xc54\xd3\xf1n(p\xd8{\x11U\x05\xee\xba\xe0\xe6c\xe9xA\u0283\xdd#\xc7j\x1c,\xf7=\u074c\u0512\x86L\f\x9a\u007f\xdd\x11Co\x10\rY\xec\u012b\x95\x94\xb7\xbfd\x1d\xc5hk^\xc6v*\xaf\xf6\x06~C;.\u03c5\xba\xe2S\xc3q\xe7\x92\x02\xd8\xc8[\x8c\x82\xa2\x84f.\x96w\x02\xf7\x00\x05;F}\xbb\xcco\"\xaeL^\xf8\xc7nx:\xe0+\xaf\"\fz\x88\x8f\xfcS L\x11$O\xc3\xe68~\x96\xc4q\xab\bW\x9e\xd8\xe5=\xd4=\xf6\xcex\xaf\xa6\x14\u8302^\x13\xa4\af\xcdA\u007f\xad\xdc)3\x81.\x94\xc5\xf6\tQ\x1a\xc1r\xc4\xc7[\xd2j\xac+\xf5\xba\x8f\u050e\x11\xf7!\x97m\xbe\xa1n4<c\x89\x88\xe19\x1f<\xbe\u0654\ad*\x04\x9dp\u060a(\xbc\xc0\xbf\x8a\x1b\xa7h\xe0\x91\x15wAf\x0f\x9c\xff:\x94\x821\x81\x1d\xf8\xcaS\xc1\xd2\xe6s\xdb\xea\x8a\x15\xef\ru\xfd\x1c\x9fvu\x91\x85\xaf\xba\xb6q\x87\xa8\xa4\xecS\u0182\xef\x0f\xa6\x18\xbe[\x83\xfdMM\x83\x97qa*\xe7\u0181Z\x8b\x90\xcd#\xa1.\xe94\xa7S\u01ae\xa6%\x98\u0192\xdc_\xfb\xd6\u009b\xbe\xb7;uP\xc5,\x83c.\x85d\xed\x1f\xce\xee\xf3\x12oO\x9d\x1a\xaa\x89\xb2o\xa8wz9#\u019c\x9cS|y\xa3,\u03e7#\xc7m\x87\x8f\xe9G\xfb\xc8Y(MO4\xe1\u0119m$\xb1\x12M\x88M\xe6\xedJ\xfa<\xa9t\xb9+3\x03\x9e\xa5\x0e\x91\x9b\xef\xee\xbe\x13\ny\x8f\xcf\xc8\xed\xf6@\x8b\xd5+K\xa9\x1f\a\xdb9\xda\U00034092s\x1e\xfcOP\x88\xf9\x06\x85Pz\x18l\x10rvg\x0e\xb2\x9e\xc6\u05d3\xcc\x0f\xb3yZ45@S\xf3\x14U\x84Z\a\xed\x01Z\x13\xd0\xf7\x01\xbdt\xba\x99\x97\a\x97\xcf3P21F\x11\r\xf7\x9a\xf8\x1d\xb0xSi^:\x05\xbe\xb6\xc0\xc7r^\xf6]\xeb\xd4\x11;\xdb\x18rt]\xc5\u0462K\xb7\xf6Ua\xb3\x9e\x88\xcd\xfa\xc4l\xab\u72bb\xda\xc4\u0735\uf0a4\xf1\x86\a\x19n@\xf7\\\xec\xdcQ\"\xd6\xfb\xce$\xe6\x9a\xd6\xee\xf7\x14\xa0\u0776\u028a\xefk\x15s]\xee8\xbb7\x15\x11\xef\xc8:T\u025c\xbd\xfc\xd4\x1bu0\u01e8\x04\x96\xf3#n\x82\x9b\xf0&rV\xa9\xa7\x17\xe4\xb2]\xbb\x88zM\xa0J\xbb\xbb\x9by\x9a\xe2\x82\x16\x9a\xd4\xdb;5\x8c8\v\xff\x01\xe6!\x0fTm\x8f\xcf\xec\x15\u0f78\x85P\x0f\xa1\xab\xa7\xce\x06\x8e\x98N\x12t\xd5\xc9hn.<\u019d9\xdey\xa1*\xfe]\x0f\xe6\xbb:\"\xe8+8\x85\xabf\xa6\xebZR\xf3\xa1\x1d\xa4\x9d\x9bRR\xc9G^-X\x97\xe6 @\xce99\x04\xaf\xcd\a\xbb],\xe0\x1e\xf9\x98C\xe2\x10\xa6\xefC\xa3\xf1\aXt\xf8}\x0f7P\xb1\u06d4\xae\xfbp\xd5p\xe5c\x86|O\u007f\xb1\x87>x\xb8\xba\xb0_\x884\a\xf8`\ubfb1^-\u0394\xf5l\x83\xf5|\xf3\xbcG\u0593_\u0758G\xe6\u013c5\xc7\xe6\xb3yo}\u03bd\x99\x1f\xf6\xbdR\x9f\xd7\b\x90\xf8\xec\u3af7\x96S\x84\x94\x96\x9bO6\xb4\xfb\xfdB(\xa3y\aH \xa5\xed\vUO|\x02Gj\u007f\x98\x13\xbb\x1f\xb7\x10z\x8d\xd0il\u0782\x9e\xa2\x949\xb6@\xbaw\u0451\xb9\x00LQ\xees\x0ej\x9cT\x80\xb7>\x9aF\xe8el\x16\xd1\xe7\xe6q\x1c\x9b\x038\x19\xe6\x85j\xc60\x9a\xda\xf9\u04e6\x0e\xd8\xd4\x17m\ua035\u03b4\xa9/\xa1\xa9\x12\xd8\xdfl\x8a\x8eL\xd0>M=*\x9b\xf7'0\xf8\x87k\xbeu\xb8\xbf\"\xf8\xda5\x8f\x9d\xe0xA\xd6ty\xbe\u069f\xed\x9f\xf6\x1b2}]+\xef\x0f|\xfb\xb9\xcb\x00Oj\xbd\a\x90\xb5\xffV\xc0da>\x9a\xbf\x99,#h\x9e\rs&4\xcb:\x1fAY\xfeF\x9e\x00\xe5P\"\xcbL\x84Z\u007f2\x14\xc3p\x97\xd2\xd7o\xbb?;\u007f\xa3\ucd45\x14\xf1\u0262\x8dj3\xc8\xce|\xb1\x84\xac\xe4\x8b\rk\x8d*;\xec\xa3\xfd\xec\xcc\xdf,\xa8|\v\xe1\xf7\f\x9f\xba|\x15\xd01N\xcd\u07da\x1f\xe3\x18\xbd\xaf,\x83\xf4k\xe7/k\xe9o\xd4\xc2\xe6\xc3\fkD\xc7!\x10]\x10~e\x0f\ub1b5\x89\xc9\xef1<\xca\xf4\x1e\xc3\xe3\f#\xec-\xedG\r\xac0\xb8\xc0\xa2\xa2_9\x83\xf7\xbb\xc9O:\xd1d$4\x80\x8as\x065\xb3U:m\\\x16\xec\x1d\x83\xb9\x87\xefd~\xd7eb\x18\x95z\x12\xf6\x14<\xaa\xc0:\x15jO`\xeay/\xe0!P\xe6\\/\xf5\x8eR\x1c\xf5\xb9}\xf9\xd4\xdb\xfa=\x88\"\x87_\x80~\xa3>h\x1f\xea'\xea\xe4\x0f\xc6\xc34\xf3\"E\xa8\xf0^\xf7\xbe\xe6\u02ea\xcaE-kIf\x9b\xf6:9\x1a\xc5!\xd0\x01s\xb0\x13\xb7\xee\xf2\u03a7q\xa5\xeaZ\xf9\xba\x1a\xb4\xfa\x1f\xce\u010b\xb3\xf4\xed+\x8c\xac\x94l\xf8\x02vA\x18VG\x1f\xeb\xc8\t\xcf\x03~\xd7\a3-\xb0\x1b<\x9bI\xe4\xa3S\t\x87\u01cd]\xbe\xec:\xe2\xe3\u01b1\xb9\x93\u007f:\xe0\u030d\xf5\xed\x02\xc1\xb0\xa8\vf\xb8EV-t_!\x85K{ORx\x85\x8f*\xb7P.\r\xf4jy\x99W\u0437\tU\xb2\xa8\xdcS\t\xc5\xf7\xac:\xb0e\xe7:J\vb\xc6\xd7^|\x89\x84\x82f\x01\\l-\x9eE\xd3\x17|\x97\x91g\xbf\xaag\x17\xcfs\"\x144\xb7\xcc~\xfb,\xbayq\x17\x9b\xa2\xef\xc5)\xdav\x96\xf35Z\xaf\xe7\u8388B\xba)\xdf\xc6\xd2\xce\xd5v#GA\x16\xdaa\xc2\x11\x13xXz$x\x1ekH\x99\xc1\x04\xddYg\x8eY\u0460\xe4\xe7T\xc3\xf9\u0649\f\u063c\xe7W\xfe\x89\xe8>3\x9f\"se\xa9\xaf\x88p\xb8}\xff\x12\x1a_\xbd\xd1\x03i*\xf9F5\x94\x88\u007f}\x15C\a%#\xba\xf7t\xe3\x01\xd3\xea\xd8C\xec#\x02\x16\x88\xa7v\x8c\u007f3\xb3\xcc\xf4\xd0\xcd|s~4CU3\xe9\xa9m6\u0772\xf6\x1e\xb7\xff\x97\u034a\xb1C\u0383\xfa\x1c?g\f\xf1\\\x9b3\xa0\a\xdb\x00\xc1p\xb2][\xb0\x93\xfc\xa7\x9b\xa2\x85\xc5\xdbN\u030d\xf71\xc8J\x90\xef\xf0^\x1a4\xa5\x13`\xe0\x1ch:\x03&\xc9\u05a8c\xe8\f\xc9\x03$O\x90<WR\xab\x12$0\u007f\v\xb2{\x12h\xdc2H\x1aZ\u83e6\xd5gP\xf2:rz\u065e\xea#5\xa5H7\xb9\b\xfe\x86WB:\xd0b\xcdS\xd6\xd7o\xdcQY\xca\x10\xbe\xf1\x9a+\xacj\x1b \b\t\x04\xbaV\x1a\xa1\x87\x90)\u0247\\\xb5\xda\xe5j=azU\u007f\xf4\xd2\x0e\xff\"\x8cJ_\xfe\x06i2\x179\xac0\"\x81\xfc>\xbd\xc2+\u03db\x11-j\f\xbb\\\xa2K^\xdeeOT\xa0d\xb4\xeb\u0359\xb7\xe8\u0219\u007f^82\xb7#B5\xce}a\xef\xcb\xf8|j{\x12\v^\xcd\xed\x8a\xd1\xca\xfd>\xe0\x12\uf9e0\xe4\f\xad\u00c5H1\xf8\xa3\xf9fF\xc0\f\x04\u007fG\xf0^\x83Y\x86\xf0\x8d\x86S\x86\xcb\xe9\x13\u03b3\x98\xf0\xf0\x8a\xe3\xab#\xde|u\x1a\x976\xb9\xb3\xc6\xf8\xa92\xbe)\xcf6\xee6JF\xf01\x0e\x80\xd8\x00\x19y\xf2z\x1a\x12X^\xa0\xf6\u076e%\x15a\r\x84\x9d\x02v\n\xd8\x11a\x92\x1fG\x13)\xc1g\x87\v\x17\x9c}uU\b2\x06\xf4\xd4\xe1\xa4\xde=%\x94\xb7%9 \x8cH1\xd79\xad>\u054f\xa6\x107\x90\x9aQ\x03.\xe3u\x1c\xef\nc\xefz\xfbX\x06T?\xe8\xa8\x10V\x98\u0262\xc2\x1a\xb82W\"9\xa7\xad\xffdN<3\xa9\xc5\xe2\x848\xffi\x90h\x108\u04d0&\xf8\xcc\xcc3\xd3\xd5\xc88Dx\xb7^e\xd7<8-2\n%x\xf0|\xec4\x99\x8cf6\u056f`pi\xd1U\b\x02\xe5)\xe2\x03f\ub04f\xb66\xfd\u0300\x10\x8c\xf5\xe4\x1cJvj\xd2\xff\u0511N\xd8\xda)\xab\u0374\xe9\xf8\xc1S\b\x1d\xc9G\xcb\x04\xb7[\x9a\x01\xe0\xc2{\u0361He\xf1\xacUM\xf9\x03\xaa\x8a\xbfd=\xdbZx\xb5\xa9\xfe\xb4\x88\xaa2\xf6\u063c\xf2<\x19Q\xcc|\b'\xd6+\xdf9H\xbf\xbf\xf2\x97V>h\x99\xee\u007f[\xfc\xa98&\xe6\xc1@\x9ee\x98\r\xfd\x96\x8c\xd1<8\x9ad\xa5r\x93\x14\x92~,\x0fE;\xdf\x1c\x89\x9aF\xe2\x96l\xe1\x8fi\xf0\x9a`\xd2B\xdb!\xb4\x94\x05\xc3zck\xcf\xe6\"\xa5\x1ar\x8fW\xb0\xa6n\xd5u\xc6%\xd0\xe9\xae\xc2\xd5D\x9aVM+[A\x1d\xd4:\xcf\xf2z\x97U\xe4XV\x91cT\x1aEs\x98y=t\xa8\xe1;4C\x80z%\xbb\xe6\xbf\x19{s\xde=\xce\xffEd'\xf25gK\xa3\xd8p\x9e\u258f\x86\b\xc5-\xc6\xccp\x8d\xb76\xb03\xe7\xfb\x91\xcf\xf2\x02\xe7\u039f\xccqB0,:\x15\xc6&E\xecxrc\u01ccM\x1c\x19'\xecUF~\xd0V\xae:!\x15\x89\xb8\xbcJ<K\xbd\xf1\xf4=[\xff'\xa9!\xd3\xd8\xd2lBM\xfd\xc6y\x16\x93 \xff0\xffG\xbcN\xfe\xdf\xe6\x98*\xe7v\xc5\x11\xbe\xfe;\\\x9e.\x91\x8bE\xe1\\\x1a\x836\xd38\xa6\xbd\x02\xad\"B\x95\xf3\xf0D\xd2Ph2\v\x92\x12y\u07c8|\x14\x97\x98A\xd9\xc2u\xb5\xc7\xd7\xed\xebJ\x8f\x17\xe8\xf1\xf5e\xf0r\u0537x \x152\xf6\xdb}d,&\xe0\x0eY\xfa\xf4\x80$\x9d\x8df\xb1Z\xf8\xa9\xbc 676\xed\xa4\xa8\nyZ;\u678fK\x96h\xf6.\u0536l/\x83\x84\xe4\xca\u0791\xb3\x1b\u0679\x1ch\xb7\x88\x04G&W\x9d\xed\xdf\xd4\xfb\xde\xf7\u0465\x85\x13@\xcb\u063d\xbe`\x18a\xd1\x15\xbe~\x8fs\xf7\x9e\xae%&\x9a4-\xd0{\xb2\xc6B\x86'\xc5\xf60c\xcc?H\xe4\x89C\xb5\xad\xa5\xb6^\xf9\xeb\x17\x9f\xce\x0f\xb6\xc4c^\xf9\xff\xab\x1aY\xe3\xdf\xd3\u007f}\x96\xb1\x9f\xa4\x83\x0f\x93,}?\x18\xccRA\xc0\xd4\xdaW\x19\xb3\xb7\xa2J\x19\xca\x0f\x8f'$\x0eg\xf2\xbf\xf3\xa2\xad4k~:\xdb2\xbf\u00bf\xbak\xa5\xa0/X\xe6\xfa\xbf\x03|\xf2\x1f\x04\x1a\xc7\xe1\x10i\xe0\x0f\xd3\x1e\x13I\xc5\xdf\x03b3\xfb6\r\xef\xca\x00U\xd54\u022a\x8e\bP1FL\xe8\x9e\xd0,\u0528,+\xe7\xe0\u007f\xec\x9av\x1a\xb4*7\x98\xf8e\xc59\xed\r\x9f\xa0\x8b\x87\xda{K\xaf\xd9\x00\xbc'\xe05\x01\xdf\xf2\xab\u0095\xddy\xf6\xa4\x8b\u06b6/\xdd\xc6\xc6f\\D\x98\x140oDd\xea\x91\xdf\\\x95.h\xaf\xea.h\xbbve\u0398\xef\x81?\xe76\xe4h\x9f\aO\xb1\xe7\xeds\xbc\xec\xd4u?\xc4n:\xbf4\xaf,*c@j\t\xfc\xd7a'\xea\x01\x03\x8f\xd3hd\xba\xe6U,M\xc7\xe6L1\xadk\x01y\xd0\xf0u$\xd5\xcc\xcdT\x1c\xb6\xb6\x14\x87\xed\xe1f\xe9\xedX\x9d\xf3\x97\xdexA\xbc\xcd\x03\xc4t\xea+\xfb/<\xf2\xee\xc1I\x9d\x16\f7\xc1\xba#\xd6/H\xdft\u013aG\x0fw\u007f\xec\x84\xf5@\x9c\xb4^\x84\xae\xb7\x97\xd1\x17\u04e5T\x86\x81\x15\x02O:c\xfdP8c\x1d\u055c\xb1N\x9fv\xc6\xfa\xe1\x913\xd6=d\xfc\xc0c[0\u04a7 \xeb\xfdGl\x8b\xb3\xb3(w9f\x80\x05\x01M\xf5\x04\nh\ua066O:m\rhzo)i.\x9d\xa9\x9b\xe5\xff\xdc\x172\xbd\xa9\x86\xd7}#`\xf0\xbc\xc0\xe0y\x05\x83\x89\xb43\xf6\x8d\x18<,\"LbGzDH\xb9-\xd1#\xd7\"\x9a\x11{G\x9dqk\b\x1a\x8d\xf5\xbf\xa3\x01\x81z\xff-S\xc2\xc2\x00\x9d\xcf\xda\xf4\x86zf\xba\xe5\x868\xb7!#\xd1\x1bl\xe40G\xefQ@\uf662w\u007f\x03EK\xfc9\u051c\x1f\xa4K\x87\xa1#L_\x91g&\xfeB\xd6K\xfc\xed\xc2I\xb0f\u07b3I\xe1\f\a>p\xbe\xd8\xde\xf7^\xc5\x1d:e\xa1\r\xbbg(\fm\u06bd5\u01fc\xa6Z\xad\xc3\x01\xbc\xc2\x00Z\f<\x98\x0f\xb1\x11\b\x03]\xfb\x01c|\xa5\x97\xa5\xda\xfe\t\xed\xafd\xff\x94\x96\x88\x15\u013f\xb0\xcbG\x88\u007fE\xe4NJ\xc4\xf7&\x11\xc4O\x14\xf1\xdf\u0200\x0f\x8a\x01\xdfG\x17h\xe6Ml\x188C ~RE\xfce\x81\xf8=#K\x1f\xb0\xedi\xc4_V\x10_\xf9\xa6+\x9a\x91\u420fD7{\x12\xeb\xf5\xa9\u019bX,f\xcd\xf7\xe7\xffnV4\xa5\xb0\xba\x1b\x90$7\x8c\xa6\x13\x06\x03\xf9\xe5\xad\xd7*\xc6r\x84]\x12\x1c\xe6U\x88\xf9\x86\x87q\xf1\xa33\n\xbb\xa4\xa7\x9e\x03\xaf9\xa6\u073d\xfe\x99\xbd\x8d\u0138\xf1\x1a\x19\xef\xe3&c\xdb!F||6\x06}\xbd\x8bfU\xe22S\xa3q\x9d\xe3\x85\x19\x19|\x0e1\u0573\x02abA\xc7)\xad\x15\x9b\x0fq\xf3\x10\x84\x80X\xecq\xf1i\xca\xf7U\xeb\x15\x90j\xef\xffc\x97~\xb1\x9bk\xd0\xfe\x82U\xd8\xd3U\xa8\xd4\u04f3\xdd\xe8.Z\xb0\x97\xa1\x93\u0414T\xff\x03\xe4^\xd8\xee\aV\x8b\x03a\xae\x8b]\u007f]\xeezs\xc4\u07bf\xe9$\xad\t\u0715\xd3>v\x82\v_\xfb\xa8a\u07c4\u007f\xeb8\xf8~T\xb1\xf89\u046b\u85fa\xba\xe3\xad\xe5s\x86P\x9392M\xa0\xe2\xb1\x00\x8f\x14<i%D\xcf\u03e8\xee\xede\xfb\xc4~nDG\u0377\xf1\x8b\xe8\x18\xbf\u03e2\xc1\xf7\xe3\xcb\xe6g=_\xdec\xe5^\xb2\x97\xaa\x93>j\xcd\u0443\xb0p?\xb0d'a\u052f\xb1\x14\xef\x9b\xd8~\xfb\b\xdcD?\f\x1f^\x9d\xca\xfah\xf8\x93\xddo\x9e\xeay(\xe3\x80y\x15\xf6\xc7ks\x8a]\xfb)6\x9c\xde}{jV\xd1\x01\x81\xb6G0\x8b\xc4\xc5\xfe\u0472\x8a$\\\x8cG\x1b\xf5\x02\xcd\xec\u0256\xb8v\xf4,\xf0\xbf\xfe\x1f\xb8\x93\x82\x06w\x89\x00\x00") + +func staticJsUplotIifeMinJsGzBytes() ([]byte, error) { + return _staticJsUplotIifeMinJsGz, nil +} + +func staticJsUplotIifeMinJsGz() (*asset, error) { + bytes, err := staticJsUplotIifeMinJsGzBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "static/js/uPlot.iife.min.js.gz", size: 15215, mode: os.FileMode(420), modTime: time.Unix(1612357306, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -834,7 +972,7 @@ func staticSpeakerSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/speaker.svg", size: 524, mode: os.FileMode(420), modTime: time.Unix(1612341006, 0)} + info := bindataFileInfo{name: "static/speaker.svg", size: 524, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -851,7 +989,7 @@ func staticSpeakerSvgBr() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/speaker.svg.br", size: 278, mode: os.FileMode(420), modTime: time.Unix(1612345238, 0)} + info := bindataFileInfo{name: "static/speaker.svg.br", size: 278, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -868,7 +1006,7 @@ func staticSpeakerSvgGz() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/speaker.svg.gz", size: 329, mode: os.FileMode(420), modTime: time.Unix(1612344943, 0)} + info := bindataFileInfo{name: "static/speaker.svg.gz", size: 329, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -939,6 +1077,10 @@ var _templatesIndexHtml = []byte(`<!DOCTYPE html> </li> {{end}} </ul> + + <div class="chart" + chart-query="all_listeners" + chart-title="Listeners"></div> </div> </div> @@ -976,7 +1118,7 @@ func templatesIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/index.html", size: 2948, mode: os.FileMode(420), modTime: time.Unix(1612345109, 0)} + info := bindataFileInfo{name: "templates/index.html", size: 3067, mode: os.FileMode(420), modTime: time.Unix(1612367191, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1022,7 +1164,7 @@ func templatesPlayerHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/player.html", size: 955, mode: os.FileMode(420), modTime: time.Unix(1612344550, 0)} + info := bindataFileInfo{name: "templates/player.html", size: 955, mode: os.FileMode(420), modTime: time.Unix(1612357023, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1091,6 +1233,9 @@ var _bindata = map[string]func() (*asset, error){ "static/css/style.css": staticCssStyleCss, "static/css/style.css.br": staticCssStyleCssBr, "static/css/style.css.gz": staticCssStyleCssGz, + "static/css/uPlot.min.css": staticCssUplotMinCss, + "static/css/uPlot.min.css.br": staticCssUplotMinCssBr, + "static/css/uPlot.min.css.gz": staticCssUplotMinCssGz, "static/favicon.ico": staticFaviconIco, "static/js/autoradio.js": staticJsAutoradioJs, "static/js/autoradio.js.br": staticJsAutoradioJsBr, @@ -1104,6 +1249,9 @@ var _bindata = map[string]func() (*asset, error){ "static/js/player.js": staticJsPlayerJs, "static/js/player.js.br": staticJsPlayerJsBr, "static/js/player.js.gz": staticJsPlayerJsGz, + "static/js/uPlot.iife.min.js": staticJsUplotIifeMinJs, + "static/js/uPlot.iife.min.js.br": staticJsUplotIifeMinJsBr, + "static/js/uPlot.iife.min.js.gz": staticJsUplotIifeMinJsGz, "static/radio52.png": staticRadio52Png, "static/speaker.svg": staticSpeakerSvg, "static/speaker.svg.br": staticSpeakerSvgBr, @@ -1166,6 +1314,9 @@ var _bintree = &bintree{nil, map[string]*bintree{ "style.css": &bintree{staticCssStyleCss, map[string]*bintree{}}, "style.css.br": &bintree{staticCssStyleCssBr, map[string]*bintree{}}, "style.css.gz": &bintree{staticCssStyleCssGz, map[string]*bintree{}}, + "uPlot.min.css": &bintree{staticCssUplotMinCss, map[string]*bintree{}}, + "uPlot.min.css.br": &bintree{staticCssUplotMinCssBr, map[string]*bintree{}}, + "uPlot.min.css.gz": &bintree{staticCssUplotMinCssGz, map[string]*bintree{}}, }}, "favicon.ico": &bintree{staticFaviconIco, map[string]*bintree{}}, "js": &bintree{nil, map[string]*bintree{ @@ -1181,6 +1332,9 @@ var _bintree = &bintree{nil, map[string]*bintree{ "player.js": &bintree{staticJsPlayerJs, map[string]*bintree{}}, "player.js.br": &bintree{staticJsPlayerJsBr, map[string]*bintree{}}, "player.js.gz": &bintree{staticJsPlayerJsGz, map[string]*bintree{}}, + "uPlot.iife.min.js": &bintree{staticJsUplotIifeMinJs, map[string]*bintree{}}, + "uPlot.iife.min.js.br": &bintree{staticJsUplotIifeMinJsBr, map[string]*bintree{}}, + "uPlot.iife.min.js.gz": &bintree{staticJsUplotIifeMinJsGz, map[string]*bintree{}}, }}, "radio52.png": &bintree{staticRadio52Png, map[string]*bintree{}}, "speaker.svg": &bintree{staticSpeakerSvg, map[string]*bintree{}}, diff --git a/node/http.go b/node/http.go index 53d36972b94ba0e609fed1c0b66b4f3230af88bb..31d6a03f3871f9928503d6a0189e621fea7c6685 100644 --- a/node/http.go +++ b/node/http.go @@ -67,6 +67,16 @@ func newHTTPHandler(n *Node, icecastPort int, domain string) http.Handler { mux.Handle("/debug/", h) } + // Metrics API (Prometheus proxy). + if *prometheusURL != "" { + mp, err := newMetricsProxy() + if err != nil { + log.Printf("warning: metrics proxy disabled due to error: %v", err) + } else { + mux.Handle("/timeseries_query", gziphandler.GzipHandler(mp)) + } + } + // A very narrow selection of Icecast API methods is served // below /admin/ and forwarded to the Icecast master via a // standard httputil.ReverseProxy. diff --git a/node/metrics.go b/node/metrics.go new file mode 100644 index 0000000000000000000000000000000000000000..e5254b874419c25a9113f9bfe79dfb3621edbd05 --- /dev/null +++ b/node/metrics.go @@ -0,0 +1,138 @@ +package node + +import ( + "context" + "encoding/json" + "errors" + "flag" + "log" + "net/http" + "regexp" + "strings" + "time" + + "github.com/prometheus/client_golang/api" + v1 "github.com/prometheus/client_golang/api/prometheus/v1" + "github.com/prometheus/common/model" +) + +var ( + prometheusURL = flag.String("prometheus-url", "", "Prometheus server API URL") + prometheusTimeout = flag.Duration("prometheus-timeout", 30*time.Second, "Timeout for Prometheus requests") + + knownQueries = map[string]string{ + "stream_listeners": "sum(stream_listeners{stream=\"$arg\"})", + "all_listeners": "global:stream_listeners:sum", + } +) + +// The metricsProxy passes through some predefined queries to a +// Prometheus instance (that is monitoring autoradio), and returns +// timeseries data in a Javascript-friendly format. We don't want to +// expose Prometheus directly. +type metricsProxy struct { + client api.Client +} + +func newMetricsProxy() (*metricsProxy, error) { + client, err := api.NewClient(api.Config{ + Address: *prometheusURL, + }) + if err != nil { + return nil, err + } + return &metricsProxy{ + client: client, + }, nil +} + +func (p *metricsProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { + query, rng, err := p.queryFromRequest(r) + if err != nil { + log.Printf("bad metrics request: %v", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + v1api := v1.NewAPI(p.client) + ctx, cancel := context.WithTimeout(r.Context(), *prometheusTimeout) + defer cancel() + + result, _, err := v1api.QueryRange(ctx, query, rng) + if err != nil { + log.Printf("error querying Prometheus: query='%s': %v", query, err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + data, labels, err := tablify(result) + if err != nil { + log.Printf("error parsing Prometheus data: query='%s': %v", query, err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]interface{}{ + "data": data, + "labels": labels, + }) +} + +// Regexp used to validate query arguments. +var argRx = regexp.MustCompile(`^[-_.a-zA-Z0-9]*$`) + +func (p *metricsProxy) queryFromRequest(r *http.Request) (string, v1.Range, error) { + name := r.FormValue("query") + d, err := time.ParseDuration(r.FormValue("t")) + if err != nil { + d = time.Hour + } + + arg := r.FormValue("arg") + if !argRx.MatchString(arg) { + return "", v1.Range{}, errors.New("bad argument") + } + q, ok := knownQueries[name] + if !ok { + return "", v1.Range{}, errors.New("unknown query") + } + q = strings.Replace(q, "$arg", arg, -1) + + rng := v1.Range{ + Start: time.Now().Add(-d), + End: time.Now(), + Step: time.Minute, + } + + return q, rng, nil +} + +// tablify converts a QueryRange result into an array of float64 +// arrays that can be directly fed to uPlot via javascript. +func tablify(result model.Value) ([][]float64, []string, error) { + m := result.(model.Matrix) + + if len(m) == 0 { + return nil, nil, errors.New("no values") + } + + table := make([][]float64, len(m)+1) + // Avoid n^2 allocations. + for i := 0; i < len(table); i++ { + table[i] = make([]float64, 0, len(m[0].Values)) + } + var labels []string + for idx, row := range m { + labels = append(labels, row.Metric.String()) + for _, val := range row.Values { + // Row 0 is the timestamp. + if idx == 0 { + table[0] = append(table[0], float64(val.Timestamp)) + } + table[idx+1] = append(table[idx+1], float64(val.Value)) + } + } + + return table, labels, nil +} diff --git a/node/static/css/uPlot.min.css b/node/static/css/uPlot.min.css new file mode 100644 index 0000000000000000000000000000000000000000..e79314bdc79c612d8ecaf00056256b14a0eee04f --- /dev/null +++ b/node/static/css/uPlot.min.css @@ -0,0 +1 @@ +.uplot, .uplot *, .uplot *::before, .uplot *::after {box-sizing: border-box;}.uplot {font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";line-height: 1.5;width: min-content;}.u-title {text-align: center;font-size: 18px;font-weight: bold;}.u-wrap {position: relative;user-select: none;}.u-over, .u-under {position: absolute;}.u-under {overflow: hidden;}.uplot canvas {display: block;position: relative;width: 100%;height: 100%;}.u-legend {font-size: 14px;margin: auto;text-align: center;}.u-inline {display: block;}.u-inline * {display: inline-block;}.u-inline tr {margin-right: 16px;}.u-legend th {font-weight: 600;}.u-legend th > * {vertical-align: middle;display: inline-block;}.u-legend .u-marker {width: 1em;height: 1em;margin-right: 4px;background-clip: content-box !important;}.u-inline.u-live th::after {content: ":";vertical-align: middle;}.u-inline:not(.u-live) .u-value {display: none;}.u-series > * {padding: 4px;}.u-series th {cursor: pointer;}.u-legend .u-off > * {opacity: 0.3;}.u-select {background: rgba(0,0,0,0.07);position: absolute;pointer-events: none;}.u-cursor-x, .u-cursor-y {position: absolute;left: 0;top: 0;pointer-events: none;will-change: transform;z-index: 100;}.u-hz .u-cursor-x, .u-vt .u-cursor-y {height: 100%;border-right: 1px dashed #607D8B;}.u-hz .u-cursor-y, .u-vt .u-cursor-x {width: 100%;border-bottom: 1px dashed #607D8B;}.u-cursor-pt {position: absolute;top: 0;left: 0;border-radius: 50%;pointer-events: none;will-change: transform;z-index: 100;/*this has to be !important since we set inline "background" shorthand */background-clip: content-box !important;}.u-select.u-off, .u-cursor-x.u-off, .u-cursor-y.u-off, .u-cursor-pt.u-off {display: none;} \ No newline at end of file diff --git a/node/static/css/uPlot.min.css.br b/node/static/css/uPlot.min.css.br new file mode 100644 index 0000000000000000000000000000000000000000..07e9d19075ef0c839fb5b6f185826a8046105a9f Binary files /dev/null and b/node/static/css/uPlot.min.css.br differ diff --git a/node/static/css/uPlot.min.css.gz b/node/static/css/uPlot.min.css.gz new file mode 100644 index 0000000000000000000000000000000000000000..e3b212c839dcbd592a61fddde808a5434fe0955f Binary files /dev/null and b/node/static/css/uPlot.min.css.gz differ diff --git a/node/static/js/autoradio.js b/node/static/js/autoradio.js index fe6e6983009daf21f0f49a665594769eb0db8249..7b0b19efea68d448dcf1be837c0f16386cdf83e8 100644 --- a/node/static/js/autoradio.js +++ b/node/static/js/autoradio.js @@ -1,3 +1,31 @@ $(function() { - $('[data-toggle="tooltip"]').tooltip(); + $('[data-toggle="tooltip"]').tooltip(); + + $('.chart').each(function(idx, el) { + let queryName = el.attr('chart-query'); + let queryArg = el.attr('chart-arg'); + let title = el.attr('chart-title'); + $.ajax({ + url: '/timeseries_query?query=' + encodeURIComponent(queryName) + '&arg=' + encodeURIComponent(queryArg), + dataType: 'json', + success: function(data) { + // Build the uPlot metadata. + let opts = { + title: title, + width: 500, + height: 200, + series: [ + {}, + ], + }; + for (var i = 0; i < data.labels.length; i++) { + opts.series.push({ + show: true, + label: data.labels[i], + }); + } + let uplot = new uPlot(opts, data.data, el); + }, + }); + }); }); diff --git a/node/static/js/autoradio.js.br b/node/static/js/autoradio.js.br index 88d146d6be4fa8776501b3ba2effab1d555c06d1..021f74f55d5c8a5467dde8e2ce592a68150a92ad 100644 Binary files a/node/static/js/autoradio.js.br and b/node/static/js/autoradio.js.br differ diff --git a/node/static/js/autoradio.js.gz b/node/static/js/autoradio.js.gz index 9a4447091eec5600ec52d9c45b5f261ed753f425..51877d38577f93c26371145e5422e3cf64355da9 100644 Binary files a/node/static/js/autoradio.js.gz and b/node/static/js/autoradio.js.gz differ diff --git a/node/static/js/uPlot.iife.min.js b/node/static/js/uPlot.iife.min.js new file mode 100644 index 0000000000000000000000000000000000000000..f4051eb0ca3c34a06d3dd8989a8340bbe9a3076e --- /dev/null +++ b/node/static/js/uPlot.iife.min.js @@ -0,0 +1,2 @@ +/*! https://github.com/leeoniya/uPlot (v1.6.4) */ +var uPlot=function(){"use strict";function n(n,e,r,t){var l;r=r||0;for(var i=2147483647>=(t=t||e.length-1);t-r>1;)n>e[l=i?r+t>>1:h((r+t)/2)]?r=l:t=l;return n-e[r]>e[t]-n?t:r}function e(n,e,r,t){for(var l=1==t?e:r;l>=e&&r>=l;l+=t)if(null!=n[l])return l;return-1}var r=[0,0];function t(n,e,t,l){return r[0]=0>t?A(n,-t):n,r[1]=0>l?A(e,-l):e,r}function l(n,e,r,l){var i,a,o,s=10==r?b:k;return n==e&&(n/=r,e*=r),l?(i=h(s(n)),a=m(s(e)),n=(o=t(w(r,i),w(r,a),i,a))[0],e=o[1]):(i=h(s(n)),a=h(s(e)),n=P(n,(o=t(w(r,i),w(r,a),i,a))[0]),e=E(e,o[1])),[n,e]}var i={pad:0,soft:null,mode:0},a={min:i,max:i};function o(n,e,r,t){return I(r)?u(n,e,r):(i.pad=r,i.soft=t?0:null,i.mode=t?3:0,u(n,e,a))}function s(n,e){return null==n?e:n}function u(n,e,r){var t=r.min,l=r.max,i=s(t.pad,0),a=s(l.pad,0),o=s(t.hard,-y),u=s(l.hard,y),f=s(t.soft,y),c=s(l.soft,-y),d=s(t.mode,0),m=s(l.mode,0),x=e-n,k=x||v(e)||1e3,_=b(k),M=w(10,h(_)),S=A(P(n-k*(0==x?0==n?.1:1:i),M/10),6),z=f>n||1!=d&&(3!=d||S>f)&&(2!=d||f>S)?y:f,T=g(o,z>S&&n>=z?z:p(z,S)),D=A(E(e+k*(0==x?0==e?.1:1:a),M/10),6),W=e>c||1!=m&&(3!=m||c>D)&&(2!=m||D>c)?-y:c,Y=p(u,D>W&&W>=e?W:g(W,D));return T==Y&&0==T&&(Y=100),[T,Y]}var f=new Intl.NumberFormat(navigator.language).format,c=Math,v=c.abs,h=c.floor,d=c.round,m=c.ceil,p=c.min,g=c.max,w=c.pow,x=c.sqrt,b=c.log10,k=c.log2,_=c.PI,y=1/0;function M(n,e){return d(n/e)*e}function S(n,e,r){return p(g(n,e),r)}function z(n){return"function"==typeof n?n:()=>n}var T=(n,e)=>e,D=()=>null;function E(n,e){return m(n/e)*e}function P(n,e){return h(n/e)*e}function A(n,e){return d(n*(e=Math.pow(10,e)))/e}var W=new Map;function Y(n){return((""+n).split(".")[1]||"").length}function C(n,e,r,t){for(var l=[],i=t.map(Y),a=e;r>a;a++)for(var o=v(a),s=A(w(n,a),o),u=0;t.length>u;u++){var f=t[u]*s,c=(0>f||0>a?o:0)+(i[u]>a?i[u]:0),h=A(f,c);l.push(h),W.set(h,c)}return l}var H={},F=Array.isArray;function N(n){return"string"==typeof n}function I(n){var e=!1;if(null!=n){var r=n.constructor;e=null==r||r==Object}return e}function L(n){var e;if(F(n))e=n.map(L);else if(I(n))for(var r in e={},n)e[r]=L(n[r]);else e=n;return e}function V(n){for(var e=arguments,r=1;e.length>r;r++){var t=e[r];for(var l in t)I(n[l])?V(n[l],L(t[l])):n[l]=L(t[l])}return n}function O(n,e,r){for(var t=0,l=void 0,i=-1;e.length>t;t++){var a=e[t];if(a>i){for(l=a-1;l>=0&&null==n[l];)n[l--]=null;for(l=a+1;r>l&&null==n[l];)n[i=l++]=null}}}var j="undefined"==typeof queueMicrotask?n=>Promise.resolve().then(n):queueMicrotask,G="width",B="height",R="top",U="bottom",J="left",q="right",Z="#000",X="#0000",K="mousemove",Q="mousedown",$="mouseup",nn="mouseenter",en="mouseleave",rn="dblclick",tn="resize",ln="scroll",an="u-off",on="u-label",sn=document,un=window,fn=devicePixelRatio;function cn(n,e){null!=e&&n.classList.add(e)}function vn(n,e){n.classList.remove(e)}function hn(n,e,r){n.style[e]=r+"px"}function dn(n,e,r,t){var l=sn.createElement(n);return null!=e&&cn(l,e),null!=r&&r.insertBefore(l,t),l}function mn(n,e){return dn("div",n,e)}function pn(n,e,r,t,l){n.style.transform="translate("+e+"px,"+r+"px)",0>e||0>r||e>t||r>l?cn(n,an):vn(n,an)}var gn={passive:!0};function wn(n,e,r){e.addEventListener(n,r,gn)}function xn(n,e,r){e.removeEventListener(n,r,gn)}var bn=["January","February","March","April","May","June","July","August","September","October","November","December"],kn=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];function _n(n){return n.slice(0,3)}var yn=kn.map(_n),Mn=bn.map(_n),Sn={MMMM:bn,MMM:Mn,WWWW:kn,WWW:yn};function zn(n){return(10>n?"0":"")+n}var Tn={YYYY:n=>n.getFullYear(),YY:n=>(n.getFullYear()+"").slice(2),MMMM:(n,e)=>e.MMMM[n.getMonth()],MMM:(n,e)=>e.MMM[n.getMonth()],MM:n=>zn(n.getMonth()+1),M:n=>n.getMonth()+1,DD:n=>zn(n.getDate()),D:n=>n.getDate(),WWWW:(n,e)=>e.WWWW[n.getDay()],WWW:(n,e)=>e.WWW[n.getDay()],HH:n=>zn(n.getHours()),H:n=>n.getHours(),h:n=>{var e=n.getHours();return 0==e?12:e>12?e-12:e},AA:n=>12>n.getHours()?"AM":"PM",aa:n=>12>n.getHours()?"am":"pm",a:n=>12>n.getHours()?"a":"p",mm:n=>zn(n.getMinutes()),m:n=>n.getMinutes(),ss:n=>zn(n.getSeconds()),s:n=>n.getSeconds(),fff:n=>function(n){return(10>n?"00":100>n?"0":"")+n}(n.getMilliseconds())};function Dn(n,e){e=e||Sn;for(var r,t=[],l=/\{([a-z]+)\}|[^{]+/gi;r=l.exec(n);)t.push("{"==r[0][0]?Tn[r[1]]:r[0]);return n=>{for(var r="",l=0;t.length>l;l++)r+="string"==typeof t[l]?t[l]:t[l](n,e);return r}}var En=(new Intl.DateTimeFormat).resolvedOptions().timeZone,Pn=n=>n%1==0,An=[1,2,2.5,5],Wn=C(10,-16,0,An),Yn=C(10,0,16,An),Cn=Yn.filter(Pn),Hn=Wn.concat(Yn),Fn="{YYYY}",Nn="\n"+Fn,In="{M}/{D}",Ln="\n"+In,Vn=Ln+"/{YY}",On="{aa}",jn="{h}:{mm}"+On,Gn="\n"+jn,Bn=":{ss}",Rn=null;function Un(n){var e=1e3*n,r=60*e,t=60*r,l=24*t,i=30*l,a=365*l;return[(1==n?C(10,0,3,An).filter(Pn):C(10,-3,0,An)).concat([e,5*e,10*e,15*e,30*e,r,5*r,10*r,15*r,30*r,t,2*t,3*t,4*t,6*t,8*t,12*t,l,2*l,3*l,4*l,5*l,6*l,7*l,8*l,9*l,10*l,15*l,i,2*i,3*i,4*i,6*i,a,2*a,5*a,10*a,25*a,50*a,100*a]),[[a,Fn,Rn,Rn,Rn,Rn,Rn,Rn,1],[28*l,"{MMM}",Nn,Rn,Rn,Rn,Rn,Rn,1],[l,In,Nn,Rn,Rn,Rn,Rn,Rn,1],[t,"{h}"+On,Vn,Rn,Ln,Rn,Rn,Rn,1],[r,jn,Vn,Rn,Ln,Rn,Rn,Rn,1],[e,Bn,Vn+" "+jn,Rn,Ln+" "+jn,Rn,Gn,Rn,1],[n,Bn+".{fff}",Vn+" "+jn,Rn,Ln+" "+jn,Rn,Gn,Rn,1]],function(e){return(o,s,u,f,c,v)=>{var d=[],m=c>=a,p=c>=i&&a>c,g=e(u),w=g*n,x=te(g.getFullYear(),m?0:g.getMonth(),p||m?1:g.getDate()),b=x*n;if(p||m)for(var k=p?c/i:0,_=m?c/a:0,y=w==b?w:te(x.getFullYear()+_,x.getMonth()+k,1)*n,M=new Date(y/n),S=M.getFullYear(),z=M.getMonth(),T=0;f>=y;T++){var D=te(S+_*T,z+k*T,1);(y=(+D+(D-e(D*n)))*n)>f||d.push(y)}else{var P=l>c?c:l,W=b+(h(u)-h(w))+E(w-b,P);d.push(W);for(var Y=e(W),C=Y.getHours()+Y.getMinutes()/r+Y.getSeconds()/t,H=c/t,F=v/o.axes[s]._space;(W=A(W+c,1==n?0:3))<=f;)if(H>1){var N=h(A(C+H,6))%24,I=e(W).getHours()-N;I>1&&(I=-1),C=(C+H)%24,.7>A(((W-=I*t)-d[d.length-1])/c,3)*F||d.push(W)}else d.push(W)}return d}}]}var Jn=Un(1),qn=Jn[0],Zn=Jn[1],Xn=Jn[2],Kn=Un(.001),Qn=Kn[0],$n=Kn[1],ne=Kn[2];function ee(n,e){return n.map((n=>n.map(((r,t)=>0==t||8==t||null==r?r:e(1==t||0==n[8]?r:n[1]+r)))))}function re(n,e){return(r,t,l,i,a)=>{var o,s,u,f,c,v,h=e.find((n=>a>=n[0]))||e[e.length-1];return t.map((e=>{var r=n(e),t=r.getFullYear(),l=r.getMonth(),i=r.getDate(),a=r.getHours(),d=r.getMinutes(),m=r.getSeconds(),p=t!=o&&h[2]||l!=s&&h[3]||i!=u&&h[4]||a!=f&&h[5]||d!=c&&h[6]||m!=v&&h[7]||h[1];return o=t,s=l,u=i,f=a,c=d,v=m,p(r)}))}}function te(n,e,r){return new Date(n,e,r)}function le(n,e){return e(n)}function ie(n,e){return(r,t)=>e(n(t))}function ae(n,e){var r=n.series[e];return r.width?r.stroke(n,e):r.points.width?r.points.stroke(n,e):null}function oe(n,e){return n.series[e].fill(n,e)}C(2,-53,53,[1]);var se=[0,0];function ue(n,e,r){return n=>{0==n.button&&r(n)}}function fe(n,e,r){return r}var ce={show:!0,x:!0,y:!0,lock:!1,move:function(n,e,r){return se[0]=e,se[1]=r,se},points:{show:function(n,e){var r=n.cursor.points,t=mn(),l=r.stroke(n,e),i=r.fill(n,e);t.style.background=i||l;var a=r.size(n,e),o=r.width(n,e,a);o&&(t.style.border=o+"px solid "+l);var s=a/-2;return hn(t,G,a),hn(t,B,a),hn(t,"marginLeft",s),hn(t,"marginTop",s),t},size:function(n,e){return De(n.series[e].width,1)},width:0,stroke:function(n,e){return n.series[e].stroke(n,e)},fill:function(n,e){return n.series[e].stroke(n,e)}},bind:{mousedown:ue,mouseup:ue,click:ue,dblclick:ue,mousemove:fe,mouseleave:fe,mouseenter:fe},drag:{setScale:!0,x:!0,y:!1,dist:0,uni:null,_x:!1,_y:!1},focus:{prox:-1},left:-10,top:-10,idx:null,dataIdx:function(n,e,r){return r}},ve={show:!0,stroke:"rgba(0,0,0,0.07)",width:2,filter:T},he=V({},ve,{size:10}),de='12px system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',me="bold "+de,pe={show:!0,scale:"x",stroke:Z,space:50,gap:5,size:50,labelSize:30,labelFont:me,side:2,grid:ve,ticks:he,font:de,rotate:0},ge={show:!0,scale:"x",auto:!1,sorted:1,min:y,max:-y,idxs:[]};function we(n,e){return e.map((n=>null==n?"":f(n)))}function xe(n,e,r,t,l,i,a){for(var o=[],s=W.get(l)||0,u=r=a?r:A(E(r,l),s);t>=u;u=A(u+l,s))o.push(Object.is(u,-0)?0:u);return o}function be(n,e,r,t,l){var i=[],a=n.scales[n.axes[e].scale].log,o=h((10==a?b:k)(r));l=w(a,o),0>o&&(l=A(l,-o));var s=r;do{i.push(s),l*a>(s=A(s+l,W.get(l)))||(l=s)}while(t>=s);return i}var ke=/./,_e=/[12357]/,ye=/[125]/,Me=/1/;function Se(n,e,r){var t=n.axes[r],l=t.scale;if(2==n.scales[l].log)return e;var i=n.valToPos,a=t._space,o=i(10,l),s=i(9,l)-o<a?i(7,l)-o<a?i(5,l)-o<a?Me:ye:_e:ke;return e.map((n=>s.test(n)?n:null))}function ze(n,e){return null==e?"":f(e)}var Te={show:!0,scale:"y",stroke:Z,space:30,gap:5,size:50,labelSize:30,labelFont:me,side:3,grid:ve,ticks:he,font:de,rotate:0};function De(n,e){return A((3+2*(n||1))*e,3)}function Ee(n,e){var r=n.scales[n.series[e].scale],t=n.bands&&n.bands.some((n=>n.series[0]==e));return 3==r.distr||t?r.min:0}var Pe={scale:"y",auto:!0,sorted:0,show:!0,band:!1,spanGaps:!1,alpha:1,points:{show:function(n,e){var r=n.series[0].idxs;return(0==n.scales[n.series[0].scale].ori?n.bbox.width:n.bbox.height)/(n.series[e].points.space*fn)>=r[1]-r[0]}},values:null,min:y,max:-y,idxs:[],path:null,clip:null};function Ae(n,e,r){return r/10}var We={time:!0,auto:!0,distr:1,log:10,min:null,max:null,dir:1,ori:0},Ye=V({},We,{time:!1,ori:1}),Ce={};function He(){var n=[];return{sub:function(e){n.push(e)},unsub:function(e){n=n.filter((n=>n!=e))},pub:function(e,r,t,l,i,a,o){n.length>1&&n.forEach((n=>{n!=r&&n.pub(e,r,t,l,i,a,o)}))}}}function Fe(n,e,r){var t=n.series[e],l=n.scales,i=n.bbox,a=n._data[0],o=n._data[e],s=l[n.series[0].scale],u=l[t.scale],f=i.left,c=i.top,v=i.width,h=i.height,d=n.valToPosH,m=n.valToPosV;return 0==s.ori?r(t,a,o,s,u,d,m,f,c,v,h,Ve,je,Be,Ue,qe):r(t,a,o,s,u,m,d,c,f,h,v,Oe,Ge,Re,Je,Ze)}function Ne(n,e,r,t,l){return Fe(n,e,((n,e,i,a,o,s,u,f,c,v,h)=>{var d,m,p=0==a.ori?je:Ge;1==a.dir*(0==a.ori?1:-1)?(d=r,m=t):(d=t,m=r);var g=M(s(e[d],a,v,f),.5),w=M(u(i[d],o,h,c),.5),x=M(s(e[m],a,v,f),.5),b=M(u(o.max,o,h,c),.5),k=new Path2D(l);return p(k,x,b),p(k,g,b),p(k,g,w),k}))}function Ie(n,e,r,t,l,i){var a=null;if(n.length>0){a=new Path2D;for(var o=0==e?Be:Re,s=r,u=0;n.length>u;u++){var f=n[u];o(a,s,t,f[0]-s,t+i),s=f[1]}o(a,s,t,r+l-s,t+i)}return a}function Le(n,e,r){if(r>e){var t=n[n.length-1];t&&t[0]==e?t[1]=r:n.push([e,r])}}function Ve(n,e,r){n.moveTo(e,r)}function Oe(n,e,r){n.moveTo(r,e)}function je(n,e,r){n.lineTo(e,r)}function Ge(n,e,r){n.lineTo(r,e)}function Be(n,e,r,t,l){n.rect(e,r,t,l)}function Re(n,e,r,t,l){n.rect(r,e,l,t)}function Ue(n,e,r,t,l,i){n.arc(e,r,t,l,i)}function Je(n,e,r,t,l,i){n.arc(r,e,t,l,i)}function qe(n,e,r,t,l,i,a){n.bezierCurveTo(e,r,t,l,i,a)}function Ze(n,e,r,t,l,i,a){n.bezierCurveTo(r,e,l,t,a,i)}function Xe(n){return(e,r,t,l,i)=>{t!=l&&(n(e,r,t),n(e,r,l),n(e,r,i))}}var Ke=Xe(je),Qe=Xe(Ge);function $e(){return(n,r,t,l)=>Fe(n,r,((i,a,o,s,u,f,c,v,h,m,w)=>{var x,b;0==s.ori?(x=je,b=Ke):(x=Ge,b=Qe);var k,_,S,z=s.dir*(0==s.ori?1:-1),T={stroke:new Path2D,fill:null,clip:null,band:null},D=T.stroke,E=y,P=-y,A=[],W=d(f(a[1==z?t:l],s,m,v)),Y=!1,C=e(o,t,l,1*z),H=e(o,t,l,-1*z),F=M(f(a[C],s,m,v),.5),N=M(f(a[H],s,m,v),.5);F>v&&Le(A,v,F);for(var I=1==z?t:l;I>=t&&l>=I;I+=z){var L=d(f(a[I],s,m,v));if(L==W)null!=o[I]?(k=d(c(o[I],u,w,h)),E==y&&x(D,L,k),E=p(k,E),P=g(k,P)):Y||null!==o[I]||(Y=!0);else{var V=!1;E!=y?(b(D,W,E,P,k),_=S=W):Y&&(V=!0,Y=!1),null!=o[I]?(x(D,L,k=d(c(o[I],u,w,h))),E=P=k,L-W>1&&null===o[I-z]&&(V=!0)):(E=y,P=-y,Y||null!==o[I]||(Y=!0)),V&&Le(A,_,L),W=L}}if(E!=y&&E!=P&&S!=W&&b(D,W,E,P,k),v+m>N&&Le(A,N,v+m),null!=i.fill){var O=T.fill=new Path2D(D),j=d(c(i.fillTo(n,r,i.min,i.max),u,w,h));x(O,N,j),x(O,F,j)}return i.spanGaps||(T.clip=Ie(A,s.ori,v,h,m,w)),n.bands.length>0&&(T.band=Ne(n,r,t,l,D)),T}))}function nr(n,e,r,t,l){var i,a,o,s,u,f,c,v,h,m,p,g,b,k,_,y,M,S,z,T,D,E,P,A,W,Y=new Path2D,C=n.length;t(Y,d(n[0]),d(e[0]));for(var H=0;C-1>H;H++){var F=0==H?0:H-1;a=e[F],s=e[H],u=n[H+1],f=e[H+1],C>H+2?(c=n[H+2],v=e[H+2]):(c=u,v=f),b=x(w((i=n[F])-(o=n[H]),2)+w(a-s,2)),k=x(w(o-u,2)+w(s-f,2)),_=x(w(u-c,2)+w(f-v,2)),T=w(_,r),E=w(_,2*r),D=w(k,r),P=w(k,2*r),(S=3*(W=w(b,r))*(W+D))>0&&(S=1/S),(z=3*T*(T+D))>0&&(z=1/z),m=(-P*a+(y=2*(A=w(b,2*r))+3*W*D+P)*s+A*f)*S,g=(E*s+(M=2*E+3*T*D+P)*f-P*v)*z,0==(h=(-P*i+y*o+A*u)*S)&&0==m&&(h=o,m=s),0==(p=(E*o+M*u-P*c)*z)&&0==g&&(p=u,g=f),l(Y,h,m,p,g,u,f)}return Y}var er=$e();function rr(n,e,r,t){return(t?[n[0],n[1]].concat(n.slice(2)):[n[0]].concat(n.slice(1))).map(((n,t)=>tr(n,t,e,r)))}function tr(n,e,r,t){return V({},0==e?r:t,n)}var lr=[null,null];function ir(n,e,r){return null==e?lr:[e,r]}var ar=ir;function or(n,e,r){return null==e?lr:o(e,r,.1,!0)}function sr(n,e,r,t){return null==e?lr:l(e,r,n.scales[t].log,!1)}var ur=sr;function fr(n){var e;return[n=n.replace(/(\d+)px/,((n,r)=>(e=d(r*fn))+"px")),e]}function cr(e,r,t){var i={};function a(n,e){return 3==e.distr?b((n>0?n:e.clamp(i,n,e.min,e.max,e.key))/e.min)/b(e.max/e.min):(n-e.min)/(e.max-e.min)}function u(n,e,r,t){var l=a(n,e);return t+r*(-1==e.dir?1-l:l)}function f(n,e,r,t){var l=a(n,e);return t+r*(-1==e.dir?l:1-l)}function c(n,e,r,t){return 0==e.ori?u(n,e,r,t):f(n,e,r,t)}i.valToPosH=u,i.valToPosV=f;var x=!1;i.status=0;var k=i.root=mn("uplot");null!=e.id&&(k.id=e.id),cn(k,e.class),e.title&&(mn("u-title",k).textContent=e.title);var P=dn("canvas"),Y=i.ctx=P.getContext("2d"),C=mn("u-wrap",k),O=mn("u-under",C);C.appendChild(P);var Z=mn("u-over",C),gn=s((e=L(e)).pxAlign,!0);(e.plugins||[]).forEach((n=>{n.opts&&(e=n.opts(i,e)||e)}));var bn=e.ms||.001,kn=i.series=rr(e.series||[],ge,Pe,!1),_n=i.axes=rr(e.axes||[],pe,Te,!0),yn=i.scales={},Mn=i.bands=e.bands||[];Mn.forEach((n=>{n.fill=z(n.fill||null)}));var Sn=kn[0].scale,zn={axes:function(){_n.forEach(((n,e)=>{if(n.show&&n._show){var r=yn[n.scale],t=n.side,l=t%2,a=0==l?Ge:Be,o=0==l?Le:je,s=d(n.gap*fn),u=n.ticks,f=u.show?d(u.size*fn):0,v=n._found,h=v[0],m=v[1],p=n._splits,g=2==r.distr?p.map((n=>Mr[n])):p,w=2==r.distr?Mr[p[1]]-Mr[p[0]]:h,x=n._rotate*-_/180,b=d(n._pos*fn),k=b+(f+s)*(0==l&&0==t||1==l&&3==t?-1:1),y=0==l?k:0,M=1==l?k:0;Y.font=n.font[0],Y.fillStyle=n.stroke(i,e),Y.textAlign=1==n.align?J:2==n.align?q:x>0?J:0>x?q:0==l?"center":3==t?q:J,Y.textBaseline=x||1==l?"middle":2==t?R:U;var S=1.5*n.font[1],z=p.map((n=>d(c(n,r,a,o))));if(n._values.forEach(((n,e)=>{null!=n&&(0==l?M=z[e]:y=z[e],(""+n).split(/\n/gm).forEach(((n,e)=>{x?(Y.save(),Y.translate(M,y+e*S),Y.rotate(x),Y.fillText(n,0,0),Y.restore()):Y.fillText(n,M,y+e*S)})))})),n.label){Y.save();var T=d(n._lpos*fn);1==l?(M=y=0,Y.translate(T,d(je+Be/2)),Y.rotate((3==t?-_:_)/2)):(M=d(Le+Ge/2),y=T),Y.font=n.labelFont[0],Y.textAlign="center",Y.textBaseline=2==t?R:U,Y.fillText(n.label,M,y),Y.restore()}u.show&&Pr(z,u.filter(i,g,e,m,w),l,t,b,f,A(u.width*fn,3),u.stroke(i,e),u.dash,u.cap);var D=n.grid;D.show&&Pr(z,D.filter(i,g,e,m,w),l,0==l?2:1,0==l?je:Le,0==l?Be:Ge,A(D.width*fn,3),D.stroke(i,e),D.dash,D.cap)}})),Tt("drawAxes")},series:function(){wr>0&&(kn.forEach(((n,e)=>{if(e>0&&n.show&&null==n._paths){var t=function(n){for(var e=S(kr-1,0,wr-1),r=S(_r+1,0,wr-1);null==n[e]&&e>0;)e--;for(;null==n[r]&&wr-1>r;)r++;return[e,r]}(r[e]);n._paths=n.paths(i,e,t[0],t[1])}})),kn.forEach(((n,e)=>{e>0&&n.show&&(n._paths&&function(n){var e=kn[n],r=e._paths,t=r.stroke,l=r.fill,a=r.clip,o=A(e.width*fn,3),s=o%2/2,u=e._stroke=e.stroke(i,n),f=e._fill=e.fill(i,n);Y.globalAlpha=e.alpha;var c=gn&&e.pxAlign;c&&Y.translate(s,s),Y.save();var v=Le,h=je,d=Ge,m=Be,p=o*fn/2;0==e.min&&(m+=p),0==e.max&&(h-=p,m+=p),Y.beginPath(),Y.rect(v,h,d,m),Y.clip(),a&&Y.clip(a),function(n,e,r,t,l,a,o,s){var u=!1;Mn.forEach(((f,c)=>{if(f.series[0]==n){var v=kn[f.series[1]],h=(v._paths||H).band;Y.save();var d=null;v.show&&h&&(d=f.fill(i,c)||a,Y.clip(h)),Er(e,r,t,l,d,o,s),Y.restore(),u=!0}})),u||Er(e,r,t,l,a,o,s)}(n,u,o,e.dash,e.cap,f,t,l),Y.restore(),c&&Y.translate(-s,-s),Y.globalAlpha=1}(e),n.points.show(i,e,kr,_r)&&function(n){var e=kn[n],t=e.points,l=A(t.width*fn,3),a=l%2/2,o=t.width>0,s=(t.size-t.width)/2*fn,u=A(2*s,3),f=gn&&e.pxAlign;f&&Y.translate(a,a),Y.save(),Y.beginPath(),Y.rect(Le-u,je-u,Ge+2*u,Be+2*u),Y.clip(),Y.globalAlpha=e.alpha;var c,v,h,m,p=new Path2D,g=yn[e.scale];0==Nn.ori?(c=Ge,v=Le,h=Be,m=je):(c=Be,v=je,h=Ge,m=Le);for(var w=kr;_r>=w;w++)if(null!=r[n][w]){var x=d(An(r[0][w],Nn,c,v)),b=d(Wn(r[n][w],g,h,m));Yn(p,x+s,b),Fn(p,x,b,s,0,2*_)}var k=t._stroke=t.stroke(i,n),y=t._fill=t.fill(i,n);Dr(k,l,t.dash,t.cap,y||(o?"#fff":e._stroke)),Y.fill(p),o&&Y.stroke(p),Y.globalAlpha=1,Y.restore(),f&&Y.translate(-a,-a)}(e),Tt("drawSeries",e))})))}},Tn=(e.drawOrder||["axes","series"]).map((n=>zn[n]));function En(n){var r=yn[n];if(null==r){var t=(e.scales||H)[n]||H;if(null!=t.from)En(t.from),yn[n]=V({},yn[t.from],t);else{(r=yn[n]=V({},n==Sn?We:Ye,t)).key=n;var l=r.time,i=3==r.distr,a=r.range;if(n!=Sn&&!F(a)&&I(a)){var s=a;a=(n,e,r)=>null==e?lr:o(e,r,s)}r.range=z(a||(l?ar:n==Sn?i?ur:ir:i?sr:or)),r.auto=z(r.auto),r.clamp=z(r.clamp||Ae)}}}for(var Pn in En("x"),En("y"),kn.forEach((n=>{En(n.scale)})),_n.forEach((n=>{En(n.scale)})),e.scales)En(Pn);var An,Wn,Yn,Fn,Nn=yn[Sn],In=Nn.distr;0==Nn.ori?(cn(k,"u-hz"),An=u,Wn=f,Yn=Ve,Fn=Ue):(cn(k,"u-vt"),An=f,Wn=u,Yn=Oe,Fn=Je);var Ln={};for(var Vn in yn){var On=yn[Vn];null==On.min&&null==On.max||(Ln[Vn]={min:On.min,max:On.max})}var jn,Gn=e.tzDate||(n=>new Date(n/bn)),Bn=e.fmtDate||Dn,Rn=1==bn?Xn(Gn):ne(Gn),Un=re(Gn,ee(1==bn?Zn:$n,Bn)),Jn=ie(Gn,le("{YYYY}-{MM}-{DD} {h}:{mm}{aa}",Bn)),Kn=V({show:!0,live:!0},e.legend),te=Kn.show;Kn.width=z(s(Kn.width,2)),Kn.dash=z(Kn.dash||"solid"),Kn.stroke=z(Kn.stroke||ae),Kn.fill=z(Kn.fill||oe);var se,ue=[],fe=!1;if(te){jn=dn("table","u-legend",k);var ve=kn[1]?kn[1].values:null;if(fe=null!=ve){var he=dn("tr","u-thead",jn);for(var de in dn("th",null,he),se=ve(i,1,0))dn("th",on,he).textContent=de}else se={_:0},cn(jn,"u-inline"),Kn.live&&cn(jn,"u-live")}var me=new Map;function ke(n,e,r){var t=me.get(e)||{},l=nr.bind[n](i,e,r);l&&(wn(n,e,t[n]=l),me.set(e,t))}var _e=0,ye=0,Me=0,Fe=0,Ne=0,Ie=0,Le=0,je=0,Ge=0,Be=0;i.bbox={};var Re=!1,qe=!1,Ze=!1,Xe=!1,Ke=!1;function Qe(n,e){n==i.width&&e==i.height||$e(n,e),Yr(!1),Ze=!0,qe=!0,Xe=!0,Ke=!0,Jr()}function $e(n,e){i.width=_e=Me=n,i.height=ye=Fe=e,Ne=Ie=0,function(){var n=!1,e=!1,r=!1,t=!1;_n.forEach((l=>{if(l.show&&l._show){var i=l.side,a=i%2,o=l._size+(l.labelSize=null!=l.label?l.labelSize||30:0);o>0&&(a?(Me-=o,3==i?(Ne+=o,t=!0):r=!0):(Fe-=o,0==i?(Ie+=o,n=!0):e=!0))}})),pr[0]=n,pr[1]=r,pr[2]=e,pr[3]=t,Me-=br[1]+br[3],Ne+=br[3],Fe-=br[2]+br[0],Ie+=br[0]}(),function(){var n=Ne+Me,e=Ie+Fe,r=Ne,t=Ie;function l(l,i){switch(l){case 1:return(n+=i)-i;case 2:return(e+=i)-i;case 3:return(r-=i)+i;case 0:return(t-=i)+i}}_n.forEach((n=>{if(n.show&&n._show){var e=n.side;n._pos=l(e,n._size),null!=n.label&&(n._lpos=l(e,n.labelSize))}}))}();var r=i.bbox;Le=r.left=M(Ne*fn,.5),je=r.top=M(Ie*fn,.5),Ge=r.width=M(Me*fn,.5),Be=r.height=M(Fe*fn,.5)}i.setSize=function(n){Qe(n.width,n.height)};var nr=i.cursor=V({},ce,e.cursor);nr._lock=!1;var cr=nr.points;cr.show=z(cr.show),cr.size=z(cr.size),cr.stroke=z(cr.stroke),cr.width=z(cr.width),cr.fill=z(cr.fill);var vr=i.focus=V({},e.focus||{alpha:.3},nr.focus),hr=vr.prox>=0,dr=[null];function mr(n,e){var r=yn[n.scale].time,t=n.value;if(n.value=r?N(t)?ie(Gn,le(t,Bn)):t||Jn:t||ze,n.label=n.label||(r?"Time":"Value"),e>0){n.width=null==n.width?1:n.width,n.paths=n.paths||er||D,n.fillTo=z(n.fillTo||Ee),n.pxAlign=s(n.pxAlign,!0),n.stroke=z(n.stroke||null),n.fill=z(n.fill||null),n._stroke=n._fill=n._paths=n._focus=null;var l=De(n.width,1),a=n.points=V({},{size:l,width:g(1,.2*l),stroke:n.stroke,space:2*l,_stroke:null,_fill:null},n.points);a.show=z(a.show),a.fill=z(a.fill),a.stroke=z(a.stroke)}if(te&&ue.splice(e,0,function(n,e){if(0==e&&(fe||!Kn.live))return null;var r=[],t=dn("tr","u-series",jn,jn.childNodes[e]);cn(t,n.class),n.show||cn(t,an);var l=dn("th",null,t),a=mn("u-marker",l);if(e>0){var o=Kn.width(i,e);o&&(a.style.border=o+"px "+Kn.dash(i,e)+" "+Kn.stroke(i,e)),a.style.background=Kn.fill(i,e)}var s=mn(on,l);for(var u in s.textContent=n.label,e>0&&(ke("click",l,(()=>{nr._lock||ot(kn.indexOf(n),{show:!n.show},Dt.setSeries)})),hr&&ke(nn,l,(()=>{nr._lock||ot(kn.indexOf(n),st,Dt.setSeries)}))),se){var f=dn("td","u-value",t);f.textContent="--",r.push(f)}return r}(n,e)),nr.show){var o=function(n,e){if(e>0){var r=nr.points.show(i,e);if(r)return cn(r,"u-cursor-pt"),cn(r,n.class),pn(r,-10,-10,Me,Fe),Z.insertBefore(r,dr[e]),r}}(n,e);o&&dr.splice(e,0,o)}}i.addSeries=function(n,e){n=tr(n,e=null==e?kn.length:e,ge,Pe),kn.splice(e,0,n),mr(kn[e],e)},i.delSeries=function(n){kn.splice(n,1),te&&ue.splice(n,1)[0][0].parentNode.remove(),dr.length>1&&dr.splice(n,1)[0].remove()},kn.forEach(mr);var pr=[!1,!1,!1,!1];function gr(n,e,r){var t=r[0],l=r[1],i=r[2],a=r[3],o=e%2,s=0;return 0==o&&(a||l)&&(s=0==e&&!t||2==e&&!i?d(pe.size/3):0),1==o&&(t||i)&&(s=1==e&&!l||3==e&&!a?d(Te.size/2):0),s}_n.forEach((function(n,e){if(n._show=n.show,n.show){var r=yn[n.scale];null==r&&(n.scale=n.side%2?kn[1].scale:Sn,r=yn[n.scale]);var t=r.time;n.size=z(n.size),n.space=z(n.space),n.rotate=z(n.rotate),n.incrs=z(n.incrs||(2==r.distr?Cn:t?1==bn?qn:Qn:Hn)),n.splits=z(n.splits||(t&&1==r.distr?Rn:3==r.distr?be:xe)),n.stroke=z(n.stroke),n.grid.stroke=z(n.grid.stroke),n.ticks.stroke=z(n.ticks.stroke);var l=n.values;n.values=t?F(l)?re(Gn,ee(l,Bn)):N(l)?function(n,e){var r=Dn(e);return(e,t)=>t.map((e=>r(n(e))))}(Gn,l):l||Un:l||we,n.filter=z(n.filter||(3==r.distr?Se:T)),n.font=fr(n.font),n.labelFont=fr(n.labelFont),n._size=n.size(i,null,e,0),n._space=n._rotate=n._incrs=n._found=n._splits=n._values=null,n._size>0&&(pr[e]=!0)}}));var wr,xr=i.padding=(e.padding||[gr,gr,gr,gr]).map((n=>z(s(n,gr)))),br=i._padding=xr.map(((n,e)=>n(i,e,pr,0))),kr=null,_r=null,yr=kn[0].idxs,Mr=null,Sr=!1;function zr(n,e){if((n=n||[])[0]=n[0]||[],i.data=n,r=n.slice(),wr=(Mr=r[0]).length,2==In&&(r[0]=Mr.map(((n,e)=>e))),i._data=r,Yr(!0),Tt("setData"),!1!==e){var t=Nn;t.auto(i,Sr)?Tr():at(Sn,t.min,t.max),Xe=!0,Ke=!0,Jr()}}function Tr(){var n,e,t,i;Sr=!0,wr>0?(kr=yr[0]=0,_r=yr[1]=wr-1,t=r[0][kr],i=r[0][_r],2==In?(t=kr,i=_r):1==wr&&(3==In?(t=(n=l(t,t,Nn.log,!1))[0],i=n[1]):Nn.time?i=t+86400/bn:(t=(e=o(t,i,.1,!0))[0],i=e[1]))):(kr=yr[0]=t=null,_r=yr[1]=i=null),at(Sn,t,i)}function Dr(n,e,r,t,l){Y.strokeStyle=n||X,Y.lineWidth=e,Y.lineJoin="round",Y.lineCap=t||"butt",Y.setLineDash(r||[]),Y.fillStyle=l||X}function Er(n,e,r,t,l,i,a){Dr(n,e,r,t,l),l&&a&&Y.fill(a),n&&i&&e&&Y.stroke(i)}function Pr(n,e,r,t,l,i,a,o,s,u){var f=a%2/2;gn&&Y.translate(f,f),Dr(o,a,s,u),Y.beginPath();var c,v,h,d,m=l+(0==t||3==t?-i:i);0==r?(v=l,d=m):(c=l,h=m),n.forEach(((n,t)=>{null!=e[t]&&(0==r?c=h=n:v=d=n,Y.moveTo(c,v),Y.lineTo(h,d))})),Y.stroke(),gn&&Y.translate(-f,-f)}function Ar(n){var e=!0;return _n.forEach(((r,t)=>{if(r.show){var l=yn[r.scale];if(null!=l.min){r._show||(e=!1,r._show=!0,Yr(!1));var a=r.side,o=l.min,s=l.max,u=function(n,e,r,t){var l,a=_n[n];if(t>0){var o=a._space=a.space(i,n,e,r,t),s=a._incrs=a.incrs(i,n,e,r,t,o);l=a._found=function(n,e,r,t,l){for(var i=t/(e-n),a=(""+h(n)).length,o=0;r.length>o;o++){var s=r[o]*i,u=10>r[o]?W.get(r[o]):0;if(s>=l&&17>a+u)return[r[o],s]}return[0,0]}(e,r,s,t,o)}else l=[0,0];return l}(t,o,s,0==a%2?Me:Fe),f=u[0],c=u[1];if(0!=c){var v=r._splits=r.splits(i,t,o,s,f,c,2==l.distr),d=2==l.distr?v.map((n=>Mr[n])):v,p=2==l.distr?Mr[v[1]]-Mr[v[0]]:f,g=r._values=r.values(i,r.filter(i,d,t,c,p),t,c,p);r._rotate=2==a?r.rotate(i,g,t,c):0;var w=r._size;r._size=m(r.size(i,g,t,n)),null!=w&&r._size!=w&&(e=!1)}}else r._show&&(e=!1,r._show=!1,Yr(!1))}})),e}function Wr(n){var e=!0;return xr.forEach(((r,t)=>{var l=r(i,t,pr,n);l!=br[t]&&(e=!1),br[t]=l})),e}function Yr(n){kn.forEach(((e,r)=>{r>0&&(e._paths=null,n&&(e.min=null,e.max=null))}))}i.setData=zr;var Cr,Hr,Fr,Nr,Ir,Lr,Vr,Or,jr,Gr,Br,Rr,Ur=!1;function Jr(){Ur||(j(qr),Ur=!0)}function qr(){Re&&(function(){var e=L(yn);for(var t in e){var l=e[t],a=Ln[t];if(null!=a&&null!=a.min)V(l,a),t==Sn&&Yr(!0);else if(t!=Sn)if(0==wr&&null==l.from){var o=l.range(i,null,null,t);l.min=o[0],l.max=o[1]}else l.min=y,l.max=-y}if(wr>0)for(var s in kn.forEach(((t,l)=>{var a=t.scale,o=e[a],s=Ln[a];if(0==l){var u=o.range(i,o.min,o.max,a);o.min=u[0],o.max=u[1],kr=n(o.min,r[0]),_r=n(o.max,r[0]),o.min>r[0][kr]&&kr++,r[0][_r]>o.max&&_r--,t.min=Mr[kr],t.max=Mr[_r]}else if(t.show&&t.auto&&o.auto(i,Sr)&&(null==s||null==s.min)){var f=null==t.min?3==o.distr?function(n,e,r){for(var t=y,l=-y,i=e;r>=i;i++)n[i]>0&&(t=p(t,n[i]),l=g(l,n[i]));return[t==y?1:t,l==-y?10:l]}(r[l],kr,_r):function(n,e,r,t){var l=y,i=-y;if(1==t)l=n[e],i=n[r];else if(-1==t)l=n[r],i=n[e];else for(var a=e;r>=a;a++)null!=n[a]&&(l=p(l,n[a]),i=g(i,n[a]));return[l,i]}(r[l],kr,_r,t.sorted):[t.min,t.max];o.min=p(o.min,t.min=f[0]),o.max=g(o.max,t.max=f[1])}t.idxs[0]=kr,t.idxs[1]=_r})),e){var u=e[s],f=Ln[s];if(null==u.from&&(null==f||null==f.min)){var c=u.range(i,u.min==y?null:u.min,u.max==-y?null:u.max,s);u.min=c[0],u.max=c[1]}}for(var v in e){var h=e[v];if(null!=h.from){var d=e[h.from],m=h.range(i,d.min,d.max,v);h.min=m[0],h.max=m[1]}}var w={},x=!1;for(var b in e){var k=e[b],_=yn[b];_.min==k.min&&_.max==k.max||(_.min=k.min,_.max=k.max,w[b]=x=!0)}if(x){for(var M in kn.forEach((n=>{w[n.scale]&&(n._paths=null)})),w)Ze=!0,Tt("setScale",M);nr.show&&(Xe=!0)}for(var S in Ln)Ln[S]=null}(),Re=!1),Ze&&(function(){for(var n=!1,e=0;!n;){var r=Ar(++e),t=Wr(e);(n=r&&t)||($e(i.width,i.height),qe=!0)}}(),Ze=!1),qe&&(hn(O,J,Ne),hn(O,R,Ie),hn(O,G,Me),hn(O,B,Fe),hn(Z,J,Ne),hn(Z,R,Ie),hn(Z,G,Me),hn(Z,B,Fe),hn(C,G,_e),hn(C,B,ye),P.width=d(_e*fn),P.height=d(ye*fn),gt(),Tt("setSize"),qe=!1),nr.show&&Xe&&(mt(),Xe=!1),_e>0&&ye>0&&(Y.clearRect(0,0,P.width,P.height),Tt("drawClear"),Tn.forEach((n=>n())),Tt("draw")),x||(x=!0,i.status=1,Tt("ready")),Sr=!1,Ur=!1}function Zr(e,t){var l=yn[e];if(null==l.from){if(0==wr){var a=l.range(i,t.min,t.max,e);t.min=a[0],t.max=a[1]}if(t.min>t.max){var o=t.min;t.min=t.max,t.max=o}if(wr>1&&null!=t.min&&null!=t.max&&1e-16>t.max-t.min)return;e==Sn&&2==l.distr&&wr>0&&(t.min=n(t.min,r[0]),t.max=n(t.max,r[0])),Ln[e]=t,Re=!0,Jr()}}i.redraw=(n,e)=>{Ze=e||!1,!1!==n?at(Sn,Nn.min,Nn.max):Jr()},i.setScale=Zr;var Xr=!1,Kr=nr.drag,Qr=Kr.x,$r=Kr.y;nr.show&&(nr.x&&(Cr=mn("u-cursor-x",Z)),nr.y&&(Hr=mn("u-cursor-y",Z)),0==Nn.ori?(Fr=Cr,Nr=Hr):(Fr=Hr,Nr=Cr),Br=nr.left,Rr=nr.top);var nt,et,rt,tt=i.select=V({show:!0,over:!0,left:0,width:0,top:0,height:0},e.select),lt=tt.show?mn("u-select",tt.over?Z:O):null;function it(n,e){if(tt.show){for(var r in n)hn(lt,r,tt[r]=n[r]);!1!==e&&Tt("setSelect")}}function at(n,e,r){Zr(n,{min:e,max:r})}function ot(n,e,r){var t=kn[n];null!=e.focus&&function(n){if(n!=rt){var e=null==n;kn.forEach(((r,t)=>{var l=e||0==t||t==n;r._focus=e?null:l,function(n,e){!function(n,e){kn[n].alpha=e,nr.show&&dr[n]&&(dr[n].style.opacity=e),te&&ue[n]&&(ue[n][0].parentNode.style.opacity=e)}(n,e)}(t,l?1:vr.alpha)})),rt=n,Jr()}}(n),null!=e.show&&(t.show=e.show,function(n){var e=te?ue[n][0].parentNode:null;kn[n].show?e&&vn(e,an):(e&&cn(e,an),dr.length>1&&pn(dr[n],-10,-10,Me,Fe))}(n),at(t.scale,null,null),Jr()),Tt("setSeries",n,e),r&&Pt.pub("setSeries",i,n,e)}i.setSelect=it,i.setSeries=ot;var st={focus:!0},ut={focus:!1};function ft(n,e){var r=yn[e],t=Me;1==r.ori&&(n=(t=Fe)-n),-1==r.dir&&(n=t-n);var l=r.min,i=r.max,a=n/t;return 3==r.distr?(l=b(l),i=b(i),w(10,l+(i-l)*a)):l+(i-l)*a}function ct(n,e){hn(lt,J,tt.left=n),hn(lt,G,tt.width=e)}function vt(n,e){hn(lt,R,tt.top=n),hn(lt,B,tt.height=e)}te&&hr&&wn(en,jn,(()=>{nr._lock||(ot(null,ut,Dt.setSeries),mt())})),i.valToIdx=e=>n(e,r[0]),i.posToIdx=function(e){return n(ft(e,Sn),r[0],kr,_r)},i.posToVal=ft,i.valToPos=(n,e,r)=>0==yn[e].ori?u(n,yn[e],r?Ge:Me,r?Le:0):f(n,yn[e],r?Be:Fe,r?je:0),i.batch=function(n){n(i),Jr()},i.setCursor=n=>{Br=n.left,Rr=n.top,mt()};var ht=0==Nn.ori?ct:vt,dt=1==Nn.ori?ct:vt;function mt(e,t){var l,a;jr=Br,Gr=Rr,l=nr.move(i,Br,Rr),Br=l[0],Rr=l[1],nr.show&&(Fr&&pn(Fr,d(Br),0,Me,Fe),Nr&&pn(Nr,0,d(Rr),Me,Fe)),nt=y;var o=0==Nn.ori?Me:Fe,s=1==Nn.ori?Me:Fe;if(0>Br||0==wr||kr>_r){a=null;for(var u=0;kn.length>u;u++)if(u>0&&dr.length>1&&pn(dr[u],-10,-10,Me,Fe),te&&Kn.live){if(0==u&&fe)continue;for(var f=0;ue[u].length>f;f++)ue[u][f].firstChild.nodeValue="--"}hr&&ot(null,st,Dt.setSeries)}else{var c=ft(0==Nn.ori?Br:Rr,Sn);a=n(c,r[0],kr,_r);for(var h=E(An(r[0][a],Nn,o,0),.5),m=0;kn.length>m;m++){var g=kn[m],w=nr.dataIdx(i,m,a,c),b=w==a?h:E(An(r[0][w],Nn,o,0),.5);if(m>0&&g.show){var k=r[m][w],_=null==k?-10:E(Wn(k,yn[g.scale],s,0),.5);if(_>0){var M=v(_-Rr);M>nt||(nt=M,et=m)}var S=void 0,z=void 0;0==Nn.ori?(S=b,z=_):(S=_,z=b),dr.length>1&&pn(dr[m],S,z,Me,Fe)}if(te&&Kn.live){if(w==nr.idx&&!Ke||0==m&&fe)continue;var T=0==m&&2==In?Mr:r[m],D=fe?g.values(i,m,w):{_:g.value(i,T[w],m,w)},P=0;for(var A in D)ue[m][P++].firstChild.nodeValue=D[A]}}Ke=!1}if(tt.show&&Xr)if(null!=t){var W=Dt.scales,Y=W[0],C=W[1],H=t.cursor.drag;Qr=H._x,$r=H._y;var F,N,I,L,V,O=t.select,j=O.left,G=O.top,B=O.width,R=O.height,U=t.scales[Y].ori,J=t.posToVal;Y&&(0==U?(F=j,N=B):(F=G,N=R),I=yn[Y],L=An(J(F,Y),I,o,0),V=An(J(F+N,Y),I,o,0),ht(p(L,V),v(V-L)),C||dt(0,s)),C&&(1==U?(F=j,N=B):(F=G,N=R),I=yn[C],L=Wn(J(F,C),I,s,0),V=Wn(J(F+N,C),I,s,0),dt(p(L,V),v(V-L)),Y||ht(0,o))}else{var q=v(jr-Ir),Z=v(Gr-Lr);if(1==Nn.ori){var X=q;q=Z,Z=X}Qr=Kr.x&&q>=Kr.dist,$r=Kr.y&&Z>=Kr.dist;var Q,$,nn=Kr.uni;null!=nn?Qr&&$r&&($r=Z>=nn,(Qr=q>=nn)||$r||(Z>q?$r=!0:Qr=!0)):Kr.x&&Kr.y&&(Qr||$r)&&(Qr=$r=!0),Qr&&(0==Nn.ori?(Q=Vr,$=Br):(Q=Or,$=Rr),ht(p(Q,$),v($-Q)),$r||dt(0,s)),$r&&(1==Nn.ori?(Q=Vr,$=Br):(Q=Or,$=Rr),dt(p(Q,$),v($-Q)),Qr||ht(0,o)),Qr||$r||(ht(0,0),dt(0,0))}if(nr.idx=a,nr.left=Br,nr.top=Rr,Kr._x=Qr,Kr._y=$r,null!=e&&(Pt.pub(K,i,Br,Rr,o,s,a),hr)){var en=Dt.setSeries,rn=vr.prox;null==rt?nt>rn||ot(et,st,en):nt>rn?ot(null,st,en):et!=rt&&ot(et,st,en)}x&&Tt("setCursor")}var pt=null;function gt(){pt=Z.getBoundingClientRect()}function wt(n,e,r,t,l,i){nr._lock||(xt(n,e,r,t,l,i,0,!1,null!=n),null!=n?mt(1):mt(null,e))}function xt(n,e,r,t,l,a,o,s,u){var f;if(null!=n)r=n.clientX-pt.left,t=n.clientY-pt.top;else{if(0>r||0>t)return Br=-10,void(Rr=-10);var v=Me,h=Fe,d=l,m=a,p=r,g=t;1==Nn.ori&&(v=Fe,h=Me);var w=Dt.scales,x=w[0],b=w[1];if(1==e.scales[x].ori&&(d=a,m=l,p=t,g=r),r=null!=x?c(e.posToVal(p,x),yn[x],v,0):v*(p/d),t=null!=b?c(e.posToVal(g,b),yn[b],h,0):h*(g/m),1==Nn.ori){var k=r;r=t,t=k}}u&&(r>1&&Me-1>r||(r=M(r,Me)),t>1&&Fe-1>t||(t=M(t,Fe))),s?(Ir=r,Lr=t,f=nr.move(i,r,t),Vr=f[0],Or=f[1]):(Br=r,Rr=t)}function bt(){it({width:0,height:0},!1)}function kt(n,e,r,t,l,a){Xr=!0,Qr=$r=Kr._x=Kr._y=!1,xt(n,e,r,t,l,a,0,!0,!1),null!=n&&(ke($,sn,_t),Pt.pub(Q,i,Vr,Or,Me,Fe,null))}function _t(n,e,r,t,l,a){Xr=Kr._x=Kr._y=!1,xt(n,e,r,t,l,a,0,!1,!0);var o=tt.left,s=tt.top,u=tt.width,f=tt.height,c=u>0||f>0;if(c&&it(tt),Kr.setScale&&c){var v=o,h=u,d=s,m=f;if(1==Nn.ori&&(v=s,h=f,d=o,m=u),Qr&&at(Sn,ft(v,Sn),ft(v+h,Sn)),$r)for(var p in yn){var g=yn[p];p!=Sn&&null==g.from&&g.min!=y&&at(p,ft(d+m,p),ft(d,p))}bt()}else nr.lock&&(nr._lock=!nr._lock,nr._lock||mt());null!=n&&(function(n,e){var r=me.get(e)||{};xn(n,e,r[n]),r[n]=null}($,sn),Pt.pub($,i,Br,Rr,Me,Fe,null))}function yt(n){Tr(),bt(),null!=n&&Pt.pub(rn,i,Br,Rr,Me,Fe,null)}var Mt,St={};St.mousedown=kt,St.mousemove=wt,St.mouseup=_t,St.dblclick=yt,St.setSeries=(n,e,r,t)=>{ot(r,t)},nr.show&&(ke(Q,Z,kt),ke(K,Z,wt),ke(nn,Z,gt),ke(en,Z,(function(){if(!nr._lock){var n=Xr;if(Xr){var e,r,t=!0,l=!0;0==Nn.ori?(e=Qr,r=$r):(e=$r,r=Qr),e&&r&&(t=10>=Br||Br>=Me-10,l=10>=Rr||Rr>=Fe-10),e&&t&&(Br=Vr>Br?0:Me),r&&l&&(Rr=Or>Rr?0:Fe),mt(1),Xr=!1}Br=-10,Rr=-10,mt(1),n&&(Xr=n)}})),ke(rn,Z,yt),Mt=function(n){var e=null;function r(){e=null,n()}return function(){clearTimeout(e),e=setTimeout(r,100)}}(gt),wn(tn,un,Mt),wn(ln,un,Mt),i.syncRect=gt);var zt=i.hooks=e.hooks||{};function Tt(n,e,r){n in zt&&zt[n].forEach((n=>{n.call(null,i,e,r)}))}(e.plugins||[]).forEach((n=>{for(var e in n.hooks)zt[e]=(zt[e]||[]).concat(n.hooks[e])}));var Dt=V({key:null,setSeries:!1,scales:[Sn,null]},nr.sync),Et=Dt.key,Pt=null!=Et?Ce[Et]=Ce[Et]||He():He();function At(){Tt("init",e,r),zr(r||e.data,!1),Ln[Sn]?Zr(Sn,Ln[Sn]):Tr(),Qe(e.width,e.height),it(tt,!1)}return Pt.sub(i),i.pub=function(n,e,r,t,l,i,a){St[n](null,e,r,t,l,i,a)},i.destroy=function(){Pt.unsub(i),xn(tn,un,Mt),xn(ln,un,Mt),k.remove(),Tt("destroy")},t?t instanceof HTMLElement?(t.appendChild(k),At()):t(i,At):At(),i}cr.assign=V,cr.fmtNum=f,cr.rangeNum=o,cr.rangeLog=l,cr.orient=Fe,cr.join=function(n,e){for(var r=new Set,t=0;n.length>t;t++)for(var l=n[t][0],i=l.length,a=0;i>a;a++)r.add(l[a]);for(var o=[Array.from(r).sort(((n,e)=>n-e))],s=o[0].length,u=new Map,f=0;s>f;f++)u.set(o[0][f],f);for(var c=0;n.length>c;c++)for(var v=n[c],h=v[0],d=1;v.length>d;d++){for(var m=v[d],p=Array(s).fill(void 0),g=e?e[c][d]:1,w=[],x=0;m.length>x;x++){var b=m[x],k=u.get(h[x]);null==b?0!=g&&(p[k]=b,2==g&&w.push(k)):p[k]=b}O(p,w,s),o.push(p)}return o},cr.fmtDate=Dn,cr.tzDate=function(n,e){var r;return"Etc/UTC"==e?r=new Date(+n+6e4*n.getTimezoneOffset()):e==En?r=n:(r=new Date(n.toLocaleString("en-US",{timeZone:e}))).setMilliseconds(n.getMilliseconds()),r},cr.addGap=Le,cr.clipGaps=Ie;var vr=cr.paths={};return vr.linear=$e,vr.spline=function(){return(n,r,t,l)=>Fe(n,r,((i,a,o,s,u,f,c,v,h,m,p)=>{var g,w,x;0==s.ori?(g=Ve,x=je,w=qe):(g=Oe,x=Ge,w=Ze);var b=1*s.dir*(0==s.ori?1:-1);t=e(o,t,l,1),l=e(o,t,l,-1);for(var k=[],_=!1,y=d(f(a[1==b?t:l],s,m,v)),M=y,S=[],z=[],T=1==b?t:l;T>=t&&l>=T;T+=b){var D=o[T],E=f(a[T],s,m,v);null!=D?(_&&(Le(k,M,E),_=!1),S.push(M=E),z.push(c(o[T],u,p,h))):null===D&&(Le(k,M,E),_=!0)}var P={stroke:nr(S,z,.5,g,w),fill:null,clip:null,band:null},A=P.stroke;if(null!=i.fill){var W=P.fill=new Path2D(A),Y=i.fillTo(n,r,i.min,i.max),C=d(c(Y,u,p,h));x(W,M,C),x(W,y,C)}return i.spanGaps||(P.clip=Ie(k,s.ori,v,h,m,p)),n.bands.length>0&&(P.band=Ne(n,r,t,l,A)),P}))},vr.stepped=function(n){var r=s(n.align,1);return(n,t,l,i)=>Fe(n,t,((a,o,s,u,f,c,v,h,m,p,g)=>{var w=0==u.ori?je:Ge,x={stroke:new Path2D,fill:null,clip:null,band:null},b=x.stroke,k=1*u.dir*(0==u.ori?1:-1);l=e(s,l,i,1),i=e(s,l,i,-1);var _=[],y=!1,M=d(v(s[1==k?l:i],f,g,m)),S=d(c(o[1==k?l:i],u,p,h)),z=S;w(b,S,M);for(var T=1==k?l:i;T>=l&&i>=T;T+=k){var D=s[T],E=d(c(o[T],u,p,h));if(null!=D){var P=d(v(D,f,g,m));if(y){if(Le(_,z,E),M!=P){var A=a.width*fn/2,W=_[_.length-1];W[0]+=A,W[1]-=A}y=!1}1==r?w(b,E,M):w(b,z,P),w(b,E,P),M=P,z=E}else null===D&&(Le(_,z,E),y=!0)}if(null!=a.fill){var Y=x.fill=new Path2D(b),C=a.fillTo(n,t,a.min,a.max),H=d(v(C,f,g,m));w(Y,z,H),w(Y,S,H)}return a.spanGaps||(x.clip=Ie(_,u.ori,h,m,p,g)),n.bands.length>0&&(x.band=Ne(n,t,l,i,b)),x}))},vr.bars=function(n){var r=s((n=n||H).size,[.6,y]),t=n.align||0,l=1-r[0],i=s(r[1],y)*fn;return(n,r,a,o)=>Fe(n,r,((s,u,f,c,v,h,m,w,x,b,k)=>{var _,y=0==c.ori?Be:Re,S=h(u[1],c,b,w)-h(u[0],c,b,w),z=S*l,T=m(s.fillTo(n,r,s.min,s.max),v,k,x),D=d(s.width*fn),E=d(p(i,S-z)-D),P=1==t?0:-1==t?E:E/2,A={stroke:new Path2D,fill:null,clip:null,band:null},W=n.bands.length>0;W&&(A.band=new Path2D,_=M(m(v.max,v,k,x),.5));for(var Y=A.stroke,C=A.band,H=c.dir*(0==c.ori?1:-1),F=1==H?a:o;F>=a&&o>=F;F+=H){var N=f[F];if(null==N){if(!W)continue;var I=e(f,1==H?a:o,F,-H),L=e(f,F,1==H?o:a,H),V=f[I];N=V+(F-I)/(L-I)*(f[L]-V)}var O=h(2==c.distr?F:u[F],c,b,w),j=m(N,v,k,x),G=d(O-P),B=d(g(j,T)),R=d(p(j,T)),U=B-R;null!=f[F]&&y(Y,G,R,E,U),W&&(B=R,y(C,G,R=_,E,U=B-R))}return null!=s.fill&&(A.fill=new Path2D(Y)),A}))},cr}(); diff --git a/node/static/js/uPlot.iife.min.js.br b/node/static/js/uPlot.iife.min.js.br new file mode 100644 index 0000000000000000000000000000000000000000..7f51a7efabde501eaa062b98b25825e4713a0247 Binary files /dev/null and b/node/static/js/uPlot.iife.min.js.br differ diff --git a/node/static/js/uPlot.iife.min.js.gz b/node/static/js/uPlot.iife.min.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..1a349724b13059baefec6149020277a83e3a9fdd Binary files /dev/null and b/node/static/js/uPlot.iife.min.js.gz differ diff --git a/node/templates/index.html b/node/templates/index.html index 1a470fcf051007773d5738a1b2f7c669fbece10e..7817f55f2adfdd7373d1b06c8b22d833a0ca5b4f 100644 --- a/node/templates/index.html +++ b/node/templates/index.html @@ -64,6 +64,10 @@ </li> {{end}} </ul> + + <div class="chart" + chart-query="all_listeners" + chart-title="Listeners"></div> </div> </div> diff --git a/vendor/github.com/json-iterator/go/.codecov.yml b/vendor/github.com/json-iterator/go/.codecov.yml new file mode 100644 index 0000000000000000000000000000000000000000..955dc0be5fa67651f73927238c3ba011186af65f --- /dev/null +++ b/vendor/github.com/json-iterator/go/.codecov.yml @@ -0,0 +1,3 @@ +ignore: + - "output_tests/.*" + diff --git a/vendor/github.com/json-iterator/go/.gitignore b/vendor/github.com/json-iterator/go/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..15556530a85421a47fc1fa355773e29768a715a5 --- /dev/null +++ b/vendor/github.com/json-iterator/go/.gitignore @@ -0,0 +1,4 @@ +/vendor +/bug_test.go +/coverage.txt +/.idea diff --git a/vendor/github.com/json-iterator/go/.travis.yml b/vendor/github.com/json-iterator/go/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..449e67cd01acba105df358ccac3c32f0693f3f1a --- /dev/null +++ b/vendor/github.com/json-iterator/go/.travis.yml @@ -0,0 +1,14 @@ +language: go + +go: + - 1.8.x + - 1.x + +before_install: + - go get -t -v ./... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/json-iterator/go/Gopkg.lock b/vendor/github.com/json-iterator/go/Gopkg.lock new file mode 100644 index 0000000000000000000000000000000000000000..c8a9fbb3871b0e32024cf102cfd6d5d175c3cda5 --- /dev/null +++ b/vendor/github.com/json-iterator/go/Gopkg.lock @@ -0,0 +1,21 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/modern-go/concurrent" + packages = ["."] + revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a" + version = "1.0.0" + +[[projects]] + name = "github.com/modern-go/reflect2" + packages = ["."] + revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" + version = "1.0.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "ea54a775e5a354cb015502d2e7aa4b74230fc77e894f34a838b268c25ec8eeb8" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/json-iterator/go/Gopkg.toml b/vendor/github.com/json-iterator/go/Gopkg.toml new file mode 100644 index 0000000000000000000000000000000000000000..313a0f887b6f412639bdfed98411843830275d8d --- /dev/null +++ b/vendor/github.com/json-iterator/go/Gopkg.toml @@ -0,0 +1,26 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + +ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"] + +[[constraint]] + name = "github.com/modern-go/reflect2" + version = "1.0.1" diff --git a/vendor/github.com/json-iterator/go/LICENSE b/vendor/github.com/json-iterator/go/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..2cf4f5ab28e9c50b4553caadfc0d978edd0d4adb --- /dev/null +++ b/vendor/github.com/json-iterator/go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 json-iterator + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/json-iterator/go/README.md b/vendor/github.com/json-iterator/go/README.md new file mode 100644 index 0000000000000000000000000000000000000000..52b111d5f36ef2313f57fe70f58e41e866046bef --- /dev/null +++ b/vendor/github.com/json-iterator/go/README.md @@ -0,0 +1,87 @@ +[](https://sourcegraph.com/github.com/json-iterator/go?badge) +[](https://pkg.go.dev/github.com/json-iterator/go) +[](https://travis-ci.org/json-iterator/go) +[](https://codecov.io/gh/json-iterator/go) +[](https://goreportcard.com/report/github.com/json-iterator/go) +[](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE) +[](https://gitter.im/json-iterator/Lobby) + +A high-performance 100% compatible drop-in replacement of "encoding/json" + +You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go) + +# Benchmark + + + +Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go + +Raw Result (easyjson requires static code generation) + +| | ns/op | allocation bytes | allocation times | +| --------------- | ----------- | ---------------- | ---------------- | +| std decode | 35510 ns/op | 1960 B/op | 99 allocs/op | +| easyjson decode | 8499 ns/op | 160 B/op | 4 allocs/op | +| jsoniter decode | 5623 ns/op | 160 B/op | 3 allocs/op | +| std encode | 2213 ns/op | 712 B/op | 5 allocs/op | +| easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op | +| jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op | + +Always benchmark with your own workload. +The result depends heavily on the data input. + +# Usage + +100% compatibility with standard lib + +Replace + +```go +import "encoding/json" +json.Marshal(&data) +``` + +with + +```go +import jsoniter "github.com/json-iterator/go" + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Marshal(&data) +``` + +Replace + +```go +import "encoding/json" +json.Unmarshal(input, &data) +``` + +with + +```go +import jsoniter "github.com/json-iterator/go" + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Unmarshal(input, &data) +``` + +[More documentation](http://jsoniter.com/migrate-from-go-std.html) + +# How to get + +``` +go get github.com/json-iterator/go +``` + +# Contribution Welcomed ! + +Contributors + +- [thockin](https://github.com/thockin) +- [mattn](https://github.com/mattn) +- [cch123](https://github.com/cch123) +- [Oleg Shaldybin](https://github.com/olegshaldybin) +- [Jason Toffaletti](https://github.com/toffaletti) + +Report issue or pull request, or email taowen@gmail.com, or [](https://gitter.im/json-iterator/Lobby) diff --git a/vendor/github.com/json-iterator/go/adapter.go b/vendor/github.com/json-iterator/go/adapter.go new file mode 100644 index 0000000000000000000000000000000000000000..92d2cc4a3dd5ce61d6d90d7b1c3c8cb155366c55 --- /dev/null +++ b/vendor/github.com/json-iterator/go/adapter.go @@ -0,0 +1,150 @@ +package jsoniter + +import ( + "bytes" + "io" +) + +// RawMessage to make replace json with jsoniter +type RawMessage []byte + +// Unmarshal adapts to json/encoding Unmarshal API +// +// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. +// Refer to https://godoc.org/encoding/json#Unmarshal for more information +func Unmarshal(data []byte, v interface{}) error { + return ConfigDefault.Unmarshal(data, v) +} + +// UnmarshalFromString is a convenient method to read from string instead of []byte +func UnmarshalFromString(str string, v interface{}) error { + return ConfigDefault.UnmarshalFromString(str, v) +} + +// Get quick method to get value from deeply nested JSON structure +func Get(data []byte, path ...interface{}) Any { + return ConfigDefault.Get(data, path...) +} + +// Marshal adapts to json/encoding Marshal API +// +// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API +// Refer to https://godoc.org/encoding/json#Marshal for more information +func Marshal(v interface{}) ([]byte, error) { + return ConfigDefault.Marshal(v) +} + +// MarshalIndent same as json.MarshalIndent. Prefix is not supported. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + return ConfigDefault.MarshalIndent(v, prefix, indent) +} + +// MarshalToString convenient method to write as string instead of []byte +func MarshalToString(v interface{}) (string, error) { + return ConfigDefault.MarshalToString(v) +} + +// NewDecoder adapts to json/stream NewDecoder API. +// +// NewDecoder returns a new decoder that reads from r. +// +// Instead of a json/encoding Decoder, an Decoder is returned +// Refer to https://godoc.org/encoding/json#NewDecoder for more information +func NewDecoder(reader io.Reader) *Decoder { + return ConfigDefault.NewDecoder(reader) +} + +// Decoder reads and decodes JSON values from an input stream. +// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) +type Decoder struct { + iter *Iterator +} + +// Decode decode JSON into interface{} +func (adapter *Decoder) Decode(obj interface{}) error { + if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil { + if !adapter.iter.loadMore() { + return io.EOF + } + } + adapter.iter.ReadVal(obj) + err := adapter.iter.Error + if err == io.EOF { + return nil + } + return adapter.iter.Error +} + +// More is there more? +func (adapter *Decoder) More() bool { + iter := adapter.iter + if iter.Error != nil { + return false + } + c := iter.nextToken() + if c == 0 { + return false + } + iter.unreadByte() + return c != ']' && c != '}' +} + +// Buffered remaining buffer +func (adapter *Decoder) Buffered() io.Reader { + remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail] + return bytes.NewReader(remaining) +} + +// UseNumber causes the Decoder to unmarshal a number into an interface{} as a +// Number instead of as a float64. +func (adapter *Decoder) UseNumber() { + cfg := adapter.iter.cfg.configBeforeFrozen + cfg.UseNumber = true + adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) +} + +// DisallowUnknownFields causes the Decoder to return an error when the destination +// is a struct and the input contains object keys which do not match any +// non-ignored, exported fields in the destination. +func (adapter *Decoder) DisallowUnknownFields() { + cfg := adapter.iter.cfg.configBeforeFrozen + cfg.DisallowUnknownFields = true + adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) +} + +// NewEncoder same as json.NewEncoder +func NewEncoder(writer io.Writer) *Encoder { + return ConfigDefault.NewEncoder(writer) +} + +// Encoder same as json.Encoder +type Encoder struct { + stream *Stream +} + +// Encode encode interface{} as JSON to io.Writer +func (adapter *Encoder) Encode(val interface{}) error { + adapter.stream.WriteVal(val) + adapter.stream.WriteRaw("\n") + adapter.stream.Flush() + return adapter.stream.Error +} + +// SetIndent set the indention. Prefix is not supported +func (adapter *Encoder) SetIndent(prefix, indent string) { + config := adapter.stream.cfg.configBeforeFrozen + config.IndentionStep = len(indent) + adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) +} + +// SetEscapeHTML escape html by default, set to false to disable +func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { + config := adapter.stream.cfg.configBeforeFrozen + config.EscapeHTML = escapeHTML + adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) +} + +// Valid reports whether data is a valid JSON encoding. +func Valid(data []byte) bool { + return ConfigDefault.Valid(data) +} diff --git a/vendor/github.com/json-iterator/go/any.go b/vendor/github.com/json-iterator/go/any.go new file mode 100644 index 0000000000000000000000000000000000000000..f6b8aeab0a12dd61faf85156fd8dea10c96a8c9c --- /dev/null +++ b/vendor/github.com/json-iterator/go/any.go @@ -0,0 +1,325 @@ +package jsoniter + +import ( + "errors" + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "strconv" + "unsafe" +) + +// Any generic object representation. +// The lazy json implementation holds []byte and parse lazily. +type Any interface { + LastError() error + ValueType() ValueType + MustBeValid() Any + ToBool() bool + ToInt() int + ToInt32() int32 + ToInt64() int64 + ToUint() uint + ToUint32() uint32 + ToUint64() uint64 + ToFloat32() float32 + ToFloat64() float64 + ToString() string + ToVal(val interface{}) + Get(path ...interface{}) Any + Size() int + Keys() []string + GetInterface() interface{} + WriteTo(stream *Stream) +} + +type baseAny struct{} + +func (any *baseAny) Get(path ...interface{}) Any { + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} +} + +func (any *baseAny) Size() int { + return 0 +} + +func (any *baseAny) Keys() []string { + return []string{} +} + +func (any *baseAny) ToVal(obj interface{}) { + panic("not implemented") +} + +// WrapInt32 turn int32 into Any interface +func WrapInt32(val int32) Any { + return &int32Any{baseAny{}, val} +} + +// WrapInt64 turn int64 into Any interface +func WrapInt64(val int64) Any { + return &int64Any{baseAny{}, val} +} + +// WrapUint32 turn uint32 into Any interface +func WrapUint32(val uint32) Any { + return &uint32Any{baseAny{}, val} +} + +// WrapUint64 turn uint64 into Any interface +func WrapUint64(val uint64) Any { + return &uint64Any{baseAny{}, val} +} + +// WrapFloat64 turn float64 into Any interface +func WrapFloat64(val float64) Any { + return &floatAny{baseAny{}, val} +} + +// WrapString turn string into Any interface +func WrapString(val string) Any { + return &stringAny{baseAny{}, val} +} + +// Wrap turn a go object into Any interface +func Wrap(val interface{}) Any { + if val == nil { + return &nilAny{} + } + asAny, isAny := val.(Any) + if isAny { + return asAny + } + typ := reflect2.TypeOf(val) + switch typ.Kind() { + case reflect.Slice: + return wrapArray(val) + case reflect.Struct: + return wrapStruct(val) + case reflect.Map: + return wrapMap(val) + case reflect.String: + return WrapString(val.(string)) + case reflect.Int: + if strconv.IntSize == 32 { + return WrapInt32(int32(val.(int))) + } + return WrapInt64(int64(val.(int))) + case reflect.Int8: + return WrapInt32(int32(val.(int8))) + case reflect.Int16: + return WrapInt32(int32(val.(int16))) + case reflect.Int32: + return WrapInt32(val.(int32)) + case reflect.Int64: + return WrapInt64(val.(int64)) + case reflect.Uint: + if strconv.IntSize == 32 { + return WrapUint32(uint32(val.(uint))) + } + return WrapUint64(uint64(val.(uint))) + case reflect.Uintptr: + if ptrSize == 32 { + return WrapUint32(uint32(val.(uintptr))) + } + return WrapUint64(uint64(val.(uintptr))) + case reflect.Uint8: + return WrapUint32(uint32(val.(uint8))) + case reflect.Uint16: + return WrapUint32(uint32(val.(uint16))) + case reflect.Uint32: + return WrapUint32(uint32(val.(uint32))) + case reflect.Uint64: + return WrapUint64(val.(uint64)) + case reflect.Float32: + return WrapFloat64(float64(val.(float32))) + case reflect.Float64: + return WrapFloat64(val.(float64)) + case reflect.Bool: + if val.(bool) == true { + return &trueAny{} + } + return &falseAny{} + } + return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} +} + +// ReadAny read next JSON element as an Any object. It is a better json.RawMessage. +func (iter *Iterator) ReadAny() Any { + return iter.readAny() +} + +func (iter *Iterator) readAny() Any { + c := iter.nextToken() + switch c { + case '"': + iter.unreadByte() + return &stringAny{baseAny{}, iter.ReadString()} + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + return &nilAny{} + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + return &trueAny{} + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + return &falseAny{} + case '{': + return iter.readObjectAny() + case '[': + return iter.readArrayAny() + case '-': + return iter.readNumberAny(false) + case 0: + return &invalidAny{baseAny{}, errors.New("input is empty")} + default: + return iter.readNumberAny(true) + } +} + +func (iter *Iterator) readNumberAny(positive bool) Any { + iter.startCapture(iter.head - 1) + iter.skipNumber() + lazyBuf := iter.stopCapture() + return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readObjectAny() Any { + iter.startCapture(iter.head - 1) + iter.skipObject() + lazyBuf := iter.stopCapture() + return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readArrayAny() Any { + iter.startCapture(iter.head - 1) + iter.skipArray() + lazyBuf := iter.stopCapture() + return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func locateObjectField(iter *Iterator, target string) []byte { + var found []byte + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + if field == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + return true + }) + return found +} + +func locateArrayElement(iter *Iterator, target int) []byte { + var found []byte + n := 0 + iter.ReadArrayCB(func(iter *Iterator) bool { + if n == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + n++ + return true + }) + return found +} + +func locatePath(iter *Iterator, path []interface{}) Any { + for i, pathKeyObj := range path { + switch pathKey := pathKeyObj.(type) { + case string: + valueBytes := locateObjectField(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int: + valueBytes := locateArrayElement(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int32: + if '*' == pathKey { + return iter.readAny().Get(path[i:]...) + } + return newInvalidAny(path[i:]) + default: + return newInvalidAny(path[i:]) + } + } + if iter.Error != nil && iter.Error != io.EOF { + return &invalidAny{baseAny{}, iter.Error} + } + return iter.readAny() +} + +var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem() + +func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ == anyType { + return &directAnyCodec{} + } + if typ.Implements(anyType) { + return &anyCodec{ + valType: typ, + } + } + return nil +} + +func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == anyType { + return &directAnyCodec{} + } + if typ.Implements(anyType) { + return &anyCodec{ + valType: typ, + } + } + return nil +} + +type anyCodec struct { + valType reflect2.Type +} + +func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + panic("not implemented") +} + +func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + any.WriteTo(stream) +} + +func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + return any.Size() == 0 +} + +type directAnyCodec struct { +} + +func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *(*Any)(ptr) = iter.readAny() +} + +func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + any := *(*Any)(ptr) + if any == nil { + stream.WriteNil() + return + } + any.WriteTo(stream) +} + +func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool { + any := *(*Any)(ptr) + return any.Size() == 0 +} diff --git a/vendor/github.com/json-iterator/go/any_array.go b/vendor/github.com/json-iterator/go/any_array.go new file mode 100644 index 0000000000000000000000000000000000000000..0449e9aa428aeba21696ecd1511880db12ee4445 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_array.go @@ -0,0 +1,278 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type arrayLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *arrayLazyAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayLazyAny) MustBeValid() Any { + return any +} + +func (any *arrayLazyAny) LastError() error { + return any.err +} + +func (any *arrayLazyAny) ToBool() bool { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.ReadArray() +} + +func (any *arrayLazyAny) ToInt() int { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt32() int32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt64() int64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint() uint { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint32() uint32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint64() uint64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat32() float32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat64() float64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *arrayLazyAny) ToVal(val interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(val) +} + +func (any *arrayLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateArrayElement(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + arr := make([]Any, 0) + iter.ReadArrayCB(func(iter *Iterator) bool { + found := iter.readAny().Get(path[1:]...) + if found.ValueType() != InvalidValue { + arr = append(arr, found) + } + return true + }) + return wrapArray(arr) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadArrayCB(func(iter *Iterator) bool { + size++ + iter.Skip() + return true + }) + return size +} + +func (any *arrayLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *arrayLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type arrayAny struct { + baseAny + val reflect.Value +} + +func wrapArray(val interface{}) *arrayAny { + return &arrayAny{baseAny{}, reflect.ValueOf(val)} +} + +func (any *arrayAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayAny) MustBeValid() Any { + return any +} + +func (any *arrayAny) LastError() error { + return nil +} + +func (any *arrayAny) ToBool() bool { + return any.val.Len() != 0 +} + +func (any *arrayAny) ToInt() int { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt32() int32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt64() int64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint() uint { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint32() uint32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint64() uint64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat32() float32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat64() float64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToString() string { + str, _ := MarshalToString(any.val.Interface()) + return str +} + +func (any *arrayAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + if firstPath < 0 || firstPath >= any.val.Len() { + return newInvalidAny(path) + } + return Wrap(any.val.Index(firstPath).Interface()) + case int32: + if '*' == firstPath { + mappedAll := make([]Any, 0) + for i := 0; i < any.val.Len(); i++ { + mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll = append(mappedAll, mapped) + } + } + return wrapArray(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayAny) Size() int { + return any.val.Len() +} + +func (any *arrayAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *arrayAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/vendor/github.com/json-iterator/go/any_bool.go b/vendor/github.com/json-iterator/go/any_bool.go new file mode 100644 index 0000000000000000000000000000000000000000..9452324af5b17483f48e7b453c44266c3078032b --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_bool.go @@ -0,0 +1,137 @@ +package jsoniter + +type trueAny struct { + baseAny +} + +func (any *trueAny) LastError() error { + return nil +} + +func (any *trueAny) ToBool() bool { + return true +} + +func (any *trueAny) ToInt() int { + return 1 +} + +func (any *trueAny) ToInt32() int32 { + return 1 +} + +func (any *trueAny) ToInt64() int64 { + return 1 +} + +func (any *trueAny) ToUint() uint { + return 1 +} + +func (any *trueAny) ToUint32() uint32 { + return 1 +} + +func (any *trueAny) ToUint64() uint64 { + return 1 +} + +func (any *trueAny) ToFloat32() float32 { + return 1 +} + +func (any *trueAny) ToFloat64() float64 { + return 1 +} + +func (any *trueAny) ToString() string { + return "true" +} + +func (any *trueAny) WriteTo(stream *Stream) { + stream.WriteTrue() +} + +func (any *trueAny) Parse() *Iterator { + return nil +} + +func (any *trueAny) GetInterface() interface{} { + return true +} + +func (any *trueAny) ValueType() ValueType { + return BoolValue +} + +func (any *trueAny) MustBeValid() Any { + return any +} + +type falseAny struct { + baseAny +} + +func (any *falseAny) LastError() error { + return nil +} + +func (any *falseAny) ToBool() bool { + return false +} + +func (any *falseAny) ToInt() int { + return 0 +} + +func (any *falseAny) ToInt32() int32 { + return 0 +} + +func (any *falseAny) ToInt64() int64 { + return 0 +} + +func (any *falseAny) ToUint() uint { + return 0 +} + +func (any *falseAny) ToUint32() uint32 { + return 0 +} + +func (any *falseAny) ToUint64() uint64 { + return 0 +} + +func (any *falseAny) ToFloat32() float32 { + return 0 +} + +func (any *falseAny) ToFloat64() float64 { + return 0 +} + +func (any *falseAny) ToString() string { + return "false" +} + +func (any *falseAny) WriteTo(stream *Stream) { + stream.WriteFalse() +} + +func (any *falseAny) Parse() *Iterator { + return nil +} + +func (any *falseAny) GetInterface() interface{} { + return false +} + +func (any *falseAny) ValueType() ValueType { + return BoolValue +} + +func (any *falseAny) MustBeValid() Any { + return any +} diff --git a/vendor/github.com/json-iterator/go/any_float.go b/vendor/github.com/json-iterator/go/any_float.go new file mode 100644 index 0000000000000000000000000000000000000000..35fdb09497fa86e5fbc84ad288cbfe8f012c9521 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_float.go @@ -0,0 +1,83 @@ +package jsoniter + +import ( + "strconv" +) + +type floatAny struct { + baseAny + val float64 +} + +func (any *floatAny) Parse() *Iterator { + return nil +} + +func (any *floatAny) ValueType() ValueType { + return NumberValue +} + +func (any *floatAny) MustBeValid() Any { + return any +} + +func (any *floatAny) LastError() error { + return nil +} + +func (any *floatAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *floatAny) ToInt() int { + return int(any.val) +} + +func (any *floatAny) ToInt32() int32 { + return int32(any.val) +} + +func (any *floatAny) ToInt64() int64 { + return int64(any.val) +} + +func (any *floatAny) ToUint() uint { + if any.val > 0 { + return uint(any.val) + } + return 0 +} + +func (any *floatAny) ToUint32() uint32 { + if any.val > 0 { + return uint32(any.val) + } + return 0 +} + +func (any *floatAny) ToUint64() uint64 { + if any.val > 0 { + return uint64(any.val) + } + return 0 +} + +func (any *floatAny) ToFloat32() float32 { + return float32(any.val) +} + +func (any *floatAny) ToFloat64() float64 { + return any.val +} + +func (any *floatAny) ToString() string { + return strconv.FormatFloat(any.val, 'E', -1, 64) +} + +func (any *floatAny) WriteTo(stream *Stream) { + stream.WriteFloat64(any.val) +} + +func (any *floatAny) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_int32.go b/vendor/github.com/json-iterator/go/any_int32.go new file mode 100644 index 0000000000000000000000000000000000000000..1b56f399150d9c3012babf663da40b1e2ac3e939 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_int32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int32Any struct { + baseAny + val int32 +} + +func (any *int32Any) LastError() error { + return nil +} + +func (any *int32Any) ValueType() ValueType { + return NumberValue +} + +func (any *int32Any) MustBeValid() Any { + return any +} + +func (any *int32Any) ToBool() bool { + return any.val != 0 +} + +func (any *int32Any) ToInt() int { + return int(any.val) +} + +func (any *int32Any) ToInt32() int32 { + return any.val +} + +func (any *int32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *int32Any) ToUint() uint { + return uint(any.val) +} + +func (any *int32Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *int32Any) WriteTo(stream *Stream) { + stream.WriteInt32(any.val) +} + +func (any *int32Any) Parse() *Iterator { + return nil +} + +func (any *int32Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_int64.go b/vendor/github.com/json-iterator/go/any_int64.go new file mode 100644 index 0000000000000000000000000000000000000000..c440d72b6d3ae1438fc92cd29e501ffac250e4e5 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_int64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int64Any struct { + baseAny + val int64 +} + +func (any *int64Any) LastError() error { + return nil +} + +func (any *int64Any) ValueType() ValueType { + return NumberValue +} + +func (any *int64Any) MustBeValid() Any { + return any +} + +func (any *int64Any) ToBool() bool { + return any.val != 0 +} + +func (any *int64Any) ToInt() int { + return int(any.val) +} + +func (any *int64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *int64Any) ToInt64() int64 { + return any.val +} + +func (any *int64Any) ToUint() uint { + return uint(any.val) +} + +func (any *int64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int64Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int64Any) ToString() string { + return strconv.FormatInt(any.val, 10) +} + +func (any *int64Any) WriteTo(stream *Stream) { + stream.WriteInt64(any.val) +} + +func (any *int64Any) Parse() *Iterator { + return nil +} + +func (any *int64Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_invalid.go b/vendor/github.com/json-iterator/go/any_invalid.go new file mode 100644 index 0000000000000000000000000000000000000000..1d859eac3274a44b956e5d559cb1ed2dd8843ae1 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_invalid.go @@ -0,0 +1,82 @@ +package jsoniter + +import "fmt" + +type invalidAny struct { + baseAny + err error +} + +func newInvalidAny(path []interface{}) *invalidAny { + return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)} +} + +func (any *invalidAny) LastError() error { + return any.err +} + +func (any *invalidAny) ValueType() ValueType { + return InvalidValue +} + +func (any *invalidAny) MustBeValid() Any { + panic(any.err) +} + +func (any *invalidAny) ToBool() bool { + return false +} + +func (any *invalidAny) ToInt() int { + return 0 +} + +func (any *invalidAny) ToInt32() int32 { + return 0 +} + +func (any *invalidAny) ToInt64() int64 { + return 0 +} + +func (any *invalidAny) ToUint() uint { + return 0 +} + +func (any *invalidAny) ToUint32() uint32 { + return 0 +} + +func (any *invalidAny) ToUint64() uint64 { + return 0 +} + +func (any *invalidAny) ToFloat32() float32 { + return 0 +} + +func (any *invalidAny) ToFloat64() float64 { + return 0 +} + +func (any *invalidAny) ToString() string { + return "" +} + +func (any *invalidAny) WriteTo(stream *Stream) { +} + +func (any *invalidAny) Get(path ...interface{}) Any { + if any.err == nil { + return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)} + } + return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)} +} + +func (any *invalidAny) Parse() *Iterator { + return nil +} + +func (any *invalidAny) GetInterface() interface{} { + return nil +} diff --git a/vendor/github.com/json-iterator/go/any_nil.go b/vendor/github.com/json-iterator/go/any_nil.go new file mode 100644 index 0000000000000000000000000000000000000000..d04cb54c11c1e57eb1d9cd820b00f402c9ed5c3c --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_nil.go @@ -0,0 +1,69 @@ +package jsoniter + +type nilAny struct { + baseAny +} + +func (any *nilAny) LastError() error { + return nil +} + +func (any *nilAny) ValueType() ValueType { + return NilValue +} + +func (any *nilAny) MustBeValid() Any { + return any +} + +func (any *nilAny) ToBool() bool { + return false +} + +func (any *nilAny) ToInt() int { + return 0 +} + +func (any *nilAny) ToInt32() int32 { + return 0 +} + +func (any *nilAny) ToInt64() int64 { + return 0 +} + +func (any *nilAny) ToUint() uint { + return 0 +} + +func (any *nilAny) ToUint32() uint32 { + return 0 +} + +func (any *nilAny) ToUint64() uint64 { + return 0 +} + +func (any *nilAny) ToFloat32() float32 { + return 0 +} + +func (any *nilAny) ToFloat64() float64 { + return 0 +} + +func (any *nilAny) ToString() string { + return "" +} + +func (any *nilAny) WriteTo(stream *Stream) { + stream.WriteNil() +} + +func (any *nilAny) Parse() *Iterator { + return nil +} + +func (any *nilAny) GetInterface() interface{} { + return nil +} diff --git a/vendor/github.com/json-iterator/go/any_number.go b/vendor/github.com/json-iterator/go/any_number.go new file mode 100644 index 0000000000000000000000000000000000000000..9d1e901a66ad36f15646eebbdfde5f80fae5a6b8 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_number.go @@ -0,0 +1,123 @@ +package jsoniter + +import ( + "io" + "unsafe" +) + +type numberLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *numberLazyAny) ValueType() ValueType { + return NumberValue +} + +func (any *numberLazyAny) MustBeValid() Any { + return any +} + +func (any *numberLazyAny) LastError() error { + return any.err +} + +func (any *numberLazyAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *numberLazyAny) ToInt() int { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToInt32() int32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToInt64() int64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint() uint { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint32() uint32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint64() uint64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToFloat32() float32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToFloat64() float64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *numberLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *numberLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} diff --git a/vendor/github.com/json-iterator/go/any_object.go b/vendor/github.com/json-iterator/go/any_object.go new file mode 100644 index 0000000000000000000000000000000000000000..c44ef5c989a46a629432c809faed5f77c0b676b8 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_object.go @@ -0,0 +1,374 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type objectLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *objectLazyAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectLazyAny) MustBeValid() Any { + return any +} + +func (any *objectLazyAny) LastError() error { + return any.err +} + +func (any *objectLazyAny) ToBool() bool { + return true +} + +func (any *objectLazyAny) ToInt() int { + return 0 +} + +func (any *objectLazyAny) ToInt32() int32 { + return 0 +} + +func (any *objectLazyAny) ToInt64() int64 { + return 0 +} + +func (any *objectLazyAny) ToUint() uint { + return 0 +} + +func (any *objectLazyAny) ToUint32() uint32 { + return 0 +} + +func (any *objectLazyAny) ToUint64() uint64 { + return 0 +} + +func (any *objectLazyAny) ToFloat32() float32 { + return 0 +} + +func (any *objectLazyAny) ToFloat64() float64 { + return 0 +} + +func (any *objectLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *objectLazyAny) ToVal(obj interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(obj) +} + +func (any *objectLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateObjectField(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + mapped := locatePath(iter, path[1:]) + if mapped.ValueType() != InvalidValue { + mappedAll[field] = mapped + } + return true + }) + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectLazyAny) Keys() []string { + keys := []string{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + iter.Skip() + keys = append(keys, field) + return true + }) + return keys +} + +func (any *objectLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + size++ + return true + }) + return size +} + +func (any *objectLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *objectLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type objectAny struct { + baseAny + err error + val reflect.Value +} + +func wrapStruct(val interface{}) *objectAny { + return &objectAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *objectAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectAny) MustBeValid() Any { + return any +} + +func (any *objectAny) Parse() *Iterator { + return nil +} + +func (any *objectAny) LastError() error { + return any.err +} + +func (any *objectAny) ToBool() bool { + return any.val.NumField() != 0 +} + +func (any *objectAny) ToInt() int { + return 0 +} + +func (any *objectAny) ToInt32() int32 { + return 0 +} + +func (any *objectAny) ToInt64() int64 { + return 0 +} + +func (any *objectAny) ToUint() uint { + return 0 +} + +func (any *objectAny) ToUint32() uint32 { + return 0 +} + +func (any *objectAny) ToUint64() uint64 { + return 0 +} + +func (any *objectAny) ToFloat32() float32 { + return 0 +} + +func (any *objectAny) ToFloat64() float64 { + return 0 +} + +func (any *objectAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *objectAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + field := any.val.FieldByName(firstPath) + if !field.IsValid() { + return newInvalidAny(path) + } + return Wrap(field.Interface()) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for i := 0; i < any.val.NumField(); i++ { + field := any.val.Field(i) + if field.CanInterface() { + mapped := Wrap(field.Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[any.val.Type().Field(i).Name] = mapped + } + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectAny) Keys() []string { + keys := make([]string, 0, any.val.NumField()) + for i := 0; i < any.val.NumField(); i++ { + keys = append(keys, any.val.Type().Field(i).Name) + } + return keys +} + +func (any *objectAny) Size() int { + return any.val.NumField() +} + +func (any *objectAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *objectAny) GetInterface() interface{} { + return any.val.Interface() +} + +type mapAny struct { + baseAny + err error + val reflect.Value +} + +func wrapMap(val interface{}) *mapAny { + return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *mapAny) ValueType() ValueType { + return ObjectValue +} + +func (any *mapAny) MustBeValid() Any { + return any +} + +func (any *mapAny) Parse() *Iterator { + return nil +} + +func (any *mapAny) LastError() error { + return any.err +} + +func (any *mapAny) ToBool() bool { + return true +} + +func (any *mapAny) ToInt() int { + return 0 +} + +func (any *mapAny) ToInt32() int32 { + return 0 +} + +func (any *mapAny) ToInt64() int64 { + return 0 +} + +func (any *mapAny) ToUint() uint { + return 0 +} + +func (any *mapAny) ToUint32() uint32 { + return 0 +} + +func (any *mapAny) ToUint64() uint64 { + return 0 +} + +func (any *mapAny) ToFloat32() float32 { + return 0 +} + +func (any *mapAny) ToFloat64() float64 { + return 0 +} + +func (any *mapAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *mapAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for _, key := range any.val.MapKeys() { + keyAsStr := key.String() + element := Wrap(any.val.MapIndex(key).Interface()) + mapped := element.Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[keyAsStr] = mapped + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + value := any.val.MapIndex(reflect.ValueOf(firstPath)) + if !value.IsValid() { + return newInvalidAny(path) + } + return Wrap(value.Interface()) + } +} + +func (any *mapAny) Keys() []string { + keys := make([]string, 0, any.val.Len()) + for _, key := range any.val.MapKeys() { + keys = append(keys, key.String()) + } + return keys +} + +func (any *mapAny) Size() int { + return any.val.Len() +} + +func (any *mapAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *mapAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/vendor/github.com/json-iterator/go/any_str.go b/vendor/github.com/json-iterator/go/any_str.go new file mode 100644 index 0000000000000000000000000000000000000000..1f12f6612de98255335e5dccf6200355ef27363f --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_str.go @@ -0,0 +1,166 @@ +package jsoniter + +import ( + "fmt" + "strconv" +) + +type stringAny struct { + baseAny + val string +} + +func (any *stringAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} +} + +func (any *stringAny) Parse() *Iterator { + return nil +} + +func (any *stringAny) ValueType() ValueType { + return StringValue +} + +func (any *stringAny) MustBeValid() Any { + return any +} + +func (any *stringAny) LastError() error { + return nil +} + +func (any *stringAny) ToBool() bool { + str := any.ToString() + if str == "0" { + return false + } + for _, c := range str { + switch c { + case ' ', '\n', '\r', '\t': + default: + return true + } + } + return false +} + +func (any *stringAny) ToInt() int { + return int(any.ToInt64()) + +} + +func (any *stringAny) ToInt32() int32 { + return int32(any.ToInt64()) +} + +func (any *stringAny) ToInt64() int64 { + if any.val == "" { + return 0 + } + + flag := 1 + startPos := 0 + if any.val[0] == '+' || any.val[0] == '-' { + startPos = 1 + } + + if any.val[0] == '-' { + flag = -1 + } + + endPos := startPos + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) + return int64(flag) * parsed +} + +func (any *stringAny) ToUint() uint { + return uint(any.ToUint64()) +} + +func (any *stringAny) ToUint32() uint32 { + return uint32(any.ToUint64()) +} + +func (any *stringAny) ToUint64() uint64 { + if any.val == "" { + return 0 + } + + startPos := 0 + + if any.val[0] == '-' { + return 0 + } + if any.val[0] == '+' { + startPos = 1 + } + + endPos := startPos + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) + return parsed +} + +func (any *stringAny) ToFloat32() float32 { + return float32(any.ToFloat64()) +} + +func (any *stringAny) ToFloat64() float64 { + if len(any.val) == 0 { + return 0 + } + + // first char invalid + if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') { + return 0 + } + + // extract valid num expression from string + // eg 123true => 123, -12.12xxa => -12.12 + endPos := 1 + for i := 1; i < len(any.val); i++ { + if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' { + endPos = i + 1 + continue + } + + // end position is the first char which is not digit + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + endPos = i + break + } + } + parsed, _ := strconv.ParseFloat(any.val[:endPos], 64) + return parsed +} + +func (any *stringAny) ToString() string { + return any.val +} + +func (any *stringAny) WriteTo(stream *Stream) { + stream.WriteString(any.val) +} + +func (any *stringAny) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_uint32.go b/vendor/github.com/json-iterator/go/any_uint32.go new file mode 100644 index 0000000000000000000000000000000000000000..656bbd33d7ee9d7dcd153603a21c66851bc19511 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_uint32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint32Any struct { + baseAny + val uint32 +} + +func (any *uint32Any) LastError() error { + return nil +} + +func (any *uint32Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint32Any) MustBeValid() Any { + return any +} + +func (any *uint32Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint32Any) ToInt() int { + return int(any.val) +} + +func (any *uint32Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint32Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint32Any) ToUint32() uint32 { + return any.val +} + +func (any *uint32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *uint32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *uint32Any) WriteTo(stream *Stream) { + stream.WriteUint32(any.val) +} + +func (any *uint32Any) Parse() *Iterator { + return nil +} + +func (any *uint32Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_uint64.go b/vendor/github.com/json-iterator/go/any_uint64.go new file mode 100644 index 0000000000000000000000000000000000000000..7df2fce33ba971b51129ce73359ca3c3038cfdee --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_uint64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint64Any struct { + baseAny + val uint64 +} + +func (any *uint64Any) LastError() error { + return nil +} + +func (any *uint64Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint64Any) MustBeValid() Any { + return any +} + +func (any *uint64Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint64Any) ToInt() int { + return int(any.val) +} + +func (any *uint64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint64Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint64Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *uint64Any) ToUint64() uint64 { + return any.val +} + +func (any *uint64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint64Any) ToString() string { + return strconv.FormatUint(any.val, 10) +} + +func (any *uint64Any) WriteTo(stream *Stream) { + stream.WriteUint64(any.val) +} + +func (any *uint64Any) Parse() *Iterator { + return nil +} + +func (any *uint64Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/build.sh b/vendor/github.com/json-iterator/go/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..b45ef688313ec5063cd21ac84ee5ed87d3849c38 --- /dev/null +++ b/vendor/github.com/json-iterator/go/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +set -x + +if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then + mkdir -p /tmp/build-golang/src/github.com/json-iterator + ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go +fi +export GOPATH=/tmp/build-golang +go get -u github.com/golang/dep/cmd/dep +cd /tmp/build-golang/src/github.com/json-iterator/go +exec $GOPATH/bin/dep ensure -update diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go new file mode 100644 index 0000000000000000000000000000000000000000..2adcdc3b790e53e4192655b15680a596a52449dd --- /dev/null +++ b/vendor/github.com/json-iterator/go/config.go @@ -0,0 +1,375 @@ +package jsoniter + +import ( + "encoding/json" + "io" + "reflect" + "sync" + "unsafe" + + "github.com/modern-go/concurrent" + "github.com/modern-go/reflect2" +) + +// Config customize how the API should behave. +// The API is created from Config by Froze. +type Config struct { + IndentionStep int + MarshalFloatWith6Digits bool + EscapeHTML bool + SortMapKeys bool + UseNumber bool + DisallowUnknownFields bool + TagKey string + OnlyTaggedField bool + ValidateJsonRawMessage bool + ObjectFieldMustBeSimpleString bool + CaseSensitive bool +} + +// API the public interface of this package. +// Primary Marshal and Unmarshal. +type API interface { + IteratorPool + StreamPool + MarshalToString(v interface{}) (string, error) + Marshal(v interface{}) ([]byte, error) + MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) + UnmarshalFromString(str string, v interface{}) error + Unmarshal(data []byte, v interface{}) error + Get(data []byte, path ...interface{}) Any + NewEncoder(writer io.Writer) *Encoder + NewDecoder(reader io.Reader) *Decoder + Valid(data []byte) bool + RegisterExtension(extension Extension) + DecoderOf(typ reflect2.Type) ValDecoder + EncoderOf(typ reflect2.Type) ValEncoder +} + +// ConfigDefault the default API +var ConfigDefault = Config{ + EscapeHTML: true, +}.Froze() + +// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior +var ConfigCompatibleWithStandardLibrary = Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, +}.Froze() + +// ConfigFastest marshals float with only 6 digits precision +var ConfigFastest = Config{ + EscapeHTML: false, + MarshalFloatWith6Digits: true, // will lose precession + ObjectFieldMustBeSimpleString: true, // do not unescape object field +}.Froze() + +type frozenConfig struct { + configBeforeFrozen Config + sortMapKeys bool + indentionStep int + objectFieldMustBeSimpleString bool + onlyTaggedField bool + disallowUnknownFields bool + decoderCache *concurrent.Map + encoderCache *concurrent.Map + encoderExtension Extension + decoderExtension Extension + extraExtensions []Extension + streamPool *sync.Pool + iteratorPool *sync.Pool + caseSensitive bool +} + +func (cfg *frozenConfig) initCache() { + cfg.decoderCache = concurrent.NewMap() + cfg.encoderCache = concurrent.NewMap() +} + +func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { + cfg.decoderCache.Store(cacheKey, decoder) +} + +func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { + cfg.encoderCache.Store(cacheKey, encoder) +} + +func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { + decoder, found := cfg.decoderCache.Load(cacheKey) + if found { + return decoder.(ValDecoder) + } + return nil +} + +func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { + encoder, found := cfg.encoderCache.Load(cacheKey) + if found { + return encoder.(ValEncoder) + } + return nil +} + +var cfgCache = concurrent.NewMap() + +func getFrozenConfigFromCache(cfg Config) *frozenConfig { + obj, found := cfgCache.Load(cfg) + if found { + return obj.(*frozenConfig) + } + return nil +} + +func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { + cfgCache.Store(cfg, frozenConfig) +} + +// Froze forge API from config +func (cfg Config) Froze() API { + api := &frozenConfig{ + sortMapKeys: cfg.SortMapKeys, + indentionStep: cfg.IndentionStep, + objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, + onlyTaggedField: cfg.OnlyTaggedField, + disallowUnknownFields: cfg.DisallowUnknownFields, + caseSensitive: cfg.CaseSensitive, + } + api.streamPool = &sync.Pool{ + New: func() interface{} { + return NewStream(api, nil, 512) + }, + } + api.iteratorPool = &sync.Pool{ + New: func() interface{} { + return NewIterator(api) + }, + } + api.initCache() + encoderExtension := EncoderExtension{} + decoderExtension := DecoderExtension{} + if cfg.MarshalFloatWith6Digits { + api.marshalFloatWith6Digits(encoderExtension) + } + if cfg.EscapeHTML { + api.escapeHTML(encoderExtension) + } + if cfg.UseNumber { + api.useNumber(decoderExtension) + } + if cfg.ValidateJsonRawMessage { + api.validateJsonRawMessage(encoderExtension) + } + api.encoderExtension = encoderExtension + api.decoderExtension = decoderExtension + api.configBeforeFrozen = cfg + return api +} + +func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig { + api := getFrozenConfigFromCache(cfg) + if api != nil { + return api + } + api = cfg.Froze().(*frozenConfig) + for _, extension := range extraExtensions { + api.RegisterExtension(extension) + } + addFrozenConfigToCache(cfg, api) + return api +} + +func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) { + encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) { + rawMessage := *(*json.RawMessage)(ptr) + iter := cfg.BorrowIterator([]byte(rawMessage)) + defer cfg.ReturnIterator(iter) + iter.Read() + if iter.Error != nil && iter.Error != io.EOF { + stream.WriteRaw("null") + } else { + stream.WriteRaw(string(rawMessage)) + } + }, func(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 + }} + extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder + extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder +} + +func (cfg *frozenConfig) useNumber(extension DecoderExtension) { + extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { + exitingValue := *((*interface{})(ptr)) + if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr { + iter.ReadVal(exitingValue) + return + } + if iter.WhatIsNext() == NumberValue { + *((*interface{})(ptr)) = json.Number(iter.readNumberAsString()) + } else { + *((*interface{})(ptr)) = iter.Read() + } + }} +} +func (cfg *frozenConfig) getTagKey() string { + tagKey := cfg.configBeforeFrozen.TagKey + if tagKey == "" { + return "json" + } + return tagKey +} + +func (cfg *frozenConfig) RegisterExtension(extension Extension) { + cfg.extraExtensions = append(cfg.extraExtensions, extension) + copied := cfg.configBeforeFrozen + cfg.configBeforeFrozen = copied +} + +type lossyFloat32Encoder struct { +} + +func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32Lossy(*((*float32)(ptr))) +} + +func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type lossyFloat64Encoder struct { +} + +func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64Lossy(*((*float64)(ptr))) +} + +func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +// EnableLossyFloatMarshalling keeps 10**(-6) precision +// for float variables for better performance. +func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) { + // for better performance + extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{} + extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{} +} + +type htmlEscapedStringEncoder struct { +} + +func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteStringWithHTMLEscaped(str) +} + +func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) { + encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{} +} + +func (cfg *frozenConfig) cleanDecoders() { + typeDecoders = map[string]ValDecoder{} + fieldDecoders = map[string]ValDecoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) cleanEncoders() { + typeEncoders = map[string]ValEncoder{} + fieldEncoders = map[string]ValEncoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return "", stream.Error + } + return string(stream.Buffer()), nil +} + +func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return nil, stream.Error + } + result := stream.Buffer() + copied := make([]byte, len(result)) + copy(copied, result) + return copied, nil +} + +func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + if prefix != "" { + panic("prefix is not supported") + } + for _, r := range indent { + if r != ' ' { + panic("indent can only be space") + } + } + newCfg := cfg.configBeforeFrozen + newCfg.IndentionStep = len(indent) + return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v) +} + +func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error { + data := []byte(str) + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + c := iter.nextToken() + if c == 0 { + if iter.Error == io.EOF { + return nil + } + return iter.Error + } + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + return iter.Error +} + +func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + return locatePath(iter, path) +} + +func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + c := iter.nextToken() + if c == 0 { + if iter.Error == io.EOF { + return nil + } + return iter.Error + } + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + return iter.Error +} + +func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder { + stream := NewStream(cfg, writer, 512) + return &Encoder{stream} +} + +func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder { + iter := Parse(cfg, reader, 512) + return &Decoder{iter} +} + +func (cfg *frozenConfig) Valid(data []byte) bool { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.Skip() + return iter.Error == nil +} diff --git a/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md new file mode 100644 index 0000000000000000000000000000000000000000..3095662b0610038098235c19a7a5b13dd12dd4be --- /dev/null +++ b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md @@ -0,0 +1,7 @@ +| json type \ dest type | bool | int | uint | float |string| +| --- | --- | --- | --- |--|--| +| number | positive => true <br/> negative => true <br/> zero => false| 23.2 => 23 <br/> -32.1 => -32| 12.1 => 12 <br/> -12.1 => 0|as normal|same as origin| +| string | empty string => false <br/> string "0" => false <br/> other strings => true | "123.32" => 123 <br/> "-123.4" => -123 <br/> "123.23xxxw" => 123 <br/> "abcde12" => 0 <br/> "-32.1" => -32| 13.2 => 13 <br/> -1.1 => 0 |12.1 => 12.1 <br/> -12.3 => -12.3<br/> 12.4xxa => 12.4 <br/> +1.1e2 =>110 |same as origin| +| bool | true => true <br/> false => false| true => 1 <br/> false => 0 | true => 1 <br/> false => 0 |true => 1 <br/>false => 0|true => "true" <br/> false => "false"| +| object | true | 0 | 0 |0|originnal json| +| array | empty array => false <br/> nonempty array => true| [] => 0 <br/> [1,2] => 1 | [] => 0 <br/> [1,2] => 1 |[] => 0<br/>[1,2] => 1|original json| \ No newline at end of file diff --git a/vendor/github.com/json-iterator/go/go.mod b/vendor/github.com/json-iterator/go/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..e05c42ff58b81e732a64404e08245a5976ed6b04 --- /dev/null +++ b/vendor/github.com/json-iterator/go/go.mod @@ -0,0 +1,11 @@ +module github.com/json-iterator/go + +go 1.12 + +require ( + github.com/davecgh/go-spew v1.1.1 + github.com/google/gofuzz v1.0.0 + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 + github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 + github.com/stretchr/testify v1.3.0 +) diff --git a/vendor/github.com/json-iterator/go/go.sum b/vendor/github.com/json-iterator/go/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..d778b5a14d633272aa571ca87ea595fbac09fe95 --- /dev/null +++ b/vendor/github.com/json-iterator/go/go.sum @@ -0,0 +1,14 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/vendor/github.com/json-iterator/go/iter.go b/vendor/github.com/json-iterator/go/iter.go new file mode 100644 index 0000000000000000000000000000000000000000..29b31cf78950654b3478784fda9d024212db75ff --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter.go @@ -0,0 +1,349 @@ +package jsoniter + +import ( + "encoding/json" + "fmt" + "io" +) + +// ValueType the type for JSON element +type ValueType int + +const ( + // InvalidValue invalid JSON element + InvalidValue ValueType = iota + // StringValue JSON element "string" + StringValue + // NumberValue JSON element 100 or 0.10 + NumberValue + // NilValue JSON element null + NilValue + // BoolValue JSON element true or false + BoolValue + // ArrayValue JSON element [] + ArrayValue + // ObjectValue JSON element {} + ObjectValue +) + +var hexDigits []byte +var valueTypes []ValueType + +func init() { + hexDigits = make([]byte, 256) + for i := 0; i < len(hexDigits); i++ { + hexDigits[i] = 255 + } + for i := '0'; i <= '9'; i++ { + hexDigits[i] = byte(i - '0') + } + for i := 'a'; i <= 'f'; i++ { + hexDigits[i] = byte((i - 'a') + 10) + } + for i := 'A'; i <= 'F'; i++ { + hexDigits[i] = byte((i - 'A') + 10) + } + valueTypes = make([]ValueType, 256) + for i := 0; i < len(valueTypes); i++ { + valueTypes[i] = InvalidValue + } + valueTypes['"'] = StringValue + valueTypes['-'] = NumberValue + valueTypes['0'] = NumberValue + valueTypes['1'] = NumberValue + valueTypes['2'] = NumberValue + valueTypes['3'] = NumberValue + valueTypes['4'] = NumberValue + valueTypes['5'] = NumberValue + valueTypes['6'] = NumberValue + valueTypes['7'] = NumberValue + valueTypes['8'] = NumberValue + valueTypes['9'] = NumberValue + valueTypes['t'] = BoolValue + valueTypes['f'] = BoolValue + valueTypes['n'] = NilValue + valueTypes['['] = ArrayValue + valueTypes['{'] = ObjectValue +} + +// Iterator is a io.Reader like object, with JSON specific read functions. +// Error is not returned as return value, but stored as Error member on this iterator instance. +type Iterator struct { + cfg *frozenConfig + reader io.Reader + buf []byte + head int + tail int + depth int + captureStartedAt int + captured []byte + Error error + Attachment interface{} // open for customized decoder +} + +// NewIterator creates an empty Iterator instance +func NewIterator(cfg API) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: nil, + head: 0, + tail: 0, + depth: 0, + } +} + +// Parse creates an Iterator instance from io.Reader +func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: reader, + buf: make([]byte, bufSize), + head: 0, + tail: 0, + depth: 0, + } +} + +// ParseBytes creates an Iterator instance from byte array +func ParseBytes(cfg API, input []byte) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: input, + head: 0, + tail: len(input), + depth: 0, + } +} + +// ParseString creates an Iterator instance from string +func ParseString(cfg API, input string) *Iterator { + return ParseBytes(cfg, []byte(input)) +} + +// Pool returns a pool can provide more iterator with same configuration +func (iter *Iterator) Pool() IteratorPool { + return iter.cfg +} + +// Reset reuse iterator instance by specifying another reader +func (iter *Iterator) Reset(reader io.Reader) *Iterator { + iter.reader = reader + iter.head = 0 + iter.tail = 0 + iter.depth = 0 + return iter +} + +// ResetBytes reuse iterator instance by specifying another byte array as input +func (iter *Iterator) ResetBytes(input []byte) *Iterator { + iter.reader = nil + iter.buf = input + iter.head = 0 + iter.tail = len(input) + iter.depth = 0 + return iter +} + +// WhatIsNext gets ValueType of relatively next json element +func (iter *Iterator) WhatIsNext() ValueType { + valueType := valueTypes[iter.nextToken()] + iter.unreadByte() + return valueType +} + +func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + return false + } + return true +} + +func (iter *Iterator) isObjectEnd() bool { + c := iter.nextToken() + if c == ',' { + return false + } + if c == '}' { + return true + } + iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) + return true +} + +func (iter *Iterator) nextToken() byte { + // a variation of skip whitespaces, returning the next non-whitespace token + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + 1 + return c + } + if !iter.loadMore() { + return 0 + } + } +} + +// ReportError record a error in iterator instance with current position. +func (iter *Iterator) ReportError(operation string, msg string) { + if iter.Error != nil { + if iter.Error != io.EOF { + return + } + } + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + peekEnd := iter.head + 10 + if peekEnd > iter.tail { + peekEnd = iter.tail + } + parsing := string(iter.buf[peekStart:peekEnd]) + contextStart := iter.head - 50 + if contextStart < 0 { + contextStart = 0 + } + contextEnd := iter.head + 50 + if contextEnd > iter.tail { + contextEnd = iter.tail + } + context := string(iter.buf[contextStart:contextEnd]) + iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", + operation, msg, iter.head-peekStart, parsing, context) +} + +// CurrentBuffer gets current buffer as string for debugging purpose +func (iter *Iterator) CurrentBuffer() string { + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, + string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) +} + +func (iter *Iterator) readByte() (ret byte) { + if iter.head == iter.tail { + if iter.loadMore() { + ret = iter.buf[iter.head] + iter.head++ + return ret + } + return 0 + } + ret = iter.buf[iter.head] + iter.head++ + return ret +} + +func (iter *Iterator) loadMore() bool { + if iter.reader == nil { + if iter.Error == nil { + iter.head = iter.tail + iter.Error = io.EOF + } + return false + } + if iter.captured != nil { + iter.captured = append(iter.captured, + iter.buf[iter.captureStartedAt:iter.tail]...) + iter.captureStartedAt = 0 + } + for { + n, err := iter.reader.Read(iter.buf) + if n == 0 { + if err != nil { + if iter.Error == nil { + iter.Error = err + } + return false + } + } else { + iter.head = 0 + iter.tail = n + return true + } + } +} + +func (iter *Iterator) unreadByte() { + if iter.Error != nil { + return + } + iter.head-- + return +} + +// Read read the next JSON element as generic interface{}. +func (iter *Iterator) Read() interface{} { + valueType := iter.WhatIsNext() + switch valueType { + case StringValue: + return iter.ReadString() + case NumberValue: + if iter.cfg.configBeforeFrozen.UseNumber { + return json.Number(iter.readNumberAsString()) + } + return iter.ReadFloat64() + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + return nil + case BoolValue: + return iter.ReadBool() + case ArrayValue: + arr := []interface{}{} + iter.ReadArrayCB(func(iter *Iterator) bool { + var elem interface{} + iter.ReadVal(&elem) + arr = append(arr, elem) + return true + }) + return arr + case ObjectValue: + obj := map[string]interface{}{} + iter.ReadMapCB(func(Iter *Iterator, field string) bool { + var elem interface{} + iter.ReadVal(&elem) + obj[field] = elem + return true + }) + return obj + default: + iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType)) + return nil + } +} + +// limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9 +const maxDepth = 10000 + +func (iter *Iterator) incrementDepth() (success bool) { + iter.depth++ + if iter.depth <= maxDepth { + return true + } + iter.ReportError("incrementDepth", "exceeded max depth") + return false +} + +func (iter *Iterator) decrementDepth() (success bool) { + iter.depth-- + if iter.depth >= 0 { + return true + } + iter.ReportError("decrementDepth", "unexpected negative nesting") + return false +} diff --git a/vendor/github.com/json-iterator/go/iter_array.go b/vendor/github.com/json-iterator/go/iter_array.go new file mode 100644 index 0000000000000000000000000000000000000000..204fe0e0922aa0582eada026b3ee4af5f7cf25f7 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_array.go @@ -0,0 +1,64 @@ +package jsoniter + +// ReadArray read array element, tells if the array has more element to read. +func (iter *Iterator) ReadArray() (ret bool) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return false // null + case '[': + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + return true + } + return false + case ']': + return false + case ',': + return true + default: + iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) + return + } +} + +// ReadArrayCB read array with callback +func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { + c := iter.nextToken() + if c == '[' { + if !iter.incrementDepth() { + return false + } + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + if !callback(iter) { + iter.decrementDepth() + return false + } + c = iter.nextToken() + for c == ',' { + if !callback(iter) { + iter.decrementDepth() + return false + } + c = iter.nextToken() + } + if c != ']' { + iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) + iter.decrementDepth() + return false + } + return iter.decrementDepth() + } + return iter.decrementDepth() + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) + return false +} diff --git a/vendor/github.com/json-iterator/go/iter_float.go b/vendor/github.com/json-iterator/go/iter_float.go new file mode 100644 index 0000000000000000000000000000000000000000..b9754638e88866134d2020a54dfd4729c1ff663d --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_float.go @@ -0,0 +1,339 @@ +package jsoniter + +import ( + "encoding/json" + "io" + "math/big" + "strconv" + "strings" + "unsafe" +) + +var floatDigits []int8 + +const invalidCharForNumber = int8(-1) +const endOfNumber = int8(-2) +const dotInNumber = int8(-3) + +func init() { + floatDigits = make([]int8, 256) + for i := 0; i < len(floatDigits); i++ { + floatDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + floatDigits[i] = i - int8('0') + } + floatDigits[','] = endOfNumber + floatDigits[']'] = endOfNumber + floatDigits['}'] = endOfNumber + floatDigits[' '] = endOfNumber + floatDigits['\t'] = endOfNumber + floatDigits['\n'] = endOfNumber + floatDigits['.'] = dotInNumber +} + +// ReadBigFloat read big.Float +func (iter *Iterator) ReadBigFloat() (ret *big.Float) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + prec := 64 + if len(str) > prec { + prec = len(str) + } + val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) + if err != nil { + iter.Error = err + return nil + } + return val +} + +// ReadBigInt read big.Int +func (iter *Iterator) ReadBigInt() (ret *big.Int) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + ret = big.NewInt(0) + var success bool + ret, success = ret.SetString(str, 10) + if !success { + iter.ReportError("ReadBigInt", "invalid big int") + return nil + } + return ret +} + +//ReadFloat32 read float32 +func (iter *Iterator) ReadFloat32() (ret float32) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat32() + } + iter.unreadByte() + return iter.readPositiveFloat32() +} + +func (iter *Iterator) readPositiveFloat32() (ret float32) { + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c := iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.ReportError("readFloat32", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat32", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat32", "leading zero is invalid") + return + } + } + value := uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.head = i + return float32(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat32SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float32(float64(value) / float64(pow10[decimalPlaces])) + } + // too many decimal places + return iter.readFloat32SlowPath() + case invalidCharForNumber, dotInNumber: + return iter.readFloat32SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat32SlowPath() +} + +func (iter *Iterator) readNumberAsString() (ret string) { + strBuf := [16]byte{} + str := strBuf[0:0] +load_loop: + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + str = append(str, c) + continue + default: + iter.head = i + break load_loop + } + } + if !iter.loadMore() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + return + } + if len(str) == 0 { + iter.ReportError("readNumberAsString", "invalid number") + } + return *(*string)(unsafe.Pointer(&str)) +} + +func (iter *Iterator) readFloat32SlowPath() (ret float32) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat32SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 32) + if err != nil { + iter.Error = err + return + } + return float32(val) +} + +// ReadFloat64 read float64 +func (iter *Iterator) ReadFloat64() (ret float64) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat64() + } + iter.unreadByte() + return iter.readPositiveFloat64() +} + +func (iter *Iterator) readPositiveFloat64() (ret float64) { + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c := iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.ReportError("readFloat64", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat64", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat64", "leading zero is invalid") + return + } + } + value := uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.head = i + return float64(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat64SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float64(value) / float64(pow10[decimalPlaces]) + } + // too many decimal places + return iter.readFloat64SlowPath() + case invalidCharForNumber, dotInNumber: + return iter.readFloat64SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat64SlowPath() +} + +func (iter *Iterator) readFloat64SlowPath() (ret float64) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat64SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 64) + if err != nil { + iter.Error = err + return + } + return val +} + +func validateFloat(str string) string { + // strconv.ParseFloat is not validating `1.` or `1.e1` + if len(str) == 0 { + return "empty number" + } + if str[0] == '-' { + return "-- is not valid" + } + dotPos := strings.IndexByte(str, '.') + if dotPos != -1 { + if dotPos == len(str)-1 { + return "dot can not be last character" + } + switch str[dotPos+1] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + return "missing digit after dot" + } + } + return "" +} + +// ReadNumber read json.Number +func (iter *Iterator) ReadNumber() (ret json.Number) { + return json.Number(iter.readNumberAsString()) +} diff --git a/vendor/github.com/json-iterator/go/iter_int.go b/vendor/github.com/json-iterator/go/iter_int.go new file mode 100644 index 0000000000000000000000000000000000000000..2142320355e873d5fdc7b104ec4a713b792bdf06 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_int.go @@ -0,0 +1,345 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var intDigits []int8 + +const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1 +const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1 + +func init() { + intDigits = make([]int8, 256) + for i := 0; i < len(intDigits); i++ { + intDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + intDigits[i] = i - int8('0') + } +} + +// ReadUint read uint +func (iter *Iterator) ReadUint() uint { + if strconv.IntSize == 32 { + return uint(iter.ReadUint32()) + } + return uint(iter.ReadUint64()) +} + +// ReadInt read int +func (iter *Iterator) ReadInt() int { + if strconv.IntSize == 32 { + return int(iter.ReadInt32()) + } + return int(iter.ReadInt64()) +} + +// ReadInt8 read int8 +func (iter *Iterator) ReadInt8() (ret int8) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt8+1 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int8(val) + } + val := iter.readUint32(c) + if val > math.MaxInt8 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int8(val) +} + +// ReadUint8 read uint8 +func (iter *Iterator) ReadUint8() (ret uint8) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint8 { + iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint8(val) +} + +// ReadInt16 read int16 +func (iter *Iterator) ReadInt16() (ret int16) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt16+1 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int16(val) + } + val := iter.readUint32(c) + if val > math.MaxInt16 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int16(val) +} + +// ReadUint16 read uint16 +func (iter *Iterator) ReadUint16() (ret uint16) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint16 { + iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint16(val) +} + +// ReadInt32 read int32 +func (iter *Iterator) ReadInt32() (ret int32) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt32+1 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int32(val) + } + val := iter.readUint32(c) + if val > math.MaxInt32 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int32(val) +} + +// ReadUint32 read uint32 +func (iter *Iterator) ReadUint32() (ret uint32) { + return iter.readUint32(iter.nextToken()) +} + +func (iter *Iterator) readUint32(c byte) (ret uint32) { + ind := intDigits[c] + if ind == 0 { + iter.assertInteger() + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint32(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint32(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint32(ind2)*10 + uint32(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + if value > uint32SafeToMultiply10 { + value2 := (value << 3) + (value << 1) + uint32(ind) + if value2 < value { + iter.ReportError("readUint32", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint32(ind) + } + if !iter.loadMore() { + iter.assertInteger() + return value + } + } +} + +// ReadInt64 read int64 +func (iter *Iterator) ReadInt64() (ret int64) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint64(iter.readByte()) + if val > math.MaxInt64+1 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return -int64(val) + } + val := iter.readUint64(c) + if val > math.MaxInt64 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return int64(val) +} + +// ReadUint64 read uint64 +func (iter *Iterator) ReadUint64() uint64 { + return iter.readUint64(iter.nextToken()) +} + +func (iter *Iterator) readUint64(c byte) (ret uint64) { + ind := intDigits[c] + if ind == 0 { + iter.assertInteger() + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint64(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint64(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint64(ind2)*10 + uint64(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + if value > uint64SafeToMultiple10 { + value2 := (value << 3) + (value << 1) + uint64(ind) + if value2 < value { + iter.ReportError("readUint64", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint64(ind) + } + if !iter.loadMore() { + iter.assertInteger() + return value + } + } +} + +func (iter *Iterator) assertInteger() { + if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' { + iter.ReportError("assertInteger", "can not decode float as int") + } +} diff --git a/vendor/github.com/json-iterator/go/iter_object.go b/vendor/github.com/json-iterator/go/iter_object.go new file mode 100644 index 0000000000000000000000000000000000000000..58ee89c849e7bbff01577ce657502f34b8125c85 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_object.go @@ -0,0 +1,267 @@ +package jsoniter + +import ( + "fmt" + "strings" +) + +// ReadObject read one field from object. +// If object ended, returns empty string. +// Otherwise, returns the field name. +func (iter *Iterator) ReadObject() (ret string) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return "" // null + case '{': + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + } + if c == '}' { + return "" // end of object + } + iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) + return + case ',': + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + case '}': + return "" // end of object + default: + iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) + return + } +} + +// CaseInsensitive +func (iter *Iterator) readFieldHash() int64 { + hash := int64(0x811c9dc5) + c := iter.nextToken() + if c != '"' { + iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) + return 0 + } + for { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + b := iter.buf[i] + if b == '\\' { + iter.head = i + for _, b := range iter.readStringSlowPath() { + if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash + } + if b == '"' { + iter.head = i + 1 + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash + } + if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + if !iter.loadMore() { + iter.ReportError("readFieldHash", `incomplete field name`) + return 0 + } + } +} + +func calcHash(str string, caseSensitive bool) int64 { + if !caseSensitive { + str = strings.ToLower(str) + } + hash := int64(0x811c9dc5) + for _, b := range []byte(str) { + hash ^= int64(b) + hash *= 0x1000193 + } + return int64(hash) +} + +// ReadObjectCB read object with callback, the key is ascii only and field name not copied +func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + var field string + if c == '{' { + if !iter.incrementDepth() { + return false + } + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + if !callback(iter, field) { + iter.decrementDepth() + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + if !callback(iter, field) { + iter.decrementDepth() + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadObjectCB", `object not ended with }`) + iter.decrementDepth() + return false + } + return iter.decrementDepth() + } + if c == '}' { + return iter.decrementDepth() + } + iter.ReportError("ReadObjectCB", `expect " after {, but found `+string([]byte{c})) + iter.decrementDepth() + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +// ReadMapCB read map with callback, the key can be any string +func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + if c == '{' { + if !iter.incrementDepth() { + return false + } + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + iter.decrementDepth() + return false + } + if !callback(iter, field) { + iter.decrementDepth() + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + iter.decrementDepth() + return false + } + if !callback(iter, field) { + iter.decrementDepth() + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadMapCB", `object not ended with }`) + iter.decrementDepth() + return false + } + return iter.decrementDepth() + } + if c == '}' { + return iter.decrementDepth() + } + iter.ReportError("ReadMapCB", `expect " after {, but found `+string([]byte{c})) + iter.decrementDepth() + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectStart() bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '}' { + return false + } + iter.unreadByte() + return true + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return false + } + iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { + str := iter.ReadStringAsSlice() + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if iter.buf[iter.head] != ':' { + iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) + return + } + iter.head++ + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if ret == nil { + return str + } + return ret +} diff --git a/vendor/github.com/json-iterator/go/iter_skip.go b/vendor/github.com/json-iterator/go/iter_skip.go new file mode 100644 index 0000000000000000000000000000000000000000..e91eefb15becf2fdd007fd3c992814d8c4e2cfa0 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip.go @@ -0,0 +1,130 @@ +package jsoniter + +import "fmt" + +// ReadNil reads a json object as nil and +// returns whether it's a nil or not +func (iter *Iterator) ReadNil() (ret bool) { + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') // null + return true + } + iter.unreadByte() + return false +} + +// ReadBool reads a json object as BoolValue +func (iter *Iterator) ReadBool() (ret bool) { + c := iter.nextToken() + if c == 't' { + iter.skipThreeBytes('r', 'u', 'e') + return true + } + if c == 'f' { + iter.skipFourBytes('a', 'l', 's', 'e') + return false + } + iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) + return +} + +// SkipAndReturnBytes skip next JSON element, and return its content as []byte. +// The []byte can be kept, it is a copy of data. +func (iter *Iterator) SkipAndReturnBytes() []byte { + iter.startCapture(iter.head) + iter.Skip() + return iter.stopCapture() +} + +// SkipAndAppendBytes skips next JSON element and appends its content to +// buffer, returning the result. +func (iter *Iterator) SkipAndAppendBytes(buf []byte) []byte { + iter.startCaptureTo(buf, iter.head) + iter.Skip() + return iter.stopCapture() +} + +func (iter *Iterator) startCaptureTo(buf []byte, captureStartedAt int) { + if iter.captured != nil { + panic("already in capture mode") + } + iter.captureStartedAt = captureStartedAt + iter.captured = buf +} + +func (iter *Iterator) startCapture(captureStartedAt int) { + iter.startCaptureTo(make([]byte, 0, 32), captureStartedAt) +} + +func (iter *Iterator) stopCapture() []byte { + if iter.captured == nil { + panic("not in capture mode") + } + captured := iter.captured + remaining := iter.buf[iter.captureStartedAt:iter.head] + iter.captureStartedAt = -1 + iter.captured = nil + return append(captured, remaining...) +} + +// Skip skips a json object and positions to relatively the next json object +func (iter *Iterator) Skip() { + c := iter.nextToken() + switch c { + case '"': + iter.skipString() + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + case '0': + iter.unreadByte() + iter.ReadFloat32() + case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.skipNumber() + case '[': + iter.skipArray() + case '{': + iter.skipObject() + default: + iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) + return + } +} + +func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b4 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } +} + +func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } +} diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go new file mode 100644 index 0000000000000000000000000000000000000000..9303de41e40050de20fd5256bad35932e038b930 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go @@ -0,0 +1,163 @@ +//+build jsoniter_sloppy + +package jsoniter + +// sloppy but faster implementation, do not validate the input json + +func (iter *Iterator) skipNumber() { + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\r', '\t', ',', '}', ']': + iter.head = i + return + } + } + if !iter.loadMore() { + return + } + } +} + +func (iter *Iterator) skipArray() { + level := 1 + if !iter.incrementDepth() { + return + } + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '[': // If open symbol, increase level + level++ + if !iter.incrementDepth() { + return + } + case ']': // If close symbol, increase level + level-- + if !iter.decrementDepth() { + return + } + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete array") + return + } + } +} + +func (iter *Iterator) skipObject() { + level := 1 + if !iter.incrementDepth() { + return + } + + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '{': // If open symbol, increase level + level++ + if !iter.incrementDepth() { + return + } + case '}': // If close symbol, increase level + level-- + if !iter.decrementDepth() { + return + } + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete object") + return + } + } +} + +func (iter *Iterator) skipString() { + for { + end, escaped := iter.findStringEnd() + if end == -1 { + if !iter.loadMore() { + iter.ReportError("skipString", "incomplete string") + return + } + if escaped { + iter.head = 1 // skip the first char as last char read is \ + } + } else { + iter.head = end + return + } + } +} + +// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go +// Tries to find the end of string +// Support if string contains escaped quote symbols. +func (iter *Iterator) findStringEnd() (int, bool) { + escaped := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + if !escaped { + return i + 1, false + } + j := i - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return i + 1, true + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + } + } else if c == '\\' { + escaped = true + } + } + j := iter.tail - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return -1, false // do not end with \ + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + + } + return -1, true // end with \ +} diff --git a/vendor/github.com/json-iterator/go/iter_skip_strict.go b/vendor/github.com/json-iterator/go/iter_skip_strict.go new file mode 100644 index 0000000000000000000000000000000000000000..6cf66d0438dbe20df79f41293919436a304f2f5c --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip_strict.go @@ -0,0 +1,99 @@ +//+build !jsoniter_sloppy + +package jsoniter + +import ( + "fmt" + "io" +) + +func (iter *Iterator) skipNumber() { + if !iter.trySkipNumber() { + iter.unreadByte() + if iter.Error != nil && iter.Error != io.EOF { + return + } + iter.ReadFloat64() + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = nil + iter.ReadBigFloat() + } + } +} + +func (iter *Iterator) trySkipNumber() bool { + dotFound := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + case '.': + if dotFound { + iter.ReportError("validateNumber", `more than one dot found in number`) + return true // already failed + } + if i+1 == iter.tail { + return false + } + c = iter.buf[i+1] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + iter.ReportError("validateNumber", `missing digit after dot`) + return true // already failed + } + dotFound = true + default: + switch c { + case ',', ']', '}', ' ', '\t', '\n', '\r': + if iter.head == i { + return false // if - without following digits + } + iter.head = i + return true // must be valid + } + return false // may be invalid + } + } + return false +} + +func (iter *Iterator) skipString() { + if !iter.trySkipString() { + iter.unreadByte() + iter.ReadString() + } +} + +func (iter *Iterator) trySkipString() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + iter.head = i + 1 + return true // valid + } else if c == '\\' { + return false + } else if c < ' ' { + iter.ReportError("trySkipString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return true // already failed + } + } + return false +} + +func (iter *Iterator) skipObject() { + iter.unreadByte() + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + return true + }) +} + +func (iter *Iterator) skipArray() { + iter.unreadByte() + iter.ReadArrayCB(func(iter *Iterator) bool { + iter.Skip() + return true + }) +} diff --git a/vendor/github.com/json-iterator/go/iter_str.go b/vendor/github.com/json-iterator/go/iter_str.go new file mode 100644 index 0000000000000000000000000000000000000000..adc487ea80483cbc892f0438c3133705cbcb46cd --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_str.go @@ -0,0 +1,215 @@ +package jsoniter + +import ( + "fmt" + "unicode/utf16" +) + +// ReadString read string from iterator +func (iter *Iterator) ReadString() (ret string) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + ret = string(iter.buf[iter.head:i]) + iter.head = i + 1 + return ret + } else if c == '\\' { + break + } else if c < ' ' { + iter.ReportError("ReadString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return + } + } + return iter.readStringSlowPath() + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return "" + } + iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readStringSlowPath() (ret string) { + var str []byte + var c byte + for iter.Error == nil { + c = iter.readByte() + if c == '"' { + return string(str) + } + if c == '\\' { + c = iter.readByte() + str = iter.readEscapedChar(c, str) + } else { + str = append(str, c) + } + } + iter.ReportError("readStringSlowPath", "unexpected end of input") + return +} + +func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { + switch c { + case 'u': + r := iter.readU4() + if utf16.IsSurrogate(r) { + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != '\\' { + iter.unreadByte() + str = appendRune(str, r) + return str + } + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != 'u' { + str = appendRune(str, r) + return iter.readEscapedChar(c, str) + } + r2 := iter.readU4() + if iter.Error != nil { + return nil + } + combined := utf16.DecodeRune(r, r2) + if combined == '\uFFFD' { + str = appendRune(str, r) + str = appendRune(str, r2) + } else { + str = appendRune(str, combined) + } + } else { + str = appendRune(str, r) + } + case '"': + str = append(str, '"') + case '\\': + str = append(str, '\\') + case '/': + str = append(str, '/') + case 'b': + str = append(str, '\b') + case 'f': + str = append(str, '\f') + case 'n': + str = append(str, '\n') + case 'r': + str = append(str, '\r') + case 't': + str = append(str, '\t') + default: + iter.ReportError("readEscapedChar", + `invalid escape char after \`) + return nil + } + return str +} + +// ReadStringAsSlice read string from iterator without copying into string form. +// The []byte can not be kept, as it will change after next iterator call. +func (iter *Iterator) ReadStringAsSlice() (ret []byte) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + // for: field name, base64, number + if iter.buf[i] == '"' { + // fast path: reuse the underlying buffer + ret = iter.buf[iter.head:i] + iter.head = i + 1 + return ret + } + } + readLen := iter.tail - iter.head + copied := make([]byte, readLen, readLen*2) + copy(copied, iter.buf[iter.head:iter.tail]) + iter.head = iter.tail + for iter.Error == nil { + c := iter.readByte() + if c == '"' { + return copied + } + copied = append(copied, c) + } + return copied + } + iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readU4() (ret rune) { + for i := 0; i < 4; i++ { + c := iter.readByte() + if iter.Error != nil { + return + } + if c >= '0' && c <= '9' { + ret = ret*16 + rune(c-'0') + } else if c >= 'a' && c <= 'f' { + ret = ret*16 + rune(c-'a'+10) + } else if c >= 'A' && c <= 'F' { + ret = ret*16 + rune(c-'A'+10) + } else { + iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) + return + } + } + return ret +} + +const ( + t1 = 0x00 // 0000 0000 + tx = 0x80 // 1000 0000 + t2 = 0xC0 // 1100 0000 + t3 = 0xE0 // 1110 0000 + t4 = 0xF0 // 1111 0000 + t5 = 0xF8 // 1111 1000 + + maskx = 0x3F // 0011 1111 + mask2 = 0x1F // 0001 1111 + mask3 = 0x0F // 0000 1111 + mask4 = 0x07 // 0000 0111 + + rune1Max = 1<<7 - 1 + rune2Max = 1<<11 - 1 + rune3Max = 1<<16 - 1 + + surrogateMin = 0xD800 + surrogateMax = 0xDFFF + + maxRune = '\U0010FFFF' // Maximum valid Unicode code point. + runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character" +) + +func appendRune(p []byte, r rune) []byte { + // Negative values are erroneous. Making it unsigned addresses the problem. + switch i := uint32(r); { + case i <= rune1Max: + p = append(p, byte(r)) + return p + case i <= rune2Max: + p = append(p, t2|byte(r>>6)) + p = append(p, tx|byte(r)&maskx) + return p + case i > maxRune, surrogateMin <= i && i <= surrogateMax: + r = runeError + fallthrough + case i <= rune3Max: + p = append(p, t3|byte(r>>12)) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + default: + p = append(p, t4|byte(r>>18)) + p = append(p, tx|byte(r>>12)&maskx) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + } +} diff --git a/vendor/github.com/json-iterator/go/jsoniter.go b/vendor/github.com/json-iterator/go/jsoniter.go new file mode 100644 index 0000000000000000000000000000000000000000..c2934f916eb3031985b3e4c9ccc238cb5ec182fa --- /dev/null +++ b/vendor/github.com/json-iterator/go/jsoniter.go @@ -0,0 +1,18 @@ +// Package jsoniter implements encoding and decoding of JSON as defined in +// RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. +// Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter +// and variable type declarations (if any). +// jsoniter interfaces gives 100% compatibility with code using standard lib. +// +// "JSON and Go" +// (https://golang.org/doc/articles/json_and_go.html) +// gives a description of how Marshal/Unmarshal operate +// between arbitrary or predefined json objects and bytes, +// and it applies to jsoniter.Marshal/Unmarshal as well. +// +// Besides, jsoniter.Iterator provides a different set of interfaces +// iterating given bytes/string/reader +// and yielding parsed elements one by one. +// This set of interfaces reads input as required and gives +// better performance. +package jsoniter diff --git a/vendor/github.com/json-iterator/go/pool.go b/vendor/github.com/json-iterator/go/pool.go new file mode 100644 index 0000000000000000000000000000000000000000..e2389b56cfff3ce31c878ef99a4a55471d2dc53b --- /dev/null +++ b/vendor/github.com/json-iterator/go/pool.go @@ -0,0 +1,42 @@ +package jsoniter + +import ( + "io" +) + +// IteratorPool a thread safe pool of iterators with same configuration +type IteratorPool interface { + BorrowIterator(data []byte) *Iterator + ReturnIterator(iter *Iterator) +} + +// StreamPool a thread safe pool of streams with same configuration +type StreamPool interface { + BorrowStream(writer io.Writer) *Stream + ReturnStream(stream *Stream) +} + +func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { + stream := cfg.streamPool.Get().(*Stream) + stream.Reset(writer) + return stream +} + +func (cfg *frozenConfig) ReturnStream(stream *Stream) { + stream.out = nil + stream.Error = nil + stream.Attachment = nil + cfg.streamPool.Put(stream) +} + +func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { + iter := cfg.iteratorPool.Get().(*Iterator) + iter.ResetBytes(data) + return iter +} + +func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { + iter.Error = nil + iter.Attachment = nil + cfg.iteratorPool.Put(iter) +} diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go new file mode 100644 index 0000000000000000000000000000000000000000..74974ba74b067927174fed4aa073ac61f6158c29 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect.go @@ -0,0 +1,337 @@ +package jsoniter + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/modern-go/reflect2" +) + +// ValDecoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValDecoder with json.Decoder. +// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). +// +// Reflection on type to create decoders, which is then cached +// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions +// 1. create instance of new value, for example *int will need a int to be allocated +// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New +// 3. assignment to map, both key and value will be reflect.Value +// For a simple struct binding, it will be reflect.Value free and allocation free +type ValDecoder interface { + Decode(ptr unsafe.Pointer, iter *Iterator) +} + +// ValEncoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValEncoder with json.Encoder. +// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). +type ValEncoder interface { + IsEmpty(ptr unsafe.Pointer) bool + Encode(ptr unsafe.Pointer, stream *Stream) +} + +type checkIsEmpty interface { + IsEmpty(ptr unsafe.Pointer) bool +} + +type ctx struct { + *frozenConfig + prefix string + encoders map[reflect2.Type]ValEncoder + decoders map[reflect2.Type]ValDecoder +} + +func (b *ctx) caseSensitive() bool { + if b.frozenConfig == nil { + // default is case-insensitive + return false + } + return b.frozenConfig.caseSensitive +} + +func (b *ctx) append(prefix string) *ctx { + return &ctx{ + frozenConfig: b.frozenConfig, + prefix: b.prefix + " " + prefix, + encoders: b.encoders, + decoders: b.decoders, + } +} + +// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal +func (iter *Iterator) ReadVal(obj interface{}) { + depth := iter.depth + cacheKey := reflect2.RTypeOf(obj) + decoder := iter.cfg.getDecoderFromCache(cacheKey) + if decoder == nil { + typ := reflect2.TypeOf(obj) + if typ.Kind() != reflect.Ptr { + iter.ReportError("ReadVal", "can only unmarshal into pointer") + return + } + decoder = iter.cfg.DecoderOf(typ) + } + ptr := reflect2.PtrOf(obj) + if ptr == nil { + iter.ReportError("ReadVal", "can not read into nil pointer") + return + } + decoder.Decode(ptr, iter) + if iter.depth != depth { + iter.ReportError("ReadVal", "unexpected mismatched nesting") + return + } +} + +// WriteVal copy the go interface into underlying JSON, same as json.Marshal +func (stream *Stream) WriteVal(val interface{}) { + if nil == val { + stream.WriteNil() + return + } + cacheKey := reflect2.RTypeOf(val) + encoder := stream.cfg.getEncoderFromCache(cacheKey) + if encoder == nil { + typ := reflect2.TypeOf(val) + encoder = stream.cfg.EncoderOf(typ) + } + encoder.Encode(reflect2.PtrOf(val), stream) +} + +func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { + cacheKey := typ.RType() + decoder := cfg.getDecoderFromCache(cacheKey) + if decoder != nil { + return decoder + } + ctx := &ctx{ + frozenConfig: cfg, + prefix: "", + decoders: map[reflect2.Type]ValDecoder{}, + encoders: map[reflect2.Type]ValEncoder{}, + } + ptrType := typ.(*reflect2.UnsafePtrType) + decoder = decoderOfType(ctx, ptrType.Elem()) + cfg.addDecoderToCache(cacheKey, decoder) + return decoder +} + +func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := getTypeDecoderFromExtension(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfType(ctx, typ) + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) + for _, extension := range ctx.extraExtensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + return decoder +} + +func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := ctx.decoders[typ] + if decoder != nil { + return decoder + } + placeholder := &placeholderDecoder{} + ctx.decoders[typ] = placeholder + decoder = _createDecoderOfType(ctx, typ) + placeholder.decoder = decoder + return decoder +} + +func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := createDecoderOfJsonRawMessage(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfJsonNumber(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfMarshaler(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfAny(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfNative(ctx, typ) + if decoder != nil { + return decoder + } + switch typ.Kind() { + case reflect.Interface: + ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType) + if isIFace { + return &ifaceDecoder{valType: ifaceType} + } + return &efaceDecoder{} + case reflect.Struct: + return decoderOfStruct(ctx, typ) + case reflect.Array: + return decoderOfArray(ctx, typ) + case reflect.Slice: + return decoderOfSlice(ctx, typ) + case reflect.Map: + return decoderOfMap(ctx, typ) + case reflect.Ptr: + return decoderOfOptional(ctx, typ) + default: + return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} + } +} + +func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { + cacheKey := typ.RType() + encoder := cfg.getEncoderFromCache(cacheKey) + if encoder != nil { + return encoder + } + ctx := &ctx{ + frozenConfig: cfg, + prefix: "", + decoders: map[reflect2.Type]ValDecoder{}, + encoders: map[reflect2.Type]ValEncoder{}, + } + encoder = encoderOfType(ctx, typ) + if typ.LikePtr() { + encoder = &onePtrEncoder{encoder} + } + cfg.addEncoderToCache(cacheKey, encoder) + return encoder +} + +type onePtrEncoder struct { + encoder ValEncoder +} + +func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +} + +func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := getTypeEncoderFromExtension(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfType(ctx, typ) + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) + for _, extension := range ctx.extraExtensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + return encoder +} + +func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := ctx.encoders[typ] + if encoder != nil { + return encoder + } + placeholder := &placeholderEncoder{} + ctx.encoders[typ] = placeholder + encoder = _createEncoderOfType(ctx, typ) + placeholder.encoder = encoder + return encoder +} +func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := createEncoderOfJsonRawMessage(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfJsonNumber(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfMarshaler(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfAny(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfNative(ctx, typ) + if encoder != nil { + return encoder + } + kind := typ.Kind() + switch kind { + case reflect.Interface: + return &dynamicEncoder{typ} + case reflect.Struct: + return encoderOfStruct(ctx, typ) + case reflect.Array: + return encoderOfArray(ctx, typ) + case reflect.Slice: + return encoderOfSlice(ctx, typ) + case reflect.Map: + return encoderOfMap(ctx, typ) + case reflect.Ptr: + return encoderOfOptional(ctx, typ) + default: + return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} + } +} + +type lazyErrorDecoder struct { + err error +} + +func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.WhatIsNext() != NilValue { + if iter.Error == nil { + iter.Error = decoder.err + } + } else { + iter.Skip() + } +} + +type lazyErrorEncoder struct { + err error +} + +func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if ptr == nil { + stream.WriteNil() + } else if stream.Error == nil { + stream.Error = encoder.err + } +} + +func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type placeholderDecoder struct { + decoder ValDecoder +} + +func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.decoder.Decode(ptr, iter) +} + +type placeholderEncoder struct { + encoder ValEncoder +} + +func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(ptr, stream) +} + +func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(ptr) +} diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go new file mode 100644 index 0000000000000000000000000000000000000000..13a0b7b0878cb7e6f379bb548e526a0efdce3713 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_array.go @@ -0,0 +1,104 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "unsafe" +) + +func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder { + arrayType := typ.(*reflect2.UnsafeArrayType) + decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) + return &arrayDecoder{arrayType, decoder} +} + +func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder { + arrayType := typ.(*reflect2.UnsafeArrayType) + if arrayType.Len() == 0 { + return emptyArrayEncoder{} + } + encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) + return &arrayEncoder{arrayType, encoder} +} + +type emptyArrayEncoder struct{} + +func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyArray() +} + +func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return true +} + +type arrayEncoder struct { + arrayType *reflect2.UnsafeArrayType + elemEncoder ValEncoder +} + +func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteArrayStart() + elemPtr := unsafe.Pointer(ptr) + encoder.elemEncoder.Encode(elemPtr, stream) + for i := 1; i < encoder.arrayType.Len(); i++ { + stream.WriteMore() + elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i) + encoder.elemEncoder.Encode(elemPtr, stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error()) + } +} + +func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type arrayDecoder struct { + arrayType *reflect2.UnsafeArrayType + elemDecoder ValDecoder +} + +func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error()) + } +} + +func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + arrayType := decoder.arrayType + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return + } + if c != '[' { + iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c})) + return + } + c = iter.nextToken() + if c == ']' { + return + } + iter.unreadByte() + elemPtr := arrayType.UnsafeGetIndex(ptr, 0) + decoder.elemDecoder.Decode(elemPtr, iter) + length := 1 + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + if length >= arrayType.Len() { + iter.Skip() + continue + } + idx := length + length += 1 + elemPtr = arrayType.UnsafeGetIndex(ptr, idx) + decoder.elemDecoder.Decode(elemPtr, iter) + } + if c != ']' { + iter.ReportError("decode array", "expect ], but found "+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_dynamic.go b/vendor/github.com/json-iterator/go/reflect_dynamic.go new file mode 100644 index 0000000000000000000000000000000000000000..8b6bc8b4332869236aa7b7374ee6b6803f5645d6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_dynamic.go @@ -0,0 +1,70 @@ +package jsoniter + +import ( + "github.com/modern-go/reflect2" + "reflect" + "unsafe" +) + +type dynamicEncoder struct { + valType reflect2.Type +} + +func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + stream.WriteVal(obj) +} + +func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.valType.UnsafeIndirect(ptr) == nil +} + +type efaceDecoder struct { +} + +func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + pObj := (*interface{})(ptr) + obj := *pObj + if obj == nil { + *pObj = iter.Read() + return + } + typ := reflect2.TypeOf(obj) + if typ.Kind() != reflect.Ptr { + *pObj = iter.Read() + return + } + ptrType := typ.(*reflect2.UnsafePtrType) + ptrElemType := ptrType.Elem() + if iter.WhatIsNext() == NilValue { + if ptrElemType.Kind() != reflect.Ptr { + iter.skipFourBytes('n', 'u', 'l', 'l') + *pObj = nil + return + } + } + if reflect2.IsNil(obj) { + obj := ptrElemType.New() + iter.ReadVal(obj) + *pObj = obj + return + } + iter.ReadVal(obj) +} + +type ifaceDecoder struct { + valType *reflect2.UnsafeIFaceType +} + +func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew()) + return + } + obj := decoder.valType.UnsafeIndirect(ptr) + if reflect2.IsNil(obj) { + iter.ReportError("decode non empty interface", "can not unmarshal into nil") + return + } + iter.ReadVal(obj) +} diff --git a/vendor/github.com/json-iterator/go/reflect_extension.go b/vendor/github.com/json-iterator/go/reflect_extension.go new file mode 100644 index 0000000000000000000000000000000000000000..74a97bfe5abfb228c2dec33be40f1292b9605338 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_extension.go @@ -0,0 +1,483 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "reflect" + "sort" + "strings" + "unicode" + "unsafe" +) + +var typeDecoders = map[string]ValDecoder{} +var fieldDecoders = map[string]ValDecoder{} +var typeEncoders = map[string]ValEncoder{} +var fieldEncoders = map[string]ValEncoder{} +var extensions = []Extension{} + +// StructDescriptor describe how should we encode/decode the struct +type StructDescriptor struct { + Type reflect2.Type + Fields []*Binding +} + +// GetField get one field from the descriptor by its name. +// Can not use map here to keep field orders. +func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { + for _, binding := range structDescriptor.Fields { + if binding.Field.Name() == fieldName { + return binding + } + } + return nil +} + +// Binding describe how should we encode/decode the struct field +type Binding struct { + levels []int + Field reflect2.StructField + FromNames []string + ToNames []string + Encoder ValEncoder + Decoder ValDecoder +} + +// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. +// Can also rename fields by UpdateStructDescriptor. +type Extension interface { + UpdateStructDescriptor(structDescriptor *StructDescriptor) + CreateMapKeyDecoder(typ reflect2.Type) ValDecoder + CreateMapKeyEncoder(typ reflect2.Type) ValEncoder + CreateDecoder(typ reflect2.Type) ValDecoder + CreateEncoder(typ reflect2.Type) ValEncoder + DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder + DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder +} + +// DummyExtension embed this type get dummy implementation for all methods of Extension +type DummyExtension struct { +} + +// UpdateStructDescriptor No-op +func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateMapKeyDecoder No-op +func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// CreateDecoder No-op +func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateEncoder No-op +func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type EncoderExtension map[reflect2.Type]ValEncoder + +// UpdateStructDescriptor No-op +func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateDecoder No-op +func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateEncoder get encoder from map +func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return extension[typ] +} + +// CreateMapKeyDecoder No-op +func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type DecoderExtension map[reflect2.Type]ValDecoder + +// UpdateStructDescriptor No-op +func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateMapKeyDecoder No-op +func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// CreateDecoder get decoder from map +func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return extension[typ] +} + +// CreateEncoder No-op +func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type funcDecoder struct { + fun DecoderFunc +} + +func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.fun(ptr, iter) +} + +type funcEncoder struct { + fun EncoderFunc + isEmptyFunc func(ptr unsafe.Pointer) bool +} + +func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.fun(ptr, stream) +} + +func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { + if encoder.isEmptyFunc == nil { + return false + } + return encoder.isEmptyFunc(ptr) +} + +// DecoderFunc the function form of TypeDecoder +type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) + +// EncoderFunc the function form of TypeEncoder +type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) + +// RegisterTypeDecoderFunc register TypeDecoder for a type with function +func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { + typeDecoders[typ] = &funcDecoder{fun} +} + +// RegisterTypeDecoder register TypeDecoder for a typ +func RegisterTypeDecoder(typ string, decoder ValDecoder) { + typeDecoders[typ] = decoder +} + +// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function +func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { + RegisterFieldDecoder(typ, field, &funcDecoder{fun}) +} + +// RegisterFieldDecoder register TypeDecoder for a struct field +func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { + fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder +} + +// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function +func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} +} + +// RegisterTypeEncoder register TypeEncoder for a type +func RegisterTypeEncoder(typ string, encoder ValEncoder) { + typeEncoders[typ] = encoder +} + +// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function +func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) +} + +// RegisterFieldEncoder register TypeEncoder for a struct field +func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { + fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder +} + +// RegisterExtension register extension +func RegisterExtension(extension Extension) { + extensions = append(extensions, extension) +} + +func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := _getTypeDecoderFromExtension(ctx, typ) + if decoder != nil { + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) + for _, extension := range ctx.extraExtensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + } + return decoder +} +func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { + for _, extension := range extensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + decoder := ctx.decoderExtension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + for _, extension := range ctx.extraExtensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + typeName := typ.String() + decoder = typeDecoders[typeName] + if decoder != nil { + return decoder + } + if typ.Kind() == reflect.Ptr { + ptrType := typ.(*reflect2.UnsafePtrType) + decoder := typeDecoders[ptrType.Elem().String()] + if decoder != nil { + return &OptionalDecoder{ptrType.Elem(), decoder} + } + } + return nil +} + +func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := _getTypeEncoderFromExtension(ctx, typ) + if encoder != nil { + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) + for _, extension := range ctx.extraExtensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + } + return encoder +} + +func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { + for _, extension := range extensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + encoder := ctx.encoderExtension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + for _, extension := range ctx.extraExtensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + typeName := typ.String() + encoder = typeEncoders[typeName] + if encoder != nil { + return encoder + } + if typ.Kind() == reflect.Ptr { + typePtr := typ.(*reflect2.UnsafePtrType) + encoder := typeEncoders[typePtr.Elem().String()] + if encoder != nil { + return &OptionalEncoder{encoder} + } + } + return nil +} + +func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { + structType := typ.(*reflect2.UnsafeStructType) + embeddedBindings := []*Binding{} + bindings := []*Binding{} + for i := 0; i < structType.NumField(); i++ { + field := structType.Field(i) + tag, hastag := field.Tag().Lookup(ctx.getTagKey()) + if ctx.onlyTaggedField && !hastag && !field.Anonymous() { + continue + } + if tag == "-" || field.Name() == "_" { + continue + } + tagParts := strings.Split(tag, ",") + if field.Anonymous() && (tag == "" || tagParts[0] == "") { + if field.Type().Kind() == reflect.Struct { + structDescriptor := describeStruct(ctx, field.Type()) + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} + binding.Decoder = &structFieldDecoder{field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } else if field.Type().Kind() == reflect.Ptr { + ptrType := field.Type().(*reflect2.UnsafePtrType) + if ptrType.Elem().Kind() == reflect.Struct { + structDescriptor := describeStruct(ctx, ptrType.Elem()) + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &dereferenceEncoder{binding.Encoder} + binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} + binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder} + binding.Decoder = &structFieldDecoder{field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } + } + } + fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) + fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) + decoder := fieldDecoders[fieldCacheKey] + if decoder == nil { + decoder = decoderOfType(ctx.append(field.Name()), field.Type()) + } + encoder := fieldEncoders[fieldCacheKey] + if encoder == nil { + encoder = encoderOfType(ctx.append(field.Name()), field.Type()) + } + binding := &Binding{ + Field: field, + FromNames: fieldNames, + ToNames: fieldNames, + Decoder: decoder, + Encoder: encoder, + } + binding.levels = []int{i} + bindings = append(bindings, binding) + } + return createStructDescriptor(ctx, typ, bindings, embeddedBindings) +} +func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { + structDescriptor := &StructDescriptor{ + Type: typ, + Fields: bindings, + } + for _, extension := range extensions { + extension.UpdateStructDescriptor(structDescriptor) + } + ctx.encoderExtension.UpdateStructDescriptor(structDescriptor) + ctx.decoderExtension.UpdateStructDescriptor(structDescriptor) + for _, extension := range ctx.extraExtensions { + extension.UpdateStructDescriptor(structDescriptor) + } + processTags(structDescriptor, ctx.frozenConfig) + // merge normal & embedded bindings & sort with original order + allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) + sort.Sort(allBindings) + structDescriptor.Fields = allBindings + return structDescriptor +} + +type sortableBindings []*Binding + +func (bindings sortableBindings) Len() int { + return len(bindings) +} + +func (bindings sortableBindings) Less(i, j int) bool { + left := bindings[i].levels + right := bindings[j].levels + k := 0 + for { + if left[k] < right[k] { + return true + } else if left[k] > right[k] { + return false + } + k++ + } +} + +func (bindings sortableBindings) Swap(i, j int) { + bindings[i], bindings[j] = bindings[j], bindings[i] +} + +func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { + for _, binding := range structDescriptor.Fields { + shouldOmitEmpty := false + tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",") + for _, tagPart := range tagParts[1:] { + if tagPart == "omitempty" { + shouldOmitEmpty = true + } else if tagPart == "string" { + if binding.Field.Type().Kind() == reflect.String { + binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} + binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} + } else { + binding.Decoder = &stringModeNumberDecoder{binding.Decoder} + binding.Encoder = &stringModeNumberEncoder{binding.Encoder} + } + } + } + binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} + binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} + } +} + +func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { + // ignore? + if wholeTag == "-" { + return []string{} + } + // rename? + var fieldNames []string + if tagProvidedFieldName == "" { + fieldNames = []string{originalFieldName} + } else { + fieldNames = []string{tagProvidedFieldName} + } + // private? + isNotExported := unicode.IsLower(rune(originalFieldName[0])) || originalFieldName[0] == '_' + if isNotExported { + fieldNames = []string{} + } + return fieldNames +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go new file mode 100644 index 0000000000000000000000000000000000000000..98d45c1ec25500f9d7f7c944286e26bbc5d321ae --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_json_number.go @@ -0,0 +1,112 @@ +package jsoniter + +import ( + "encoding/json" + "github.com/modern-go/reflect2" + "strconv" + "unsafe" +) + +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +func CastJsonNumber(val interface{}) (string, bool) { + switch typedVal := val.(type) { + case json.Number: + return string(typedVal), true + case Number: + return string(typedVal), true + } + return "", false +} + +var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem() +var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem() + +func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{} + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{} + } + return nil +} + +func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{} + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{} + } + return nil +} + +type jsonNumberCodec struct { +} + +func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*json.Number)(ptr)) = json.Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*json.Number)(ptr)) = "" + default: + *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + number := *((*json.Number)(ptr)) + if len(number) == 0 { + stream.writeByte('0') + } else { + stream.WriteRaw(string(number)) + } +} + +func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.Number)(ptr))) == 0 +} + +type jsoniterNumberCodec struct { +} + +func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*Number)(ptr)) = Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*Number)(ptr)) = "" + default: + *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + number := *((*Number)(ptr)) + if len(number) == 0 { + stream.writeByte('0') + } else { + stream.WriteRaw(string(number)) + } +} + +func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*Number)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go new file mode 100644 index 0000000000000000000000000000000000000000..f2619936c88fdab07c905167cd5abb99d2d0c1c1 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go @@ -0,0 +1,60 @@ +package jsoniter + +import ( + "encoding/json" + "github.com/modern-go/reflect2" + "unsafe" +) + +var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem() +var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem() + +func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{} + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{} + } + return nil +} + +func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{} + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{} + } + return nil +} + +type jsonRawMessageCodec struct { +} + +func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*json.RawMessage)(ptr)))) +} + +func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 +} + +type jsoniterRawMessageCodec struct { +} + +func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*RawMessage)(ptr)))) +} + +func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*RawMessage)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go new file mode 100644 index 0000000000000000000000000000000000000000..58296713013531babbf1c8bbf2e646ac489e1d39 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_map.go @@ -0,0 +1,346 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "sort" + "unsafe" +) + +func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder { + mapType := typ.(*reflect2.UnsafeMapType) + keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()) + elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem()) + return &mapDecoder{ + mapType: mapType, + keyType: mapType.Key(), + elemType: mapType.Elem(), + keyDecoder: keyDecoder, + elemDecoder: elemDecoder, + } +} + +func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder { + mapType := typ.(*reflect2.UnsafeMapType) + if ctx.sortMapKeys { + return &sortKeysMapEncoder{ + mapType: mapType, + keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), + elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), + } + } + return &mapEncoder{ + mapType: mapType, + keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), + elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), + } +} + +func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ) + if decoder != nil { + return decoder + } + for _, extension := range ctx.extraExtensions { + decoder := extension.CreateMapKeyDecoder(typ) + if decoder != nil { + return decoder + } + } + + ptrType := reflect2.PtrTo(typ) + if ptrType.Implements(unmarshalerType) { + return &referenceDecoder{ + &unmarshalerDecoder{ + valType: ptrType, + }, + } + } + if typ.Implements(unmarshalerType) { + return &unmarshalerDecoder{ + valType: typ, + } + } + if ptrType.Implements(textUnmarshalerType) { + return &referenceDecoder{ + &textUnmarshalerDecoder{ + valType: ptrType, + }, + } + } + if typ.Implements(textUnmarshalerType) { + return &textUnmarshalerDecoder{ + valType: typ, + } + } + + switch typ.Kind() { + case reflect.String: + return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) + case reflect.Bool, + reflect.Uint8, reflect.Int8, + reflect.Uint16, reflect.Int16, + reflect.Uint32, reflect.Int32, + reflect.Uint64, reflect.Int64, + reflect.Uint, reflect.Int, + reflect.Float32, reflect.Float64, + reflect.Uintptr: + typ = reflect2.DefaultTypeOfKind(typ.Kind()) + return &numericMapKeyDecoder{decoderOfType(ctx, typ)} + default: + return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)} + } +} + +func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ) + if encoder != nil { + return encoder + } + for _, extension := range ctx.extraExtensions { + encoder := extension.CreateMapKeyEncoder(typ) + if encoder != nil { + return encoder + } + } + + if typ == textMarshalerType { + return &directTextMarshalerEncoder{ + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + } + if typ.Implements(textMarshalerType) { + return &textMarshalerEncoder{ + valType: typ, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + } + + switch typ.Kind() { + case reflect.String: + return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) + case reflect.Bool, + reflect.Uint8, reflect.Int8, + reflect.Uint16, reflect.Int16, + reflect.Uint32, reflect.Int32, + reflect.Uint64, reflect.Int64, + reflect.Uint, reflect.Int, + reflect.Float32, reflect.Float64, + reflect.Uintptr: + typ = reflect2.DefaultTypeOfKind(typ.Kind()) + return &numericMapKeyEncoder{encoderOfType(ctx, typ)} + default: + if typ.Kind() == reflect.Interface { + return &dynamicMapKeyEncoder{ctx, typ} + } + return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} + } +} + +type mapDecoder struct { + mapType *reflect2.UnsafeMapType + keyType reflect2.Type + elemType reflect2.Type + keyDecoder ValDecoder + elemDecoder ValDecoder +} + +func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + mapType := decoder.mapType + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + *(*unsafe.Pointer)(ptr) = nil + mapType.UnsafeSet(ptr, mapType.UnsafeNew()) + return + } + if mapType.UnsafeIsNil(ptr) { + mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0)) + } + if c != '{' { + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return + } + c = iter.nextToken() + if c == '}' { + return + } + iter.unreadByte() + key := decoder.keyType.UnsafeNew() + decoder.keyDecoder.Decode(key, iter) + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return + } + elem := decoder.elemType.UnsafeNew() + decoder.elemDecoder.Decode(elem, iter) + decoder.mapType.UnsafeSetIndex(ptr, key, elem) + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + key := decoder.keyType.UnsafeNew() + decoder.keyDecoder.Decode(key, iter) + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return + } + elem := decoder.elemType.UnsafeNew() + decoder.elemDecoder.Decode(elem, iter) + decoder.mapType.UnsafeSetIndex(ptr, key, elem) + } + if c != '}' { + iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c})) + } +} + +type numericMapKeyDecoder struct { + decoder ValDecoder +} + +func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) + return + } + decoder.decoder.Decode(ptr, iter) + c = iter.nextToken() + if c != '"' { + iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) + return + } +} + +type numericMapKeyEncoder struct { + encoder ValEncoder +} + +func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.encoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type dynamicMapKeyEncoder struct { + ctx *ctx + valType reflect2.Type +} + +func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) +} + +func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + obj := encoder.valType.UnsafeIndirect(ptr) + return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) +} + +type mapEncoder struct { + mapType *reflect2.UnsafeMapType + keyEncoder ValEncoder + elemEncoder ValEncoder +} + +func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *(*unsafe.Pointer)(ptr) == nil { + stream.WriteNil() + return + } + stream.WriteObjectStart() + iter := encoder.mapType.UnsafeIterate(ptr) + for i := 0; iter.HasNext(); i++ { + if i != 0 { + stream.WriteMore() + } + key, elem := iter.UnsafeNext() + encoder.keyEncoder.Encode(key, stream) + if stream.indention > 0 { + stream.writeTwoBytes(byte(':'), byte(' ')) + } else { + stream.writeByte(':') + } + encoder.elemEncoder.Encode(elem, stream) + } + stream.WriteObjectEnd() +} + +func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + iter := encoder.mapType.UnsafeIterate(ptr) + return !iter.HasNext() +} + +type sortKeysMapEncoder struct { + mapType *reflect2.UnsafeMapType + keyEncoder ValEncoder + elemEncoder ValEncoder +} + +func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *(*unsafe.Pointer)(ptr) == nil { + stream.WriteNil() + return + } + stream.WriteObjectStart() + mapIter := encoder.mapType.UnsafeIterate(ptr) + subStream := stream.cfg.BorrowStream(nil) + subStream.Attachment = stream.Attachment + subIter := stream.cfg.BorrowIterator(nil) + keyValues := encodedKeyValues{} + for mapIter.HasNext() { + key, elem := mapIter.UnsafeNext() + subStreamIndex := subStream.Buffered() + encoder.keyEncoder.Encode(key, subStream) + if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { + stream.Error = subStream.Error + } + encodedKey := subStream.Buffer()[subStreamIndex:] + subIter.ResetBytes(encodedKey) + decodedKey := subIter.ReadString() + if stream.indention > 0 { + subStream.writeTwoBytes(byte(':'), byte(' ')) + } else { + subStream.writeByte(':') + } + encoder.elemEncoder.Encode(elem, subStream) + keyValues = append(keyValues, encodedKV{ + key: decodedKey, + keyValue: subStream.Buffer()[subStreamIndex:], + }) + } + sort.Sort(keyValues) + for i, keyValue := range keyValues { + if i != 0 { + stream.WriteMore() + } + stream.Write(keyValue.keyValue) + } + if subStream.Error != nil && stream.Error == nil { + stream.Error = subStream.Error + } + stream.WriteObjectEnd() + stream.cfg.ReturnStream(subStream) + stream.cfg.ReturnIterator(subIter) +} + +func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + iter := encoder.mapType.UnsafeIterate(ptr) + return !iter.HasNext() +} + +type encodedKeyValues []encodedKV + +type encodedKV struct { + key string + keyValue []byte +} + +func (sv encodedKeyValues) Len() int { return len(sv) } +func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key } diff --git a/vendor/github.com/json-iterator/go/reflect_marshaler.go b/vendor/github.com/json-iterator/go/reflect_marshaler.go new file mode 100644 index 0000000000000000000000000000000000000000..3e21f3756717ac3e2a8c271bcc27888a95cac2fb --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_marshaler.go @@ -0,0 +1,225 @@ +package jsoniter + +import ( + "encoding" + "encoding/json" + "unsafe" + + "github.com/modern-go/reflect2" +) + +var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem() +var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem() +var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem() +var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem() + +func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder { + ptrType := reflect2.PtrTo(typ) + if ptrType.Implements(unmarshalerType) { + return &referenceDecoder{ + &unmarshalerDecoder{ptrType}, + } + } + if ptrType.Implements(textUnmarshalerType) { + return &referenceDecoder{ + &textUnmarshalerDecoder{ptrType}, + } + } + return nil +} + +func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == marshalerType { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &directMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + } + return encoder + } + if typ.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &marshalerEncoder{ + valType: typ, + checkIsEmpty: checkIsEmpty, + } + return encoder + } + ptrType := reflect2.PtrTo(typ) + if ctx.prefix != "" && ptrType.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, ptrType) + var encoder ValEncoder = &marshalerEncoder{ + valType: ptrType, + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + if typ == textMarshalerType { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &directTextMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + return encoder + } + if typ.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: typ, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return encoder + } + // if prefix is empty, the type is the root type + if ctx.prefix != "" && ptrType.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, ptrType) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: ptrType, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + return nil +} + +type marshalerEncoder struct { + checkIsEmpty checkIsEmpty + valType reflect2.Type +} + +func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + if encoder.valType.IsNullable() && reflect2.IsNil(obj) { + stream.WriteNil() + return + } + marshaler := obj.(json.Marshaler) + bytes, err := marshaler.MarshalJSON() + if err != nil { + stream.Error = err + } else { + // html escape was already done by jsoniter + // but the extra '\n' should be trimed + l := len(bytes) + if l > 0 && bytes[l-1] == '\n' { + bytes = bytes[:l-1] + } + stream.Write(bytes) + } +} + +func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type directMarshalerEncoder struct { + checkIsEmpty checkIsEmpty +} + +func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + marshaler := *(*json.Marshaler)(ptr) + if marshaler == nil { + stream.WriteNil() + return + } + bytes, err := marshaler.MarshalJSON() + if err != nil { + stream.Error = err + } else { + stream.Write(bytes) + } +} + +func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type textMarshalerEncoder struct { + valType reflect2.Type + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty +} + +func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + if encoder.valType.IsNullable() && reflect2.IsNil(obj) { + stream.WriteNil() + return + } + marshaler := (obj).(encoding.TextMarshaler) + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + str := string(bytes) + encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) + } +} + +func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type directTextMarshalerEncoder struct { + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty +} + +func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + marshaler := *(*encoding.TextMarshaler)(ptr) + if marshaler == nil { + stream.WriteNil() + return + } + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + str := string(bytes) + encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) + } +} + +func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type unmarshalerDecoder struct { + valType reflect2.Type +} + +func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valType := decoder.valType + obj := valType.UnsafeIndirect(ptr) + unmarshaler := obj.(json.Unmarshaler) + iter.nextToken() + iter.unreadByte() // skip spaces + bytes := iter.SkipAndReturnBytes() + err := unmarshaler.UnmarshalJSON(bytes) + if err != nil { + iter.ReportError("unmarshalerDecoder", err.Error()) + } +} + +type textUnmarshalerDecoder struct { + valType reflect2.Type +} + +func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valType := decoder.valType + obj := valType.UnsafeIndirect(ptr) + if reflect2.IsNil(obj) { + ptrType := valType.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + elem := elemType.UnsafeNew() + ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem)) + obj = valType.UnsafeIndirect(ptr) + } + unmarshaler := (obj).(encoding.TextUnmarshaler) + str := iter.ReadString() + err := unmarshaler.UnmarshalText([]byte(str)) + if err != nil { + iter.ReportError("textUnmarshalerDecoder", err.Error()) + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_native.go b/vendor/github.com/json-iterator/go/reflect_native.go new file mode 100644 index 0000000000000000000000000000000000000000..f88722d14d198fe477bd69ae05bd405625be974d --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_native.go @@ -0,0 +1,453 @@ +package jsoniter + +import ( + "encoding/base64" + "reflect" + "strconv" + "unsafe" + + "github.com/modern-go/reflect2" +) + +const ptrSize = 32 << uintptr(^uintptr(0)>>63) + +func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { + sliceDecoder := decoderOfSlice(ctx, typ) + return &base64Codec{sliceDecoder: sliceDecoder} + } + typeName := typ.String() + kind := typ.Kind() + switch kind { + case reflect.String: + if typeName != "string" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) + } + return &stringCodec{} + case reflect.Int: + if typeName != "int" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &int32Codec{} + } + return &int64Codec{} + case reflect.Int8: + if typeName != "int8" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) + } + return &int8Codec{} + case reflect.Int16: + if typeName != "int16" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) + } + return &int16Codec{} + case reflect.Int32: + if typeName != "int32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) + } + return &int32Codec{} + case reflect.Int64: + if typeName != "int64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) + } + return &int64Codec{} + case reflect.Uint: + if typeName != "uint" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint8: + if typeName != "uint8" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) + } + return &uint8Codec{} + case reflect.Uint16: + if typeName != "uint16" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) + } + return &uint16Codec{} + case reflect.Uint32: + if typeName != "uint32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) + } + return &uint32Codec{} + case reflect.Uintptr: + if typeName != "uintptr" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) + } + if ptrSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint64: + if typeName != "uint64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) + } + return &uint64Codec{} + case reflect.Float32: + if typeName != "float32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) + } + return &float32Codec{} + case reflect.Float64: + if typeName != "float64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) + } + return &float64Codec{} + case reflect.Bool: + if typeName != "bool" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) + } + return &boolCodec{} + } + return nil +} + +func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { + sliceDecoder := decoderOfSlice(ctx, typ) + return &base64Codec{sliceDecoder: sliceDecoder} + } + typeName := typ.String() + switch typ.Kind() { + case reflect.String: + if typeName != "string" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) + } + return &stringCodec{} + case reflect.Int: + if typeName != "int" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &int32Codec{} + } + return &int64Codec{} + case reflect.Int8: + if typeName != "int8" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) + } + return &int8Codec{} + case reflect.Int16: + if typeName != "int16" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) + } + return &int16Codec{} + case reflect.Int32: + if typeName != "int32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) + } + return &int32Codec{} + case reflect.Int64: + if typeName != "int64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) + } + return &int64Codec{} + case reflect.Uint: + if typeName != "uint" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint8: + if typeName != "uint8" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) + } + return &uint8Codec{} + case reflect.Uint16: + if typeName != "uint16" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) + } + return &uint16Codec{} + case reflect.Uint32: + if typeName != "uint32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) + } + return &uint32Codec{} + case reflect.Uintptr: + if typeName != "uintptr" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) + } + if ptrSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint64: + if typeName != "uint64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) + } + return &uint64Codec{} + case reflect.Float32: + if typeName != "float32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) + } + return &float32Codec{} + case reflect.Float64: + if typeName != "float64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) + } + return &float64Codec{} + case reflect.Bool: + if typeName != "bool" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) + } + return &boolCodec{} + } + return nil +} + +type stringCodec struct { +} + +func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*string)(ptr)) = iter.ReadString() +} + +func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteString(str) +} + +func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +type int8Codec struct { +} + +func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int8)(ptr)) = iter.ReadInt8() + } +} + +func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt8(*((*int8)(ptr))) +} + +func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int8)(ptr)) == 0 +} + +type int16Codec struct { +} + +func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int16)(ptr)) = iter.ReadInt16() + } +} + +func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt16(*((*int16)(ptr))) +} + +func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int16)(ptr)) == 0 +} + +type int32Codec struct { +} + +func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int32)(ptr)) = iter.ReadInt32() + } +} + +func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt32(*((*int32)(ptr))) +} + +func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int32)(ptr)) == 0 +} + +type int64Codec struct { +} + +func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int64)(ptr)) = iter.ReadInt64() + } +} + +func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt64(*((*int64)(ptr))) +} + +func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int64)(ptr)) == 0 +} + +type uint8Codec struct { +} + +func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint8)(ptr)) = iter.ReadUint8() + } +} + +func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint8(*((*uint8)(ptr))) +} + +func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint8)(ptr)) == 0 +} + +type uint16Codec struct { +} + +func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint16)(ptr)) = iter.ReadUint16() + } +} + +func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint16(*((*uint16)(ptr))) +} + +func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint16)(ptr)) == 0 +} + +type uint32Codec struct { +} + +func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint32)(ptr)) = iter.ReadUint32() + } +} + +func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint32(*((*uint32)(ptr))) +} + +func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint32)(ptr)) == 0 +} + +type uint64Codec struct { +} + +func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint64)(ptr)) = iter.ReadUint64() + } +} + +func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint64(*((*uint64)(ptr))) +} + +func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint64)(ptr)) == 0 +} + +type float32Codec struct { +} + +func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float32)(ptr)) = iter.ReadFloat32() + } +} + +func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32(*((*float32)(ptr))) +} + +func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type float64Codec struct { +} + +func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float64)(ptr)) = iter.ReadFloat64() + } +} + +func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64(*((*float64)(ptr))) +} + +func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +type boolCodec struct { +} + +func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*bool)(ptr)) = iter.ReadBool() + } +} + +func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteBool(*((*bool)(ptr))) +} + +func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool { + return !(*((*bool)(ptr))) +} + +type base64Codec struct { + sliceType *reflect2.UnsafeSliceType + sliceDecoder ValDecoder +} + +func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + codec.sliceType.UnsafeSetNil(ptr) + return + } + switch iter.WhatIsNext() { + case StringValue: + src := iter.ReadString() + dst, err := base64.StdEncoding.DecodeString(src) + if err != nil { + iter.ReportError("decode base64", err.Error()) + } else { + codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst)) + } + case ArrayValue: + codec.sliceDecoder.Decode(ptr, iter) + default: + iter.ReportError("base64Codec", "invalid input") + } +} + +func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + if codec.sliceType.UnsafeIsNil(ptr) { + stream.WriteNil() + return + } + src := *((*[]byte)(ptr)) + encoding := base64.StdEncoding + stream.writeByte('"') + if len(src) != 0 { + size := encoding.EncodedLen(len(src)) + buf := make([]byte, size) + encoding.Encode(buf, src) + stream.buf = append(stream.buf, buf...) + } + stream.writeByte('"') +} + +func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*[]byte)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_optional.go b/vendor/github.com/json-iterator/go/reflect_optional.go new file mode 100644 index 0000000000000000000000000000000000000000..fa71f47489121bdb7f593f7aa3696d546dd64832 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_optional.go @@ -0,0 +1,129 @@ +package jsoniter + +import ( + "github.com/modern-go/reflect2" + "unsafe" +) + +func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + decoder := decoderOfType(ctx, elemType) + return &OptionalDecoder{elemType, decoder} +} + +func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + elemEncoder := encoderOfType(ctx, elemType) + encoder := &OptionalEncoder{elemEncoder} + return encoder +} + +type OptionalDecoder struct { + ValueType reflect2.Type + ValueDecoder ValDecoder +} + +func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + *((*unsafe.Pointer)(ptr)) = nil + } else { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + newPtr := decoder.ValueType.UnsafeNew() + decoder.ValueDecoder.Decode(newPtr, iter) + *((*unsafe.Pointer)(ptr)) = newPtr + } else { + //reuse existing instance + decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } + } +} + +type dereferenceDecoder struct { + // only to deference a pointer + valueType reflect2.Type + valueDecoder ValDecoder +} + +func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + newPtr := decoder.valueType.UnsafeNew() + decoder.valueDecoder.Decode(newPtr, iter) + *((*unsafe.Pointer)(ptr)) = newPtr + } else { + //reuse existing instance + decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } +} + +type OptionalEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*unsafe.Pointer)(ptr)) == nil +} + +type dereferenceEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + dePtr := *((*unsafe.Pointer)(ptr)) + if dePtr == nil { + return true + } + return encoder.ValueEncoder.IsEmpty(dePtr) +} + +func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { + deReferenced := *((*unsafe.Pointer)(ptr)) + if deReferenced == nil { + return true + } + isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil) + if !converted { + return false + } + fieldPtr := unsafe.Pointer(deReferenced) + return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) +} + +type referenceEncoder struct { + encoder ValEncoder +} + +func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +} + +type referenceDecoder struct { + decoder ValDecoder +} + +func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.decoder.Decode(unsafe.Pointer(&ptr), iter) +} diff --git a/vendor/github.com/json-iterator/go/reflect_slice.go b/vendor/github.com/json-iterator/go/reflect_slice.go new file mode 100644 index 0000000000000000000000000000000000000000..9441d79df33b45495d1628e71d13da7d35b9da24 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_slice.go @@ -0,0 +1,99 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "unsafe" +) + +func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder { + sliceType := typ.(*reflect2.UnsafeSliceType) + decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) + return &sliceDecoder{sliceType, decoder} +} + +func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder { + sliceType := typ.(*reflect2.UnsafeSliceType) + encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) + return &sliceEncoder{sliceType, encoder} +} + +type sliceEncoder struct { + sliceType *reflect2.UnsafeSliceType + elemEncoder ValEncoder +} + +func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if encoder.sliceType.UnsafeIsNil(ptr) { + stream.WriteNil() + return + } + length := encoder.sliceType.UnsafeLengthOf(ptr) + if length == 0 { + stream.WriteEmptyArray() + return + } + stream.WriteArrayStart() + encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream) + for i := 1; i < length; i++ { + stream.WriteMore() + elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i) + encoder.elemEncoder.Encode(elemPtr, stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error()) + } +} + +func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.sliceType.UnsafeLengthOf(ptr) == 0 +} + +type sliceDecoder struct { + sliceType *reflect2.UnsafeSliceType + elemDecoder ValDecoder +} + +func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error()) + } +} + +func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + sliceType := decoder.sliceType + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + sliceType.UnsafeSetNil(ptr) + return + } + if c != '[' { + iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c})) + return + } + c = iter.nextToken() + if c == ']' { + sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0)) + return + } + iter.unreadByte() + sliceType.UnsafeGrow(ptr, 1) + elemPtr := sliceType.UnsafeGetIndex(ptr, 0) + decoder.elemDecoder.Decode(elemPtr, iter) + length := 1 + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + idx := length + length += 1 + sliceType.UnsafeGrow(ptr, length) + elemPtr = sliceType.UnsafeGetIndex(ptr, idx) + decoder.elemDecoder.Decode(elemPtr, iter) + } + if c != ']' { + iter.ReportError("decode slice", "expect ], but found "+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go new file mode 100644 index 0000000000000000000000000000000000000000..d7eb0eb5caa8572ed60bc552efe29fb462e0fe0e --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go @@ -0,0 +1,1092 @@ +package jsoniter + +import ( + "fmt" + "io" + "strings" + "unsafe" + + "github.com/modern-go/reflect2" +) + +func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { + bindings := map[string]*Binding{} + structDescriptor := describeStruct(ctx, typ) + for _, binding := range structDescriptor.Fields { + for _, fromName := range binding.FromNames { + old := bindings[fromName] + if old == nil { + bindings[fromName] = binding + continue + } + ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding) + if ignoreOld { + delete(bindings, fromName) + } + if !ignoreNew { + bindings[fromName] = binding + } + } + } + fields := map[string]*structFieldDecoder{} + for k, binding := range bindings { + fields[k] = binding.Decoder.(*structFieldDecoder) + } + + if !ctx.caseSensitive() { + for k, binding := range bindings { + if _, found := fields[strings.ToLower(k)]; !found { + fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) + } + } + } + + return createStructDecoder(ctx, typ, fields) +} + +func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { + if ctx.disallowUnknownFields { + return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} + } + knownHash := map[int64]struct{}{ + 0: {}, + } + + switch len(fields) { + case 0: + return &skipObjectDecoder{typ} + case 1: + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} + } + case 2: + var fieldHash1 int64 + var fieldHash2 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldHash1 == 0 { + fieldHash1 = fieldHash + fieldDecoder1 = fieldDecoder + } else { + fieldHash2 = fieldHash + fieldDecoder2 = fieldDecoder + } + } + return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} + case 3: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } + } + return &threeFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3} + case 4: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } + } + return &fourFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4} + case 5: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } + } + return &fiveFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5} + case 6: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } + } + return &sixFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6} + case 7: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } + } + return &sevenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7} + case 8: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } + } + return &eightFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8} + case 9: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } + } + return &nineFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9} + case 10: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldName10 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + var fieldDecoder10 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else if fieldName9 == 0 { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } else { + fieldName10 = fieldHash + fieldDecoder10 = fieldDecoder + } + } + return &tenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9, + fieldName10, fieldDecoder10} + } + return &generalStructDecoder{typ, fields, false} +} + +type generalStructDecoder struct { + typ reflect2.Type + fields map[string]*structFieldDecoder + disallowUnknownFields bool +} + +func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + var c byte + for c = ','; c == ','; c = iter.nextToken() { + decoder.decodeOneField(ptr, iter) + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + if c != '}' { + iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c})) + } + iter.decrementDepth() +} + +func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { + var field string + var fieldDecoder *structFieldDecoder + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes := iter.ReadStringAsSlice() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil && !iter.cfg.caseSensitive { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } else { + field = iter.ReadString() + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil && !iter.cfg.caseSensitive { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } + if fieldDecoder == nil { + if decoder.disallowUnknownFields { + msg := "found unknown field: " + field + iter.ReportError("ReadObject", msg) + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + iter.Skip() + return + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + fieldDecoder.Decode(ptr, iter) +} + +type skipObjectDecoder struct { + typ reflect2.Type +} + +func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valueType := iter.WhatIsNext() + if valueType != ObjectValue && valueType != NilValue { + iter.ReportError("skipObjectDecoder", "expect object or null") + return + } + iter.Skip() +} + +type oneFieldStructDecoder struct { + typ reflect2.Type + fieldHash int64 + fieldDecoder *structFieldDecoder +} + +func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + if iter.readFieldHash() == decoder.fieldHash { + decoder.fieldDecoder.Decode(ptr, iter) + } else { + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type twoFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder +} + +func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type threeFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder +} + +func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type fourFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder +} + +func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type fiveFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder +} + +func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type sixFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder +} + +func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type sevenFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder +} + +func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type eightFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder +} + +func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type nineFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder + fieldHash9 int64 + fieldDecoder9 *structFieldDecoder +} + +func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type tenFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder + fieldHash9 int64 + fieldDecoder9 *structFieldDecoder + fieldHash10 int64 + fieldDecoder10 *structFieldDecoder +} + +func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + if !iter.incrementDepth() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + case decoder.fieldHash10: + decoder.fieldDecoder10.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + iter.decrementDepth() +} + +type structFieldDecoder struct { + field reflect2.StructField + fieldDecoder ValDecoder +} + +func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + fieldPtr := decoder.field.UnsafeGet(ptr) + decoder.fieldDecoder.Decode(fieldPtr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error()) + } +} + +type stringModeStringDecoder struct { + elemDecoder ValDecoder + cfg *frozenConfig +} + +func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.elemDecoder.Decode(ptr, iter) + str := *((*string)(ptr)) + tempIter := decoder.cfg.BorrowIterator([]byte(str)) + defer decoder.cfg.ReturnIterator(tempIter) + *((*string)(ptr)) = tempIter.ReadString() +} + +type stringModeNumberDecoder struct { + elemDecoder ValDecoder +} + +func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } + decoder.elemDecoder.Decode(ptr, iter) + if iter.Error != nil { + return + } + c = iter.readByte() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go new file mode 100644 index 0000000000000000000000000000000000000000..152e3ef5a93c6e375ed1c3ea34e66e821ef5b9ac --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go @@ -0,0 +1,211 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "unsafe" +) + +func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { + type bindingTo struct { + binding *Binding + toName string + ignored bool + } + orderedBindings := []*bindingTo{} + structDescriptor := describeStruct(ctx, typ) + for _, binding := range structDescriptor.Fields { + for _, toName := range binding.ToNames { + new := &bindingTo{ + binding: binding, + toName: toName, + } + for _, old := range orderedBindings { + if old.toName != toName { + continue + } + old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) + } + orderedBindings = append(orderedBindings, new) + } + } + if len(orderedBindings) == 0 { + return &emptyStructEncoder{} + } + finalOrderedFields := []structFieldTo{} + for _, bindingTo := range orderedBindings { + if !bindingTo.ignored { + finalOrderedFields = append(finalOrderedFields, structFieldTo{ + encoder: bindingTo.binding.Encoder.(*structFieldEncoder), + toName: bindingTo.toName, + }) + } + } + return &structEncoder{typ, finalOrderedFields} +} + +func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty { + encoder := createEncoderOfNative(ctx, typ) + if encoder != nil { + return encoder + } + kind := typ.Kind() + switch kind { + case reflect.Interface: + return &dynamicEncoder{typ} + case reflect.Struct: + return &structEncoder{typ: typ} + case reflect.Array: + return &arrayEncoder{} + case reflect.Slice: + return &sliceEncoder{} + case reflect.Map: + return encoderOfMap(ctx, typ) + case reflect.Ptr: + return &OptionalEncoder{} + default: + return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)} + } +} + +func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { + newTagged := new.Field.Tag().Get(cfg.getTagKey()) != "" + oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != "" + if newTagged { + if oldTagged { + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } else { + return true, false + } + } else { + if oldTagged { + return true, false + } + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } +} + +type structFieldEncoder struct { + field reflect2.StructField + fieldEncoder ValEncoder + omitempty bool +} + +func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + fieldPtr := encoder.field.UnsafeGet(ptr) + encoder.fieldEncoder.Encode(fieldPtr, stream) + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) + } +} + +func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { + fieldPtr := encoder.field.UnsafeGet(ptr) + return encoder.fieldEncoder.IsEmpty(fieldPtr) +} + +func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { + isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil) + if !converted { + return false + } + fieldPtr := encoder.field.UnsafeGet(ptr) + return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) +} + +type IsEmbeddedPtrNil interface { + IsEmbeddedPtrNil(ptr unsafe.Pointer) bool +} + +type structEncoder struct { + typ reflect2.Type + fields []structFieldTo +} + +type structFieldTo struct { + encoder *structFieldEncoder + toName string +} + +func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteObjectStart() + isNotFirst := false + for _, field := range encoder.fields { + if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { + continue + } + if field.encoder.IsEmbeddedPtrNil(ptr) { + continue + } + if isNotFirst { + stream.WriteMore() + } + stream.WriteObjectField(field.toName) + field.encoder.Encode(ptr, stream) + isNotFirst = true + } + stream.WriteObjectEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) + } +} + +func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type emptyStructEncoder struct { +} + +func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyObject() +} + +func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type stringModeNumberEncoder struct { + elemEncoder ValEncoder +} + +func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.elemEncoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} + +type stringModeStringEncoder struct { + elemEncoder ValEncoder + cfg *frozenConfig +} + +func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + tempStream := encoder.cfg.BorrowStream(nil) + tempStream.Attachment = stream.Attachment + defer encoder.cfg.ReturnStream(tempStream) + encoder.elemEncoder.Encode(ptr, tempStream) + stream.WriteString(string(tempStream.Buffer())) +} + +func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} diff --git a/vendor/github.com/json-iterator/go/stream.go b/vendor/github.com/json-iterator/go/stream.go new file mode 100644 index 0000000000000000000000000000000000000000..23d8a3ad6b1269c4396e45430a67521493915e2e --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream.go @@ -0,0 +1,210 @@ +package jsoniter + +import ( + "io" +) + +// stream is a io.Writer like object, with JSON specific write functions. +// Error is not returned as return value, but stored as Error member on this stream instance. +type Stream struct { + cfg *frozenConfig + out io.Writer + buf []byte + Error error + indention int + Attachment interface{} // open for customized encoder +} + +// NewStream create new stream instance. +// cfg can be jsoniter.ConfigDefault. +// out can be nil if write to internal buffer. +// bufSize is the initial size for the internal buffer in bytes. +func NewStream(cfg API, out io.Writer, bufSize int) *Stream { + return &Stream{ + cfg: cfg.(*frozenConfig), + out: out, + buf: make([]byte, 0, bufSize), + Error: nil, + indention: 0, + } +} + +// Pool returns a pool can provide more stream with same configuration +func (stream *Stream) Pool() StreamPool { + return stream.cfg +} + +// Reset reuse this stream instance by assign a new writer +func (stream *Stream) Reset(out io.Writer) { + stream.out = out + stream.buf = stream.buf[:0] +} + +// Available returns how many bytes are unused in the buffer. +func (stream *Stream) Available() int { + return cap(stream.buf) - len(stream.buf) +} + +// Buffered returns the number of bytes that have been written into the current buffer. +func (stream *Stream) Buffered() int { + return len(stream.buf) +} + +// Buffer if writer is nil, use this method to take the result +func (stream *Stream) Buffer() []byte { + return stream.buf +} + +// SetBuffer allows to append to the internal buffer directly +func (stream *Stream) SetBuffer(buf []byte) { + stream.buf = buf +} + +// Write writes the contents of p into the buffer. +// It returns the number of bytes written. +// If nn < len(p), it also returns an error explaining +// why the write is short. +func (stream *Stream) Write(p []byte) (nn int, err error) { + stream.buf = append(stream.buf, p...) + if stream.out != nil { + nn, err = stream.out.Write(stream.buf) + stream.buf = stream.buf[nn:] + return + } + return len(p), nil +} + +// WriteByte writes a single byte. +func (stream *Stream) writeByte(c byte) { + stream.buf = append(stream.buf, c) +} + +func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { + stream.buf = append(stream.buf, c1, c2) +} + +func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { + stream.buf = append(stream.buf, c1, c2, c3) +} + +func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { + stream.buf = append(stream.buf, c1, c2, c3, c4) +} + +func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { + stream.buf = append(stream.buf, c1, c2, c3, c4, c5) +} + +// Flush writes any buffered data to the underlying io.Writer. +func (stream *Stream) Flush() error { + if stream.out == nil { + return nil + } + if stream.Error != nil { + return stream.Error + } + _, err := stream.out.Write(stream.buf) + if err != nil { + if stream.Error == nil { + stream.Error = err + } + return err + } + stream.buf = stream.buf[:0] + return nil +} + +// WriteRaw write string out without quotes, just like []byte +func (stream *Stream) WriteRaw(s string) { + stream.buf = append(stream.buf, s...) +} + +// WriteNil write null to stream +func (stream *Stream) WriteNil() { + stream.writeFourBytes('n', 'u', 'l', 'l') +} + +// WriteTrue write true to stream +func (stream *Stream) WriteTrue() { + stream.writeFourBytes('t', 'r', 'u', 'e') +} + +// WriteFalse write false to stream +func (stream *Stream) WriteFalse() { + stream.writeFiveBytes('f', 'a', 'l', 's', 'e') +} + +// WriteBool write true or false into stream +func (stream *Stream) WriteBool(val bool) { + if val { + stream.WriteTrue() + } else { + stream.WriteFalse() + } +} + +// WriteObjectStart write { with possible indention +func (stream *Stream) WriteObjectStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('{') + stream.writeIndention(0) +} + +// WriteObjectField write "field": with possible indention +func (stream *Stream) WriteObjectField(field string) { + stream.WriteString(field) + if stream.indention > 0 { + stream.writeTwoBytes(':', ' ') + } else { + stream.writeByte(':') + } +} + +// WriteObjectEnd write } with possible indention +func (stream *Stream) WriteObjectEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte('}') +} + +// WriteEmptyObject write {} +func (stream *Stream) WriteEmptyObject() { + stream.writeByte('{') + stream.writeByte('}') +} + +// WriteMore write , with possible indention +func (stream *Stream) WriteMore() { + stream.writeByte(',') + stream.writeIndention(0) +} + +// WriteArrayStart write [ with possible indention +func (stream *Stream) WriteArrayStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('[') + stream.writeIndention(0) +} + +// WriteEmptyArray write [] +func (stream *Stream) WriteEmptyArray() { + stream.writeTwoBytes('[', ']') +} + +// WriteArrayEnd write ] with possible indention +func (stream *Stream) WriteArrayEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte(']') +} + +func (stream *Stream) writeIndention(delta int) { + if stream.indention == 0 { + return + } + stream.writeByte('\n') + toWrite := stream.indention - delta + for i := 0; i < toWrite; i++ { + stream.buf = append(stream.buf, ' ') + } +} diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go new file mode 100644 index 0000000000000000000000000000000000000000..826aa594ac6f34a832fd3a4b8e4dea654278dc3b --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_float.go @@ -0,0 +1,111 @@ +package jsoniter + +import ( + "fmt" + "math" + "strconv" +) + +var pow10 []uint64 + +func init() { + pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} +} + +// WriteFloat32 write float32 to stream +func (stream *Stream) WriteFloat32(val float32) { + if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) { + stream.Error = fmt.Errorf("unsupported value: %f", val) + return + } + abs := math.Abs(float64(val)) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if float32(abs) < 1e-6 || float32(abs) >= 1e21 { + fmt = 'e' + } + } + stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32) +} + +// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat32Lossy(val float32) { + if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) { + stream.Error = fmt.Errorf("unsupported value: %f", val) + return + } + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat32(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(float64(val)*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] + } +} + +// WriteFloat64 write float64 to stream +func (stream *Stream) WriteFloat64(val float64) { + if math.IsInf(val, 0) || math.IsNaN(val) { + stream.Error = fmt.Errorf("unsupported value: %f", val) + return + } + abs := math.Abs(val) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if abs < 1e-6 || abs >= 1e21 { + fmt = 'e' + } + } + stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64) +} + +// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat64Lossy(val float64) { + if math.IsInf(val, 0) || math.IsNaN(val) { + stream.Error = fmt.Errorf("unsupported value: %f", val) + return + } + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat64(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(val*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] + } +} diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go new file mode 100644 index 0000000000000000000000000000000000000000..d1059ee4c20e3739a39eb09c448c7b60a02f4d63 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_int.go @@ -0,0 +1,190 @@ +package jsoniter + +var digits []uint32 + +func init() { + digits = make([]uint32, 1000) + for i := uint32(0); i < 1000; i++ { + digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0' + if i < 10 { + digits[i] += 2 << 24 + } else if i < 100 { + digits[i] += 1 << 24 + } + } +} + +func writeFirstBuf(space []byte, v uint32) []byte { + start := v >> 24 + if start == 0 { + space = append(space, byte(v>>16), byte(v>>8)) + } else if start == 1 { + space = append(space, byte(v>>8)) + } + space = append(space, byte(v)) + return space +} + +func writeBuf(buf []byte, v uint32) []byte { + return append(buf, byte(v>>16), byte(v>>8), byte(v)) +} + +// WriteUint8 write uint8 to stream +func (stream *Stream) WriteUint8(val uint8) { + stream.buf = writeFirstBuf(stream.buf, digits[val]) +} + +// WriteInt8 write int8 to stream +func (stream *Stream) WriteInt8(nval int8) { + var val uint8 + if nval < 0 { + val = uint8(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint8(nval) + } + stream.buf = writeFirstBuf(stream.buf, digits[val]) +} + +// WriteUint16 write uint16 to stream +func (stream *Stream) WriteUint16(val uint16) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return +} + +// WriteInt16 write int16 to stream +func (stream *Stream) WriteInt16(nval int16) { + var val uint16 + if nval < 0 { + val = uint16(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint16(nval) + } + stream.WriteUint16(val) +} + +// WriteUint32 write uint32 to stream +func (stream *Stream) WriteUint32(val uint32) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q2]) + } else { + r3 := q2 - q3*1000 + stream.buf = append(stream.buf, byte(q3+'0')) + stream.buf = writeBuf(stream.buf, digits[r3]) + } + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) +} + +// WriteInt32 write int32 to stream +func (stream *Stream) WriteInt32(nval int32) { + var val uint32 + if nval < 0 { + val = uint32(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint32(nval) + } + stream.WriteUint32(val) +} + +// WriteUint64 write uint64 to stream +func (stream *Stream) WriteUint64(val uint64) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q2]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r3 := q2 - q3*1000 + q4 := q3 / 1000 + if q4 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q3]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r4 := q3 - q4*1000 + q5 := q4 / 1000 + if q5 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q4]) + stream.buf = writeBuf(stream.buf, digits[r4]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r5 := q4 - q5*1000 + q6 := q5 / 1000 + if q6 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q5]) + } else { + stream.buf = writeFirstBuf(stream.buf, digits[q6]) + r6 := q5 - q6*1000 + stream.buf = writeBuf(stream.buf, digits[r6]) + } + stream.buf = writeBuf(stream.buf, digits[r5]) + stream.buf = writeBuf(stream.buf, digits[r4]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) +} + +// WriteInt64 write int64 to stream +func (stream *Stream) WriteInt64(nval int64) { + var val uint64 + if nval < 0 { + val = uint64(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint64(nval) + } + stream.WriteUint64(val) +} + +// WriteInt write int to stream +func (stream *Stream) WriteInt(val int) { + stream.WriteInt64(int64(val)) +} + +// WriteUint write uint to stream +func (stream *Stream) WriteUint(val uint) { + stream.WriteUint64(uint64(val)) +} diff --git a/vendor/github.com/json-iterator/go/stream_str.go b/vendor/github.com/json-iterator/go/stream_str.go new file mode 100644 index 0000000000000000000000000000000000000000..54c2ba0b3a2d9716669b2bc4f99c4f0a95da2233 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_str.go @@ -0,0 +1,372 @@ +package jsoniter + +import ( + "unicode/utf8" +) + +// htmlSafeSet holds the value true if the ASCII character with the given +// array position can be safely represented inside a JSON string, embedded +// inside of HTML <script> tags, without any additional escaping. +// +// All values are true except for the ASCII control characters (0-31), the +// double quote ("), the backslash character ("\"), HTML opening and closing +// tags ("<" and ">"), and the ampersand ("&"). +var htmlSafeSet = [utf8.RuneSelf]bool{ + ' ': true, + '!': true, + '"': false, + '#': true, + '$': true, + '%': true, + '&': false, + '\'': true, + '(': true, + ')': true, + '*': true, + '+': true, + ',': true, + '-': true, + '.': true, + '/': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + ':': true, + ';': true, + '<': false, + '=': true, + '>': false, + '?': true, + '@': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'V': true, + 'W': true, + 'X': true, + 'Y': true, + 'Z': true, + '[': true, + '\\': false, + ']': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '{': true, + '|': true, + '}': true, + '~': true, + '\u007f': true, +} + +// safeSet holds the value true if the ASCII character with the given array +// position can be represented inside a JSON string without any further +// escaping. +// +// All values are true except for the ASCII control characters (0-31), the +// double quote ("), and the backslash character ("\"). +var safeSet = [utf8.RuneSelf]bool{ + ' ': true, + '!': true, + '"': false, + '#': true, + '$': true, + '%': true, + '&': true, + '\'': true, + '(': true, + ')': true, + '*': true, + '+': true, + ',': true, + '-': true, + '.': true, + '/': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + ':': true, + ';': true, + '<': true, + '=': true, + '>': true, + '?': true, + '@': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'V': true, + 'W': true, + 'X': true, + 'Y': true, + 'Z': true, + '[': true, + '\\': false, + ']': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '{': true, + '|': true, + '}': true, + '~': true, + '\u007f': true, +} + +var hex = "0123456789abcdef" + +// WriteStringWithHTMLEscaped write string to stream with html special characters escaped +func (stream *Stream) WriteStringWithHTMLEscaped(s string) { + valLen := len(s) + stream.buf = append(stream.buf, '"') + // write string, the fast path, without utf8 and escape support + i := 0 + for ; i < valLen; i++ { + c := s[i] + if c < utf8.RuneSelf && htmlSafeSet[c] { + stream.buf = append(stream.buf, c) + } else { + break + } + } + if i == valLen { + stream.buf = append(stream.buf, '"') + return + } + writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen) +} + +func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen int) { + start := i + // for the remaining parts, we process them char by char + for i < valLen { + if b := s[i]; b < utf8.RuneSelf { + if htmlSafeSet[b] { + i++ + continue + } + if start < i { + stream.WriteRaw(s[start:i]) + } + switch b { + case '\\', '"': + stream.writeTwoBytes('\\', b) + case '\n': + stream.writeTwoBytes('\\', 'n') + case '\r': + stream.writeTwoBytes('\\', 'r') + case '\t': + stream.writeTwoBytes('\\', 't') + default: + // This encodes bytes < 0x20 except for \t, \n and \r. + // If escapeHTML is set, it also escapes <, >, and & + // because they can lead to security holes when + // user-controlled strings are rendered into JSON + // and served to some browsers. + stream.WriteRaw(`\u00`) + stream.writeTwoBytes(hex[b>>4], hex[b&0xF]) + } + i++ + start = i + continue + } + c, size := utf8.DecodeRuneInString(s[i:]) + if c == utf8.RuneError && size == 1 { + if start < i { + stream.WriteRaw(s[start:i]) + } + stream.WriteRaw(`\ufffd`) + i++ + start = i + continue + } + // U+2028 is LINE SEPARATOR. + // U+2029 is PARAGRAPH SEPARATOR. + // They are both technically valid characters in JSON strings, + // but don't work in JSONP, which has to be evaluated as JavaScript, + // and can lead to security holes there. It is valid JSON to + // escape them, so we do so unconditionally. + // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. + if c == '\u2028' || c == '\u2029' { + if start < i { + stream.WriteRaw(s[start:i]) + } + stream.WriteRaw(`\u202`) + stream.writeByte(hex[c&0xF]) + i += size + start = i + continue + } + i += size + } + if start < len(s) { + stream.WriteRaw(s[start:]) + } + stream.writeByte('"') +} + +// WriteString write string to stream without html escape +func (stream *Stream) WriteString(s string) { + valLen := len(s) + stream.buf = append(stream.buf, '"') + // write string, the fast path, without utf8 and escape support + i := 0 + for ; i < valLen; i++ { + c := s[i] + if c > 31 && c != '"' && c != '\\' { + stream.buf = append(stream.buf, c) + } else { + break + } + } + if i == valLen { + stream.buf = append(stream.buf, '"') + return + } + writeStringSlowPath(stream, i, s, valLen) +} + +func writeStringSlowPath(stream *Stream, i int, s string, valLen int) { + start := i + // for the remaining parts, we process them char by char + for i < valLen { + if b := s[i]; b < utf8.RuneSelf { + if safeSet[b] { + i++ + continue + } + if start < i { + stream.WriteRaw(s[start:i]) + } + switch b { + case '\\', '"': + stream.writeTwoBytes('\\', b) + case '\n': + stream.writeTwoBytes('\\', 'n') + case '\r': + stream.writeTwoBytes('\\', 'r') + case '\t': + stream.writeTwoBytes('\\', 't') + default: + // This encodes bytes < 0x20 except for \t, \n and \r. + // If escapeHTML is set, it also escapes <, >, and & + // because they can lead to security holes when + // user-controlled strings are rendered into JSON + // and served to some browsers. + stream.WriteRaw(`\u00`) + stream.writeTwoBytes(hex[b>>4], hex[b&0xF]) + } + i++ + start = i + continue + } + i++ + continue + } + if start < len(s) { + stream.WriteRaw(s[start:]) + } + stream.writeByte('"') +} diff --git a/vendor/github.com/json-iterator/go/test.sh b/vendor/github.com/json-iterator/go/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..f4e7c0b2c945a7552f9133ddf210301f5d39d55b --- /dev/null +++ b/vendor/github.com/json-iterator/go/test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list ./... | grep -v vendor); do + go test -coverprofile=profile.out -coverpkg=github.com/json-iterator/go $d + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done diff --git a/vendor/github.com/modern-go/concurrent/.gitignore b/vendor/github.com/modern-go/concurrent/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..3f2bc47416e77ca0771c85d681d782d2201096ae --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/.gitignore @@ -0,0 +1 @@ +/coverage.txt diff --git a/vendor/github.com/modern-go/concurrent/.travis.yml b/vendor/github.com/modern-go/concurrent/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..449e67cd01acba105df358ccac3c32f0693f3f1a --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/.travis.yml @@ -0,0 +1,14 @@ +language: go + +go: + - 1.8.x + - 1.x + +before_install: + - go get -t -v ./... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/modern-go/concurrent/LICENSE b/vendor/github.com/modern-go/concurrent/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/modern-go/concurrent/README.md b/vendor/github.com/modern-go/concurrent/README.md new file mode 100644 index 0000000000000000000000000000000000000000..acab3200aa2e470c2bdd35ccfd9b9111f7c978e9 --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/README.md @@ -0,0 +1,49 @@ +# concurrent + +[](https://sourcegraph.com/github.com/modern-go/concurrent?badge) +[](http://godoc.org/github.com/modern-go/concurrent) +[](https://travis-ci.org/modern-go/concurrent) +[](https://codecov.io/gh/modern-go/concurrent) +[](https://goreportcard.com/report/github.com/modern-go/concurrent) +[](https://raw.githubusercontent.com/modern-go/concurrent/master/LICENSE) + +* concurrent.Map: backport sync.Map for go below 1.9 +* concurrent.Executor: goroutine with explicit ownership and cancellable + +# concurrent.Map + +because sync.Map is only available in go 1.9, we can use concurrent.Map to make code portable + +```go +m := concurrent.NewMap() +m.Store("hello", "world") +elem, found := m.Load("hello") +// elem will be "world" +// found will be true +``` + +# concurrent.Executor + +```go +executor := concurrent.NewUnboundedExecutor() +executor.Go(func(ctx context.Context) { + everyMillisecond := time.NewTicker(time.Millisecond) + for { + select { + case <-ctx.Done(): + fmt.Println("goroutine exited") + return + case <-everyMillisecond.C: + // do something + } + } +}) +time.Sleep(time.Second) +executor.StopAndWaitForever() +fmt.Println("executor stopped") +``` + +attach goroutine to executor instance, so that we can + +* cancel it by stop the executor with Stop/StopAndWait/StopAndWaitForever +* handle panic by callback: the default behavior will no longer crash your application \ No newline at end of file diff --git a/vendor/github.com/modern-go/concurrent/executor.go b/vendor/github.com/modern-go/concurrent/executor.go new file mode 100644 index 0000000000000000000000000000000000000000..623dba1ac00f22d1becb9e67e8a26a5b20bc2799 --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/executor.go @@ -0,0 +1,14 @@ +package concurrent + +import "context" + +// Executor replace go keyword to start a new goroutine +// the goroutine should cancel itself if the context passed in has been cancelled +// the goroutine started by the executor, is owned by the executor +// we can cancel all executors owned by the executor just by stop the executor itself +// however Executor interface does not Stop method, the one starting and owning executor +// should use the concrete type of executor, instead of this interface. +type Executor interface { + // Go starts a new goroutine controlled by the context + Go(handler func(ctx context.Context)) +} diff --git a/vendor/github.com/modern-go/concurrent/go_above_19.go b/vendor/github.com/modern-go/concurrent/go_above_19.go new file mode 100644 index 0000000000000000000000000000000000000000..aeabf8c4f9c808648014f38bbb7919ab31b25e72 --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/go_above_19.go @@ -0,0 +1,15 @@ +//+build go1.9 + +package concurrent + +import "sync" + +// Map is a wrapper for sync.Map introduced in go1.9 +type Map struct { + sync.Map +} + +// NewMap creates a thread safe Map +func NewMap() *Map { + return &Map{} +} diff --git a/vendor/github.com/modern-go/concurrent/go_below_19.go b/vendor/github.com/modern-go/concurrent/go_below_19.go new file mode 100644 index 0000000000000000000000000000000000000000..b9c8df7f4101b6270690d9f6526c6e2466109d78 --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/go_below_19.go @@ -0,0 +1,33 @@ +//+build !go1.9 + +package concurrent + +import "sync" + +// Map implements a thread safe map for go version below 1.9 using mutex +type Map struct { + lock sync.RWMutex + data map[interface{}]interface{} +} + +// NewMap creates a thread safe map +func NewMap() *Map { + return &Map{ + data: make(map[interface{}]interface{}, 32), + } +} + +// Load is same as sync.Map Load +func (m *Map) Load(key interface{}) (elem interface{}, found bool) { + m.lock.RLock() + elem, found = m.data[key] + m.lock.RUnlock() + return +} + +// Load is same as sync.Map Store +func (m *Map) Store(key interface{}, elem interface{}) { + m.lock.Lock() + m.data[key] = elem + m.lock.Unlock() +} diff --git a/vendor/github.com/modern-go/concurrent/log.go b/vendor/github.com/modern-go/concurrent/log.go new file mode 100644 index 0000000000000000000000000000000000000000..9756fcc75a79cb0af9b4049ed5543a3496d2b3a6 --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/log.go @@ -0,0 +1,13 @@ +package concurrent + +import ( + "os" + "log" + "io/ioutil" +) + +// ErrorLogger is used to print out error, can be set to writer other than stderr +var ErrorLogger = log.New(os.Stderr, "", 0) + +// InfoLogger is used to print informational message, default to off +var InfoLogger = log.New(ioutil.Discard, "", 0) \ No newline at end of file diff --git a/vendor/github.com/modern-go/concurrent/test.sh b/vendor/github.com/modern-go/concurrent/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..d1e6b2ec554450c3565764a8238b54ee9dcd7776 --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list ./... | grep -v vendor); do + go test -coverprofile=profile.out -coverpkg=github.com/modern-go/concurrent $d + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done diff --git a/vendor/github.com/modern-go/concurrent/unbounded_executor.go b/vendor/github.com/modern-go/concurrent/unbounded_executor.go new file mode 100644 index 0000000000000000000000000000000000000000..05a77dceb1e23e95882e18ed707fb682fbdeec44 --- /dev/null +++ b/vendor/github.com/modern-go/concurrent/unbounded_executor.go @@ -0,0 +1,119 @@ +package concurrent + +import ( + "context" + "fmt" + "runtime" + "runtime/debug" + "sync" + "time" + "reflect" +) + +// HandlePanic logs goroutine panic by default +var HandlePanic = func(recovered interface{}, funcName string) { + ErrorLogger.Println(fmt.Sprintf("%s panic: %v", funcName, recovered)) + ErrorLogger.Println(string(debug.Stack())) +} + +// UnboundedExecutor is a executor without limits on counts of alive goroutines +// it tracks the goroutine started by it, and can cancel them when shutdown +type UnboundedExecutor struct { + ctx context.Context + cancel context.CancelFunc + activeGoroutinesMutex *sync.Mutex + activeGoroutines map[string]int + HandlePanic func(recovered interface{}, funcName string) +} + +// GlobalUnboundedExecutor has the life cycle of the program itself +// any goroutine want to be shutdown before main exit can be started from this executor +// GlobalUnboundedExecutor expects the main function to call stop +// it does not magically knows the main function exits +var GlobalUnboundedExecutor = NewUnboundedExecutor() + +// NewUnboundedExecutor creates a new UnboundedExecutor, +// UnboundedExecutor can not be created by &UnboundedExecutor{} +// HandlePanic can be set with a callback to override global HandlePanic +func NewUnboundedExecutor() *UnboundedExecutor { + ctx, cancel := context.WithCancel(context.TODO()) + return &UnboundedExecutor{ + ctx: ctx, + cancel: cancel, + activeGoroutinesMutex: &sync.Mutex{}, + activeGoroutines: map[string]int{}, + } +} + +// Go starts a new goroutine and tracks its lifecycle. +// Panic will be recovered and logged automatically, except for StopSignal +func (executor *UnboundedExecutor) Go(handler func(ctx context.Context)) { + pc := reflect.ValueOf(handler).Pointer() + f := runtime.FuncForPC(pc) + funcName := f.Name() + file, line := f.FileLine(pc) + executor.activeGoroutinesMutex.Lock() + defer executor.activeGoroutinesMutex.Unlock() + startFrom := fmt.Sprintf("%s:%d", file, line) + executor.activeGoroutines[startFrom] += 1 + go func() { + defer func() { + recovered := recover() + // if you want to quit a goroutine without trigger HandlePanic + // use runtime.Goexit() to quit + if recovered != nil { + if executor.HandlePanic == nil { + HandlePanic(recovered, funcName) + } else { + executor.HandlePanic(recovered, funcName) + } + } + executor.activeGoroutinesMutex.Lock() + executor.activeGoroutines[startFrom] -= 1 + executor.activeGoroutinesMutex.Unlock() + }() + handler(executor.ctx) + }() +} + +// Stop cancel all goroutines started by this executor without wait +func (executor *UnboundedExecutor) Stop() { + executor.cancel() +} + +// StopAndWaitForever cancel all goroutines started by this executor and +// wait until all goroutines exited +func (executor *UnboundedExecutor) StopAndWaitForever() { + executor.StopAndWait(context.Background()) +} + +// StopAndWait cancel all goroutines started by this executor and wait. +// Wait can be cancelled by the context passed in. +func (executor *UnboundedExecutor) StopAndWait(ctx context.Context) { + executor.cancel() + for { + oneHundredMilliseconds := time.NewTimer(time.Millisecond * 100) + select { + case <-oneHundredMilliseconds.C: + if executor.checkNoActiveGoroutines() { + return + } + case <-ctx.Done(): + return + } + } +} + +func (executor *UnboundedExecutor) checkNoActiveGoroutines() bool { + executor.activeGoroutinesMutex.Lock() + defer executor.activeGoroutinesMutex.Unlock() + for startFrom, count := range executor.activeGoroutines { + if count > 0 { + InfoLogger.Println("UnboundedExecutor is still waiting goroutines to quit", + "startFrom", startFrom, + "count", count) + return false + } + } + return true +} diff --git a/vendor/github.com/modern-go/reflect2/.gitignore b/vendor/github.com/modern-go/reflect2/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7b26c946dc6c79f2daf40411c5671cdee7719cdf --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/.gitignore @@ -0,0 +1,2 @@ +/vendor +/coverage.txt diff --git a/vendor/github.com/modern-go/reflect2/.travis.yml b/vendor/github.com/modern-go/reflect2/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..fbb43744d94b22d382113d787f7441cccf8c0a86 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/.travis.yml @@ -0,0 +1,15 @@ +language: go + +go: + - 1.8.x + - 1.x + +before_install: + - go get -t -v ./... + - go get -t -v github.com/modern-go/reflect2-tests/... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/modern-go/reflect2/Gopkg.lock b/vendor/github.com/modern-go/reflect2/Gopkg.lock new file mode 100644 index 0000000000000000000000000000000000000000..2a3a69893b5082ff44b0d3b8e77be923e2c56151 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/Gopkg.lock @@ -0,0 +1,15 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/modern-go/concurrent" + packages = ["."] + revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a" + version = "1.0.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "daee8a88b3498b61c5640056665b8b9eea062006f5e596bbb6a3ed9119a11ec7" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/modern-go/reflect2/Gopkg.toml b/vendor/github.com/modern-go/reflect2/Gopkg.toml new file mode 100644 index 0000000000000000000000000000000000000000..2f4f4dbdcc5e525ede8544077e741dcff3265a8b --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/Gopkg.toml @@ -0,0 +1,35 @@ +# Gopkg.toml example +# +# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + +ignored = [] + +[[constraint]] + name = "github.com/modern-go/concurrent" + version = "1.0.0" + +[prune] + go-tests = true + unused-packages = true diff --git a/vendor/github.com/modern-go/reflect2/LICENSE b/vendor/github.com/modern-go/reflect2/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/modern-go/reflect2/README.md b/vendor/github.com/modern-go/reflect2/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6f968aab9ecbaeb92002a65d39f49682324387f3 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/README.md @@ -0,0 +1,71 @@ +# reflect2 + +[](https://sourcegraph.com/github.com/modern-go/reflect2?badge) +[](http://godoc.org/github.com/modern-go/reflect2) +[](https://travis-ci.org/modern-go/reflect2) +[](https://codecov.io/gh/modern-go/reflect2) +[](https://goreportcard.com/report/github.com/modern-go/reflect2) +[](https://raw.githubusercontent.com/modern-go/reflect2/master/LICENSE) + +reflect api that avoids runtime reflect.Value cost + +* reflect get/set interface{}, with type checking +* reflect get/set unsafe.Pointer, without type checking +* `reflect2.TypeByName` works like `Class.forName` found in java + +[json-iterator](https://github.com/json-iterator/go) use this package to save runtime dispatching cost. +This package is designed for low level libraries to optimize reflection performance. +General application should still use reflect standard library. + +# reflect2.TypeByName + +```go +// given package is github.com/your/awesome-package +type MyStruct struct { + // ... +} + +// will return the type +reflect2.TypeByName("awesome-package.MyStruct") +// however, if the type has not been used +// it will be eliminated by compiler, so we can not get it in runtime +``` + +# reflect2 get/set interface{} + +```go +valType := reflect2.TypeOf(1) +i := 1 +j := 10 +valType.Set(&i, &j) +// i will be 10 +``` + +to get set `type`, always use its pointer `*type` + +# reflect2 get/set unsafe.Pointer + +```go +valType := reflect2.TypeOf(1) +i := 1 +j := 10 +valType.UnsafeSet(unsafe.Pointer(&i), unsafe.Pointer(&j)) +// i will be 10 +``` + +to get set `type`, always use its pointer `*type` + +# benchmark + +Benchmark is not necessary for this package. It does nothing actually. +As it is just a thin wrapper to make go runtime public. +Both `reflect2` and `reflect` call same function +provided by `runtime` package exposed by go language. + +# unsafe safety + +Instead of casting `[]byte` to `sliceHeader` in your application using unsafe. +We can use reflect2 instead. This way, if `sliceHeader` changes in the future, +only reflect2 need to be upgraded. + +reflect2 tries its best to keep the implementation same as reflect (by testing). \ No newline at end of file diff --git a/vendor/github.com/modern-go/reflect2/go_above_17.go b/vendor/github.com/modern-go/reflect2/go_above_17.go new file mode 100644 index 0000000000000000000000000000000000000000..5c1cea8683ab30bf9aa5074043a1d5f630bd4374 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_above_17.go @@ -0,0 +1,8 @@ +//+build go1.7 + +package reflect2 + +import "unsafe" + +//go:linkname resolveTypeOff reflect.resolveTypeOff +func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer diff --git a/vendor/github.com/modern-go/reflect2/go_above_19.go b/vendor/github.com/modern-go/reflect2/go_above_19.go new file mode 100644 index 0000000000000000000000000000000000000000..c7e3b780116a3d19511c794daec40e65d74d9a5b --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_above_19.go @@ -0,0 +1,14 @@ +//+build go1.9 + +package reflect2 + +import ( + "unsafe" +) + +//go:linkname makemap reflect.makemap +func makemap(rtype unsafe.Pointer, cap int) (m unsafe.Pointer) + +func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer { + return makemap(rtype, cap) +} diff --git a/vendor/github.com/modern-go/reflect2/go_below_17.go b/vendor/github.com/modern-go/reflect2/go_below_17.go new file mode 100644 index 0000000000000000000000000000000000000000..65a93c889b77723b90545591ad3f34918b2e5e6c --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_below_17.go @@ -0,0 +1,9 @@ +//+build !go1.7 + +package reflect2 + +import "unsafe" + +func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer { + return nil +} diff --git a/vendor/github.com/modern-go/reflect2/go_below_19.go b/vendor/github.com/modern-go/reflect2/go_below_19.go new file mode 100644 index 0000000000000000000000000000000000000000..b050ef70cddbdc5d5c297ba16f0b0d114859e6bf --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_below_19.go @@ -0,0 +1,14 @@ +//+build !go1.9 + +package reflect2 + +import ( + "unsafe" +) + +//go:linkname makemap reflect.makemap +func makemap(rtype unsafe.Pointer) (m unsafe.Pointer) + +func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer { + return makemap(rtype) +} diff --git a/vendor/github.com/modern-go/reflect2/reflect2.go b/vendor/github.com/modern-go/reflect2/reflect2.go new file mode 100644 index 0000000000000000000000000000000000000000..63b49c799194729a141e9e03029d8b86b58171f9 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/reflect2.go @@ -0,0 +1,298 @@ +package reflect2 + +import ( + "github.com/modern-go/concurrent" + "reflect" + "unsafe" +) + +type Type interface { + Kind() reflect.Kind + // New return pointer to data of this type + New() interface{} + // UnsafeNew return the allocated space pointed by unsafe.Pointer + UnsafeNew() unsafe.Pointer + // PackEFace cast a unsafe pointer to object represented pointer + PackEFace(ptr unsafe.Pointer) interface{} + // Indirect dereference object represented pointer to this type + Indirect(obj interface{}) interface{} + // UnsafeIndirect dereference pointer to this type + UnsafeIndirect(ptr unsafe.Pointer) interface{} + // Type1 returns reflect.Type + Type1() reflect.Type + Implements(thatType Type) bool + String() string + RType() uintptr + // interface{} of this type has pointer like behavior + LikePtr() bool + IsNullable() bool + IsNil(obj interface{}) bool + UnsafeIsNil(ptr unsafe.Pointer) bool + Set(obj interface{}, val interface{}) + UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) + AssignableTo(anotherType Type) bool +} + +type ListType interface { + Type + Elem() Type + SetIndex(obj interface{}, index int, elem interface{}) + UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) + GetIndex(obj interface{}, index int) interface{} + UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer +} + +type ArrayType interface { + ListType + Len() int +} + +type SliceType interface { + ListType + MakeSlice(length int, cap int) interface{} + UnsafeMakeSlice(length int, cap int) unsafe.Pointer + Grow(obj interface{}, newLength int) + UnsafeGrow(ptr unsafe.Pointer, newLength int) + Append(obj interface{}, elem interface{}) + UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) + LengthOf(obj interface{}) int + UnsafeLengthOf(ptr unsafe.Pointer) int + SetNil(obj interface{}) + UnsafeSetNil(ptr unsafe.Pointer) + Cap(obj interface{}) int + UnsafeCap(ptr unsafe.Pointer) int +} + +type StructType interface { + Type + NumField() int + Field(i int) StructField + FieldByName(name string) StructField + FieldByIndex(index []int) StructField + FieldByNameFunc(match func(string) bool) StructField +} + +type StructField interface { + Offset() uintptr + Name() string + PkgPath() string + Type() Type + Tag() reflect.StructTag + Index() []int + Anonymous() bool + Set(obj interface{}, value interface{}) + UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) + Get(obj interface{}) interface{} + UnsafeGet(obj unsafe.Pointer) unsafe.Pointer +} + +type MapType interface { + Type + Key() Type + Elem() Type + MakeMap(cap int) interface{} + UnsafeMakeMap(cap int) unsafe.Pointer + SetIndex(obj interface{}, key interface{}, elem interface{}) + UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) + TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) + GetIndex(obj interface{}, key interface{}) interface{} + UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer + Iterate(obj interface{}) MapIterator + UnsafeIterate(obj unsafe.Pointer) MapIterator +} + +type MapIterator interface { + HasNext() bool + Next() (key interface{}, elem interface{}) + UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer) +} + +type PtrType interface { + Type + Elem() Type +} + +type InterfaceType interface { + NumMethod() int +} + +type Config struct { + UseSafeImplementation bool +} + +type API interface { + TypeOf(obj interface{}) Type + Type2(type1 reflect.Type) Type +} + +var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze() +var ConfigSafe = Config{UseSafeImplementation: true}.Froze() + +type frozenConfig struct { + useSafeImplementation bool + cache *concurrent.Map +} + +func (cfg Config) Froze() *frozenConfig { + return &frozenConfig{ + useSafeImplementation: cfg.UseSafeImplementation, + cache: concurrent.NewMap(), + } +} + +func (cfg *frozenConfig) TypeOf(obj interface{}) Type { + cacheKey := uintptr(unpackEFace(obj).rtype) + typeObj, found := cfg.cache.Load(cacheKey) + if found { + return typeObj.(Type) + } + return cfg.Type2(reflect.TypeOf(obj)) +} + +func (cfg *frozenConfig) Type2(type1 reflect.Type) Type { + if type1 == nil { + return nil + } + cacheKey := uintptr(unpackEFace(type1).data) + typeObj, found := cfg.cache.Load(cacheKey) + if found { + return typeObj.(Type) + } + type2 := cfg.wrapType(type1) + cfg.cache.Store(cacheKey, type2) + return type2 +} + +func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type { + safeType := safeType{Type: type1, cfg: cfg} + switch type1.Kind() { + case reflect.Struct: + if cfg.useSafeImplementation { + return &safeStructType{safeType} + } + return newUnsafeStructType(cfg, type1) + case reflect.Array: + if cfg.useSafeImplementation { + return &safeSliceType{safeType} + } + return newUnsafeArrayType(cfg, type1) + case reflect.Slice: + if cfg.useSafeImplementation { + return &safeSliceType{safeType} + } + return newUnsafeSliceType(cfg, type1) + case reflect.Map: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + return newUnsafeMapType(cfg, type1) + case reflect.Ptr, reflect.Chan, reflect.Func: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + return newUnsafePtrType(cfg, type1) + case reflect.Interface: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + if type1.NumMethod() == 0 { + return newUnsafeEFaceType(cfg, type1) + } + return newUnsafeIFaceType(cfg, type1) + default: + if cfg.useSafeImplementation { + return &safeType + } + return newUnsafeType(cfg, type1) + } +} + +func TypeOf(obj interface{}) Type { + return ConfigUnsafe.TypeOf(obj) +} + +func TypeOfPtr(obj interface{}) PtrType { + return TypeOf(obj).(PtrType) +} + +func Type2(type1 reflect.Type) Type { + if type1 == nil { + return nil + } + return ConfigUnsafe.Type2(type1) +} + +func PtrTo(typ Type) Type { + return Type2(reflect.PtrTo(typ.Type1())) +} + +func PtrOf(obj interface{}) unsafe.Pointer { + return unpackEFace(obj).data +} + +func RTypeOf(obj interface{}) uintptr { + return uintptr(unpackEFace(obj).rtype) +} + +func IsNil(obj interface{}) bool { + if obj == nil { + return true + } + return unpackEFace(obj).data == nil +} + +func IsNullable(kind reflect.Kind) bool { + switch kind { + case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface: + return true + } + return false +} + +func likePtrKind(kind reflect.Kind) bool { + switch kind { + case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func: + return true + } + return false +} + +func likePtrType(typ reflect.Type) bool { + if likePtrKind(typ.Kind()) { + return true + } + if typ.Kind() == reflect.Struct { + if typ.NumField() != 1 { + return false + } + return likePtrType(typ.Field(0).Type) + } + if typ.Kind() == reflect.Array { + if typ.Len() != 1 { + return false + } + return likePtrType(typ.Elem()) + } + return false +} + +// NoEscape hides a pointer from escape analysis. noescape is +// the identity function but escape analysis doesn't think the +// output depends on the input. noescape is inlined and currently +// compiles down to zero instructions. +// USE CAREFULLY! +//go:nosplit +func NoEscape(p unsafe.Pointer) unsafe.Pointer { + x := uintptr(p) + return unsafe.Pointer(x ^ 0) +} + +func UnsafeCastString(str string) []byte { + stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str)) + sliceHeader := &reflect.SliceHeader{ + Data: stringHeader.Data, + Cap: stringHeader.Len, + Len: stringHeader.Len, + } + return *(*[]byte)(unsafe.Pointer(sliceHeader)) +} diff --git a/vendor/github.com/modern-go/reflect2/reflect2_amd64.s b/vendor/github.com/modern-go/reflect2/reflect2_amd64.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/reflect2_kind.go b/vendor/github.com/modern-go/reflect2/reflect2_kind.go new file mode 100644 index 0000000000000000000000000000000000000000..62f299e40453622ade6e53e91beba8b5694ffc3d --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/reflect2_kind.go @@ -0,0 +1,30 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +// DefaultTypeOfKind return the non aliased default type for the kind +func DefaultTypeOfKind(kind reflect.Kind) Type { + return kindTypes[kind] +} + +var kindTypes = map[reflect.Kind]Type{ + reflect.Bool: TypeOf(true), + reflect.Uint8: TypeOf(uint8(0)), + reflect.Int8: TypeOf(int8(0)), + reflect.Uint16: TypeOf(uint16(0)), + reflect.Int16: TypeOf(int16(0)), + reflect.Uint32: TypeOf(uint32(0)), + reflect.Int32: TypeOf(int32(0)), + reflect.Uint64: TypeOf(uint64(0)), + reflect.Int64: TypeOf(int64(0)), + reflect.Uint: TypeOf(uint(0)), + reflect.Int: TypeOf(int(0)), + reflect.Float32: TypeOf(float32(0)), + reflect.Float64: TypeOf(float64(0)), + reflect.Uintptr: TypeOf(uintptr(0)), + reflect.String: TypeOf(""), + reflect.UnsafePointer: TypeOf(unsafe.Pointer(nil)), +} diff --git a/vendor/github.com/modern-go/reflect2/relfect2_386.s b/vendor/github.com/modern-go/reflect2/relfect2_386.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s b/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_arm.s b/vendor/github.com/modern-go/reflect2/relfect2_arm.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_arm64.s b/vendor/github.com/modern-go/reflect2/relfect2_arm64.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s b/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s b/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s b/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_s390x.s b/vendor/github.com/modern-go/reflect2/relfect2_s390x.s new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/github.com/modern-go/reflect2/safe_field.go b/vendor/github.com/modern-go/reflect2/safe_field.go new file mode 100644 index 0000000000000000000000000000000000000000..d4ba1f4f80e979f5157832f1f5014b9a63edbd9d --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_field.go @@ -0,0 +1,58 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeField struct { + reflect.StructField +} + +func (field *safeField) Offset() uintptr { + return field.StructField.Offset +} + +func (field *safeField) Name() string { + return field.StructField.Name +} + +func (field *safeField) PkgPath() string { + return field.StructField.PkgPath +} + +func (field *safeField) Type() Type { + panic("not implemented") +} + +func (field *safeField) Tag() reflect.StructTag { + return field.StructField.Tag +} + +func (field *safeField) Index() []int { + return field.StructField.Index +} + +func (field *safeField) Anonymous() bool { + return field.StructField.Anonymous +} + +func (field *safeField) Set(obj interface{}, value interface{}) { + val := reflect.ValueOf(obj).Elem() + val.FieldByIndex(field.Index()).Set(reflect.ValueOf(value).Elem()) +} + +func (field *safeField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) { + panic("unsafe operation is not supported") +} + +func (field *safeField) Get(obj interface{}) interface{} { + val := reflect.ValueOf(obj).Elem().FieldByIndex(field.Index()) + ptr := reflect.New(val.Type()) + ptr.Elem().Set(val) + return ptr.Interface() +} + +func (field *safeField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_map.go b/vendor/github.com/modern-go/reflect2/safe_map.go new file mode 100644 index 0000000000000000000000000000000000000000..88362205a2bb5d724b841bce797c75ff9893bb63 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_map.go @@ -0,0 +1,101 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeMapType struct { + safeType +} + +func (type2 *safeMapType) Key() Type { + return type2.safeType.cfg.Type2(type2.Type.Key()) +} + +func (type2 *safeMapType) MakeMap(cap int) interface{} { + ptr := reflect.New(type2.Type) + ptr.Elem().Set(reflect.MakeMap(type2.Type)) + return ptr.Interface() +} + +func (type2 *safeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { + keyVal := reflect.ValueOf(key) + elemVal := reflect.ValueOf(elem) + val := reflect.ValueOf(obj) + val.Elem().SetMapIndex(keyVal.Elem(), elemVal.Elem()) +} + +func (type2 *safeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { + keyVal := reflect.ValueOf(key) + if key == nil { + keyVal = reflect.New(type2.Type.Key()).Elem() + } + val := reflect.ValueOf(obj).MapIndex(keyVal) + if !val.IsValid() { + return nil, false + } + return val.Interface(), true +} + +func (type2 *safeMapType) GetIndex(obj interface{}, key interface{}) interface{} { + val := reflect.ValueOf(obj).Elem() + keyVal := reflect.ValueOf(key).Elem() + elemVal := val.MapIndex(keyVal) + if !elemVal.IsValid() { + ptr := reflect.New(reflect.PtrTo(val.Type().Elem())) + return ptr.Elem().Interface() + } + ptr := reflect.New(elemVal.Type()) + ptr.Elem().Set(elemVal) + return ptr.Interface() +} + +func (type2 *safeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) Iterate(obj interface{}) MapIterator { + m := reflect.ValueOf(obj).Elem() + return &safeMapIterator{ + m: m, + keys: m.MapKeys(), + } +} + +func (type2 *safeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + panic("does not support unsafe operation") +} + +type safeMapIterator struct { + i int + m reflect.Value + keys []reflect.Value +} + +func (iter *safeMapIterator) HasNext() bool { + return iter.i != len(iter.keys) +} + +func (iter *safeMapIterator) Next() (interface{}, interface{}) { + key := iter.keys[iter.i] + elem := iter.m.MapIndex(key) + iter.i += 1 + keyPtr := reflect.New(key.Type()) + keyPtr.Elem().Set(key) + elemPtr := reflect.New(elem.Type()) + elemPtr.Elem().Set(elem) + return keyPtr.Interface(), elemPtr.Interface() +} + +func (iter *safeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_slice.go b/vendor/github.com/modern-go/reflect2/safe_slice.go new file mode 100644 index 0000000000000000000000000000000000000000..bcce6fd20e5cfa99137433e84e033eaf7e162a82 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_slice.go @@ -0,0 +1,92 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeSliceType struct { + safeType +} + +func (type2 *safeSliceType) SetIndex(obj interface{}, index int, value interface{}) { + val := reflect.ValueOf(obj).Elem() + elem := reflect.ValueOf(value).Elem() + val.Index(index).Set(elem) +} + +func (type2 *safeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, value unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) GetIndex(obj interface{}, index int) interface{} { + val := reflect.ValueOf(obj).Elem() + elem := val.Index(index) + ptr := reflect.New(elem.Type()) + ptr.Elem().Set(elem) + return ptr.Interface() +} + +func (type2 *safeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) MakeSlice(length int, cap int) interface{} { + val := reflect.MakeSlice(type2.Type, length, cap) + ptr := reflect.New(val.Type()) + ptr.Elem().Set(val) + return ptr.Interface() +} + +func (type2 *safeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Grow(obj interface{}, newLength int) { + oldCap := type2.Cap(obj) + oldSlice := reflect.ValueOf(obj).Elem() + delta := newLength - oldCap + deltaVals := make([]reflect.Value, delta) + newSlice := reflect.Append(oldSlice, deltaVals...) + oldSlice.Set(newSlice) +} + +func (type2 *safeSliceType) UnsafeGrow(ptr unsafe.Pointer, newLength int) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Append(obj interface{}, elem interface{}) { + val := reflect.ValueOf(obj).Elem() + elemVal := reflect.ValueOf(elem).Elem() + newVal := reflect.Append(val, elemVal) + val.Set(newVal) +} + +func (type2 *safeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) SetNil(obj interface{}) { + val := reflect.ValueOf(obj).Elem() + val.Set(reflect.Zero(val.Type())) +} + +func (type2 *safeSliceType) UnsafeSetNil(ptr unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) LengthOf(obj interface{}) int { + return reflect.ValueOf(obj).Elem().Len() +} + +func (type2 *safeSliceType) UnsafeLengthOf(ptr unsafe.Pointer) int { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Cap(obj interface{}) int { + return reflect.ValueOf(obj).Elem().Cap() +} + +func (type2 *safeSliceType) UnsafeCap(ptr unsafe.Pointer) int { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_struct.go b/vendor/github.com/modern-go/reflect2/safe_struct.go new file mode 100644 index 0000000000000000000000000000000000000000..e5fb9b313ecdbad6ec3a57cf39872ab3a7dbc564 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_struct.go @@ -0,0 +1,29 @@ +package reflect2 + +type safeStructType struct { + safeType +} + +func (type2 *safeStructType) FieldByName(name string) StructField { + field, found := type2.Type.FieldByName(name) + if !found { + panic("field " + name + " not found") + } + return &safeField{StructField: field} +} + +func (type2 *safeStructType) Field(i int) StructField { + return &safeField{StructField: type2.Type.Field(i)} +} + +func (type2 *safeStructType) FieldByIndex(index []int) StructField { + return &safeField{StructField: type2.Type.FieldByIndex(index)} +} + +func (type2 *safeStructType) FieldByNameFunc(match func(string) bool) StructField { + field, found := type2.Type.FieldByNameFunc(match) + if !found { + panic("field match condition not found in " + type2.Type.String()) + } + return &safeField{StructField: field} +} diff --git a/vendor/github.com/modern-go/reflect2/safe_type.go b/vendor/github.com/modern-go/reflect2/safe_type.go new file mode 100644 index 0000000000000000000000000000000000000000..ee4e7bb6edfdd031eb6fc2c06a7550e249a6d0b7 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_type.go @@ -0,0 +1,78 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeType struct { + reflect.Type + cfg *frozenConfig +} + +func (type2 *safeType) New() interface{} { + return reflect.New(type2.Type).Interface() +} + +func (type2 *safeType) UnsafeNew() unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Elem() Type { + return type2.cfg.Type2(type2.Type.Elem()) +} + +func (type2 *safeType) Type1() reflect.Type { + return type2.Type +} + +func (type2 *safeType) PackEFace(ptr unsafe.Pointer) interface{} { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Implements(thatType Type) bool { + return type2.Type.Implements(thatType.Type1()) +} + +func (type2 *safeType) RType() uintptr { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Indirect(obj interface{}) interface{} { + return reflect.Indirect(reflect.ValueOf(obj)).Interface() +} + +func (type2 *safeType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + panic("does not support unsafe operation") +} + +func (type2 *safeType) LikePtr() bool { + panic("does not support unsafe operation") +} + +func (type2 *safeType) IsNullable() bool { + return IsNullable(type2.Kind()) +} + +func (type2 *safeType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + return reflect.ValueOf(obj).Elem().IsNil() +} + +func (type2 *safeType) UnsafeIsNil(ptr unsafe.Pointer) bool { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Set(obj interface{}, val interface{}) { + reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(val).Elem()) +} + +func (type2 *safeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeType) AssignableTo(anotherType Type) bool { + return type2.Type1().AssignableTo(anotherType.Type1()) +} diff --git a/vendor/github.com/modern-go/reflect2/test.sh b/vendor/github.com/modern-go/reflect2/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..3d2b9768ce6113106bb4d18ce6179a9ce4a79c80 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list github.com/modern-go/reflect2-tests/... | grep -v vendor); do + go test -coverprofile=profile.out -coverpkg=github.com/modern-go/reflect2 $d + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done diff --git a/vendor/github.com/modern-go/reflect2/type_map.go b/vendor/github.com/modern-go/reflect2/type_map.go new file mode 100644 index 0000000000000000000000000000000000000000..3acfb55803a832c5ea743febea5a9bcf3c875b3f --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/type_map.go @@ -0,0 +1,113 @@ +package reflect2 + +import ( + "reflect" + "runtime" + "strings" + "sync" + "unsafe" +) + +// typelinks1 for 1.5 ~ 1.6 +//go:linkname typelinks1 reflect.typelinks +func typelinks1() [][]unsafe.Pointer + +// typelinks2 for 1.7 ~ +//go:linkname typelinks2 reflect.typelinks +func typelinks2() (sections []unsafe.Pointer, offset [][]int32) + +// initOnce guards initialization of types and packages +var initOnce sync.Once + +var types map[string]reflect.Type +var packages map[string]map[string]reflect.Type + +// discoverTypes initializes types and packages +func discoverTypes() { + types = make(map[string]reflect.Type) + packages = make(map[string]map[string]reflect.Type) + + ver := runtime.Version() + if ver == "go1.5" || strings.HasPrefix(ver, "go1.5.") { + loadGo15Types() + } else if ver == "go1.6" || strings.HasPrefix(ver, "go1.6.") { + loadGo15Types() + } else { + loadGo17Types() + } +} + +func loadGo15Types() { + var obj interface{} = reflect.TypeOf(0) + typePtrss := typelinks1() + for _, typePtrs := range typePtrss { + for _, typePtr := range typePtrs { + (*emptyInterface)(unsafe.Pointer(&obj)).word = typePtr + typ := obj.(reflect.Type) + if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { + loadedType := typ.Elem() + pkgTypes := packages[loadedType.PkgPath()] + if pkgTypes == nil { + pkgTypes = map[string]reflect.Type{} + packages[loadedType.PkgPath()] = pkgTypes + } + types[loadedType.String()] = loadedType + pkgTypes[loadedType.Name()] = loadedType + } + if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Ptr && + typ.Elem().Elem().Kind() == reflect.Struct { + loadedType := typ.Elem().Elem() + pkgTypes := packages[loadedType.PkgPath()] + if pkgTypes == nil { + pkgTypes = map[string]reflect.Type{} + packages[loadedType.PkgPath()] = pkgTypes + } + types[loadedType.String()] = loadedType + pkgTypes[loadedType.Name()] = loadedType + } + } + } +} + +func loadGo17Types() { + var obj interface{} = reflect.TypeOf(0) + sections, offset := typelinks2() + for i, offs := range offset { + rodata := sections[i] + for _, off := range offs { + (*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off) + typ := obj.(reflect.Type) + if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { + loadedType := typ.Elem() + pkgTypes := packages[loadedType.PkgPath()] + if pkgTypes == nil { + pkgTypes = map[string]reflect.Type{} + packages[loadedType.PkgPath()] = pkgTypes + } + types[loadedType.String()] = loadedType + pkgTypes[loadedType.Name()] = loadedType + } + } + } +} + +type emptyInterface struct { + typ unsafe.Pointer + word unsafe.Pointer +} + +// TypeByName return the type by its name, just like Class.forName in java +func TypeByName(typeName string) Type { + initOnce.Do(discoverTypes) + return Type2(types[typeName]) +} + +// TypeByPackageName return the type by its package and name +func TypeByPackageName(pkgPath string, name string) Type { + initOnce.Do(discoverTypes) + pkgTypes := packages[pkgPath] + if pkgTypes == nil { + return nil + } + return Type2(pkgTypes[name]) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_array.go b/vendor/github.com/modern-go/reflect2/unsafe_array.go new file mode 100644 index 0000000000000000000000000000000000000000..76cbdba6eb1bb5814a1b0449f7c0706066badc2f --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_array.go @@ -0,0 +1,65 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeArrayType struct { + unsafeType + elemRType unsafe.Pointer + pElemRType unsafe.Pointer + elemSize uintptr + likePtr bool +} + +func newUnsafeArrayType(cfg *frozenConfig, type1 reflect.Type) *UnsafeArrayType { + return &UnsafeArrayType{ + unsafeType: *newUnsafeType(cfg, type1), + elemRType: unpackEFace(type1.Elem()).data, + pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, + elemSize: type1.Elem().Size(), + likePtr: likePtrType(type1), + } +} + +func (type2 *UnsafeArrayType) LikePtr() bool { + return type2.likePtr +} + +func (type2 *UnsafeArrayType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeArrayType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + if type2.likePtr { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) + } + return packEFace(type2.rtype, ptr) +} + +func (type2 *UnsafeArrayType) SetIndex(obj interface{}, index int, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("ArrayType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("ArrayType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) +} + +func (type2 *UnsafeArrayType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { + elemPtr := arrayAt(obj, index, type2.elemSize, "i < s.Len") + typedmemmove(type2.elemRType, elemPtr, elem) +} + +func (type2 *UnsafeArrayType) GetIndex(obj interface{}, index int) interface{} { + objEFace := unpackEFace(obj) + assertType("ArrayType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, index) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeArrayType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + return arrayAt(obj, index, type2.elemSize, "i < s.Len") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_eface.go b/vendor/github.com/modern-go/reflect2/unsafe_eface.go new file mode 100644 index 0000000000000000000000000000000000000000..805010f3a0c553db57da2e791ebbe15672b798a5 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_eface.go @@ -0,0 +1,59 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type eface struct { + rtype unsafe.Pointer + data unsafe.Pointer +} + +func unpackEFace(obj interface{}) *eface { + return (*eface)(unsafe.Pointer(&obj)) +} + +func packEFace(rtype unsafe.Pointer, data unsafe.Pointer) interface{} { + var i interface{} + e := (*eface)(unsafe.Pointer(&i)) + e.rtype = rtype + e.data = data + return i +} + +type UnsafeEFaceType struct { + unsafeType +} + +func newUnsafeEFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeEFaceType { + return &UnsafeEFaceType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafeEFaceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeEFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return unpackEFace(*(*interface{})(ptr)).data == nil +} + +func (type2 *UnsafeEFaceType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeEFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return *(*interface{})(ptr) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_field.go b/vendor/github.com/modern-go/reflect2/unsafe_field.go new file mode 100644 index 0000000000000000000000000000000000000000..5eb53130a20980ff9a150b60d3086b57077d9ddb --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_field.go @@ -0,0 +1,74 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeStructField struct { + reflect.StructField + structType *UnsafeStructType + rtype unsafe.Pointer + ptrRType unsafe.Pointer +} + +func newUnsafeStructField(structType *UnsafeStructType, structField reflect.StructField) *UnsafeStructField { + return &UnsafeStructField{ + StructField: structField, + rtype: unpackEFace(structField.Type).data, + ptrRType: unpackEFace(reflect.PtrTo(structField.Type)).data, + structType: structType, + } +} + +func (field *UnsafeStructField) Offset() uintptr { + return field.StructField.Offset +} + +func (field *UnsafeStructField) Name() string { + return field.StructField.Name +} + +func (field *UnsafeStructField) PkgPath() string { + return field.StructField.PkgPath +} + +func (field *UnsafeStructField) Type() Type { + return field.structType.cfg.Type2(field.StructField.Type) +} + +func (field *UnsafeStructField) Tag() reflect.StructTag { + return field.StructField.Tag +} + +func (field *UnsafeStructField) Index() []int { + return field.StructField.Index +} + +func (field *UnsafeStructField) Anonymous() bool { + return field.StructField.Anonymous +} + +func (field *UnsafeStructField) Set(obj interface{}, value interface{}) { + objEFace := unpackEFace(obj) + assertType("StructField.SetIndex argument 1", field.structType.ptrRType, objEFace.rtype) + valueEFace := unpackEFace(value) + assertType("StructField.SetIndex argument 2", field.ptrRType, valueEFace.rtype) + field.UnsafeSet(objEFace.data, valueEFace.data) +} + +func (field *UnsafeStructField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) { + fieldPtr := add(obj, field.StructField.Offset, "same as non-reflect &v.field") + typedmemmove(field.rtype, fieldPtr, value) +} + +func (field *UnsafeStructField) Get(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("StructField.GetIndex argument 1", field.structType.ptrRType, objEFace.rtype) + value := field.UnsafeGet(objEFace.data) + return packEFace(field.ptrRType, value) +} + +func (field *UnsafeStructField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer { + return add(obj, field.StructField.Offset, "same as non-reflect &v.field") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_iface.go b/vendor/github.com/modern-go/reflect2/unsafe_iface.go new file mode 100644 index 0000000000000000000000000000000000000000..b60195533ccf5f8bdb8087ac0a009b9be3b456a0 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_iface.go @@ -0,0 +1,64 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type iface struct { + itab *itab + data unsafe.Pointer +} + +type itab struct { + ignore unsafe.Pointer + rtype unsafe.Pointer +} + +func IFaceToEFace(ptr unsafe.Pointer) interface{} { + iface := (*iface)(ptr) + if iface.itab == nil { + return nil + } + return packEFace(iface.itab.rtype, iface.data) +} + +type UnsafeIFaceType struct { + unsafeType +} + +func newUnsafeIFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeIFaceType { + return &UnsafeIFaceType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafeIFaceType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeIFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return IFaceToEFace(ptr) +} + +func (type2 *UnsafeIFaceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeIFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + iface := (*iface)(ptr) + if iface.itab == nil { + return true + } + return false +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_link.go b/vendor/github.com/modern-go/reflect2/unsafe_link.go new file mode 100644 index 0000000000000000000000000000000000000000..57229c8db4170696bffde7177553a6d42c738e2f --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_link.go @@ -0,0 +1,70 @@ +package reflect2 + +import "unsafe" + +//go:linkname unsafe_New reflect.unsafe_New +func unsafe_New(rtype unsafe.Pointer) unsafe.Pointer + +//go:linkname typedmemmove reflect.typedmemmove +func typedmemmove(rtype unsafe.Pointer, dst, src unsafe.Pointer) + +//go:linkname unsafe_NewArray reflect.unsafe_NewArray +func unsafe_NewArray(rtype unsafe.Pointer, length int) unsafe.Pointer + +// typedslicecopy copies a slice of elemType values from src to dst, +// returning the number of elements copied. +//go:linkname typedslicecopy reflect.typedslicecopy +//go:noescape +func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int + +//go:linkname mapassign reflect.mapassign +//go:noescape +func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key, val unsafe.Pointer) + +//go:linkname mapaccess reflect.mapaccess +//go:noescape +func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer) + +// m escapes into the return value, but the caller of mapiterinit +// doesn't let the return value escape. +//go:noescape +//go:linkname mapiterinit reflect.mapiterinit +func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) *hiter + +//go:noescape +//go:linkname mapiternext reflect.mapiternext +func mapiternext(it *hiter) + +//go:linkname ifaceE2I reflect.ifaceE2I +func ifaceE2I(rtype unsafe.Pointer, src interface{}, dst unsafe.Pointer) + +// A hash iteration structure. +// If you modify hiter, also change cmd/internal/gc/reflect.go to indicate +// the layout of this structure. +type hiter struct { + key unsafe.Pointer // Must be in first position. Write nil to indicate iteration end (see cmd/internal/gc/range.go). + value unsafe.Pointer // Must be in second position (see cmd/internal/gc/range.go). + // rest fields are ignored +} + +// add returns p+x. +// +// The whySafe string is ignored, so that the function still inlines +// as efficiently as p+x, but all call sites should use the string to +// record why the addition is safe, which is to say why the addition +// does not cause x to advance to the very end of p's allocation +// and therefore point incorrectly at the next block in memory. +func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { + return unsafe.Pointer(uintptr(p) + x) +} + +// arrayAt returns the i-th element of p, +// an array whose elements are eltSize bytes wide. +// The array pointed at by p must have at least i+1 elements: +// it is invalid (but impossible to check here) to pass i >= len, +// because then the result will point outside the array. +// whySafe must explain why i < len. (Passing "i < len" is fine; +// the benefit is to surface this assumption at the call site.) +func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer { + return add(p, uintptr(i)*eltSize, "i < len") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_map.go b/vendor/github.com/modern-go/reflect2/unsafe_map.go new file mode 100644 index 0000000000000000000000000000000000000000..f2e76e6bb1491d1d47253252d66433386446ffc1 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_map.go @@ -0,0 +1,138 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeMapType struct { + unsafeType + pKeyRType unsafe.Pointer + pElemRType unsafe.Pointer +} + +func newUnsafeMapType(cfg *frozenConfig, type1 reflect.Type) MapType { + return &UnsafeMapType{ + unsafeType: *newUnsafeType(cfg, type1), + pKeyRType: unpackEFace(reflect.PtrTo(type1.Key())).data, + pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, + } +} + +func (type2 *UnsafeMapType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return *(*unsafe.Pointer)(ptr) == nil +} + +func (type2 *UnsafeMapType) LikePtr() bool { + return true +} + +func (type2 *UnsafeMapType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("MapType.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) +} + +func (type2 *UnsafeMapType) Key() Type { + return type2.cfg.Type2(type2.Type.Key()) +} + +func (type2 *UnsafeMapType) MakeMap(cap int) interface{} { + return packEFace(type2.ptrRType, type2.UnsafeMakeMap(cap)) +} + +func (type2 *UnsafeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { + m := makeMapWithSize(type2.rtype, cap) + return unsafe.Pointer(&m) +} + +func (type2 *UnsafeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("MapType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.SetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("MapType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, keyEFace.data, elemEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { + mapassign(type2.rtype, *(*unsafe.Pointer)(obj), key, elem) +} + +func (type2 *UnsafeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { + objEFace := unpackEFace(obj) + assertType("MapType.TryGetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.TryGetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data) + if elemPtr == nil { + return nil, false + } + return packEFace(type2.pElemRType, elemPtr), true +} + +func (type2 *UnsafeMapType) GetIndex(obj interface{}, key interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("MapType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.GetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { + return mapaccess(type2.rtype, *(*unsafe.Pointer)(obj), key) +} + +func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator { + objEFace := unpackEFace(obj) + assertType("MapType.Iterate argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIterate(objEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + return &UnsafeMapIterator{ + hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)), + pKeyRType: type2.pKeyRType, + pElemRType: type2.pElemRType, + } +} + +type UnsafeMapIterator struct { + *hiter + pKeyRType unsafe.Pointer + pElemRType unsafe.Pointer +} + +func (iter *UnsafeMapIterator) HasNext() bool { + return iter.key != nil +} + +func (iter *UnsafeMapIterator) Next() (interface{}, interface{}) { + key, elem := iter.UnsafeNext() + return packEFace(iter.pKeyRType, key), packEFace(iter.pElemRType, elem) +} + +func (iter *UnsafeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { + key := iter.key + elem := iter.value + mapiternext(iter.hiter) + return key, elem +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_ptr.go b/vendor/github.com/modern-go/reflect2/unsafe_ptr.go new file mode 100644 index 0000000000000000000000000000000000000000..8e5ec9cf45ed86b762db6244e2cb31b5b7dcead4 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_ptr.go @@ -0,0 +1,46 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafePtrType struct { + unsafeType +} + +func newUnsafePtrType(cfg *frozenConfig, type1 reflect.Type) *UnsafePtrType { + return &UnsafePtrType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafePtrType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafePtrType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return *(*unsafe.Pointer)(ptr) == nil +} + +func (type2 *UnsafePtrType) LikePtr() bool { + return true +} + +func (type2 *UnsafePtrType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafePtrType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_slice.go b/vendor/github.com/modern-go/reflect2/unsafe_slice.go new file mode 100644 index 0000000000000000000000000000000000000000..1c6d876c7f50256a9d8e44f0a00cddcce3ff0b60 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_slice.go @@ -0,0 +1,177 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +// sliceHeader is a safe version of SliceHeader used within this package. +type sliceHeader struct { + Data unsafe.Pointer + Len int + Cap int +} + +type UnsafeSliceType struct { + unsafeType + elemRType unsafe.Pointer + pElemRType unsafe.Pointer + elemSize uintptr +} + +func newUnsafeSliceType(cfg *frozenConfig, type1 reflect.Type) SliceType { + elemType := type1.Elem() + return &UnsafeSliceType{ + unsafeType: *newUnsafeType(cfg, type1), + pElemRType: unpackEFace(reflect.PtrTo(elemType)).data, + elemRType: unpackEFace(elemType).data, + elemSize: elemType.Size(), + } +} + +func (type2 *UnsafeSliceType) Set(obj interface{}, val interface{}) { + objEFace := unpackEFace(obj) + assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype) + valEFace := unpackEFace(val) + assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype) + type2.UnsafeSet(objEFace.data, valEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + *(*sliceHeader)(ptr) = *(*sliceHeader)(val) +} + +func (type2 *UnsafeSliceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return (*sliceHeader)(ptr).Data == nil +} + +func (type2 *UnsafeSliceType) SetNil(obj interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.SetNil argument 1", type2.ptrRType, objEFace.rtype) + type2.UnsafeSetNil(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSetNil(ptr unsafe.Pointer) { + header := (*sliceHeader)(ptr) + header.Len = 0 + header.Cap = 0 + header.Data = nil +} + +func (type2 *UnsafeSliceType) MakeSlice(length int, cap int) interface{} { + return packEFace(type2.ptrRType, type2.UnsafeMakeSlice(length, cap)) +} + +func (type2 *UnsafeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer { + header := &sliceHeader{unsafe_NewArray(type2.elemRType, cap), length, cap} + return unsafe.Pointer(header) +} + +func (type2 *UnsafeSliceType) LengthOf(obj interface{}) int { + objEFace := unpackEFace(obj) + assertType("SliceType.Len argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeLengthOf(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeLengthOf(obj unsafe.Pointer) int { + header := (*sliceHeader)(obj) + return header.Len +} + +func (type2 *UnsafeSliceType) SetIndex(obj interface{}, index int, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("SliceType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { + header := (*sliceHeader)(obj) + elemPtr := arrayAt(header.Data, index, type2.elemSize, "i < s.Len") + typedmemmove(type2.elemRType, elemPtr, elem) +} + +func (type2 *UnsafeSliceType) GetIndex(obj interface{}, index int) interface{} { + objEFace := unpackEFace(obj) + assertType("SliceType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, index) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + header := (*sliceHeader)(obj) + return arrayAt(header.Data, index, type2.elemSize, "i < s.Len") +} + +func (type2 *UnsafeSliceType) Append(obj interface{}, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.Append argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("SliceType.Append argument 2", type2.pElemRType, elemEFace.rtype) + type2.UnsafeAppend(objEFace.data, elemEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) { + header := (*sliceHeader)(obj) + oldLen := header.Len + type2.UnsafeGrow(obj, oldLen+1) + type2.UnsafeSetIndex(obj, oldLen, elem) +} + +func (type2 *UnsafeSliceType) Cap(obj interface{}) int { + objEFace := unpackEFace(obj) + assertType("SliceType.Cap argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeCap(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeCap(ptr unsafe.Pointer) int { + return (*sliceHeader)(ptr).Cap +} + +func (type2 *UnsafeSliceType) Grow(obj interface{}, newLength int) { + objEFace := unpackEFace(obj) + assertType("SliceType.Grow argument 1", type2.ptrRType, objEFace.rtype) + type2.UnsafeGrow(objEFace.data, newLength) +} + +func (type2 *UnsafeSliceType) UnsafeGrow(obj unsafe.Pointer, newLength int) { + header := (*sliceHeader)(obj) + if newLength <= header.Cap { + header.Len = newLength + return + } + newCap := calcNewCap(header.Cap, newLength) + newHeader := (*sliceHeader)(type2.UnsafeMakeSlice(header.Len, newCap)) + typedslicecopy(type2.elemRType, *newHeader, *header) + header.Data = newHeader.Data + header.Cap = newHeader.Cap + header.Len = newLength +} + +func calcNewCap(cap int, expectedCap int) int { + if cap == 0 { + cap = expectedCap + } else { + for cap < expectedCap { + if cap < 1024 { + cap += cap + } else { + cap += cap / 4 + } + } + } + return cap +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_struct.go b/vendor/github.com/modern-go/reflect2/unsafe_struct.go new file mode 100644 index 0000000000000000000000000000000000000000..804d9166397bb34b841b3081773a381c0758ca50 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_struct.go @@ -0,0 +1,59 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeStructType struct { + unsafeType + likePtr bool +} + +func newUnsafeStructType(cfg *frozenConfig, type1 reflect.Type) *UnsafeStructType { + return &UnsafeStructType{ + unsafeType: *newUnsafeType(cfg, type1), + likePtr: likePtrType(type1), + } +} + +func (type2 *UnsafeStructType) LikePtr() bool { + return type2.likePtr +} + +func (type2 *UnsafeStructType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeStructType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + if type2.likePtr { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) + } + return packEFace(type2.rtype, ptr) +} + +func (type2 *UnsafeStructType) FieldByName(name string) StructField { + structField, found := type2.Type.FieldByName(name) + if !found { + return nil + } + return newUnsafeStructField(type2, structField) +} + +func (type2 *UnsafeStructType) Field(i int) StructField { + return newUnsafeStructField(type2, type2.Type.Field(i)) +} + +func (type2 *UnsafeStructType) FieldByIndex(index []int) StructField { + return newUnsafeStructField(type2, type2.Type.FieldByIndex(index)) +} + +func (type2 *UnsafeStructType) FieldByNameFunc(match func(string) bool) StructField { + structField, found := type2.Type.FieldByNameFunc(match) + if !found { + panic("field match condition not found in " + type2.Type.String()) + } + return newUnsafeStructField(type2, structField) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_type.go b/vendor/github.com/modern-go/reflect2/unsafe_type.go new file mode 100644 index 0000000000000000000000000000000000000000..13941716ce3a2591df867f64b888266ef080e520 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_type.go @@ -0,0 +1,85 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type unsafeType struct { + safeType + rtype unsafe.Pointer + ptrRType unsafe.Pointer +} + +func newUnsafeType(cfg *frozenConfig, type1 reflect.Type) *unsafeType { + return &unsafeType{ + safeType: safeType{ + Type: type1, + cfg: cfg, + }, + rtype: unpackEFace(type1).data, + ptrRType: unpackEFace(reflect.PtrTo(type1)).data, + } +} + +func (type2 *unsafeType) Set(obj interface{}, val interface{}) { + objEFace := unpackEFace(obj) + assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype) + valEFace := unpackEFace(val) + assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype) + type2.UnsafeSet(objEFace.data, valEFace.data) +} + +func (type2 *unsafeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + typedmemmove(type2.rtype, ptr, val) +} + +func (type2 *unsafeType) IsNil(obj interface{}) bool { + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *unsafeType) UnsafeIsNil(ptr unsafe.Pointer) bool { + return ptr == nil +} + +func (type2 *unsafeType) UnsafeNew() unsafe.Pointer { + return unsafe_New(type2.rtype) +} + +func (type2 *unsafeType) New() interface{} { + return packEFace(type2.ptrRType, type2.UnsafeNew()) +} + +func (type2 *unsafeType) PackEFace(ptr unsafe.Pointer) interface{} { + return packEFace(type2.ptrRType, ptr) +} + +func (type2 *unsafeType) RType() uintptr { + return uintptr(type2.rtype) +} + +func (type2 *unsafeType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *unsafeType) UnsafeIndirect(obj unsafe.Pointer) interface{} { + return packEFace(type2.rtype, obj) +} + +func (type2 *unsafeType) LikePtr() bool { + return false +} + +func assertType(where string, expectRType unsafe.Pointer, actualRType unsafe.Pointer) { + if expectRType != actualRType { + expectType := reflect.TypeOf(0) + (*iface)(unsafe.Pointer(&expectType)).data = expectRType + actualType := reflect.TypeOf(0) + (*iface)(unsafe.Pointer(&actualType)).data = actualRType + panic(where + ": expect " + expectType.String() + ", actual " + actualType.String()) + } +} diff --git a/vendor/github.com/prometheus/client_golang/api/client.go b/vendor/github.com/prometheus/client_golang/api/client.go new file mode 100644 index 0000000000000000000000000000000000000000..f7ca60b6729d5974c6f590bb9e9205b798dba434 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/api/client.go @@ -0,0 +1,129 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package api provides clients for the HTTP APIs. +package api + +import ( + "context" + "io/ioutil" + "net" + "net/http" + "net/url" + "path" + "strings" + "time" +) + +// DefaultRoundTripper is used if no RoundTripper is set in Config. +var DefaultRoundTripper http.RoundTripper = &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext, + TLSHandshakeTimeout: 10 * time.Second, +} + +// Config defines configuration parameters for a new client. +type Config struct { + // The address of the Prometheus to connect to. + Address string + + // RoundTripper is used by the Client to drive HTTP requests. If not + // provided, DefaultRoundTripper will be used. + RoundTripper http.RoundTripper +} + +func (cfg *Config) roundTripper() http.RoundTripper { + if cfg.RoundTripper == nil { + return DefaultRoundTripper + } + return cfg.RoundTripper +} + +// Client is the interface for an API client. +type Client interface { + URL(ep string, args map[string]string) *url.URL + Do(context.Context, *http.Request) (*http.Response, []byte, error) +} + +// NewClient returns a new Client. +// +// It is safe to use the returned Client from multiple goroutines. +func NewClient(cfg Config) (Client, error) { + u, err := url.Parse(cfg.Address) + if err != nil { + return nil, err + } + u.Path = strings.TrimRight(u.Path, "/") + + return &httpClient{ + endpoint: u, + client: http.Client{Transport: cfg.roundTripper()}, + }, nil +} + +type httpClient struct { + endpoint *url.URL + client http.Client +} + +func (c *httpClient) URL(ep string, args map[string]string) *url.URL { + p := path.Join(c.endpoint.Path, ep) + + for arg, val := range args { + arg = ":" + arg + p = strings.Replace(p, arg, val, -1) + } + + u := *c.endpoint + u.Path = p + + return &u +} + +func (c *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) { + if ctx != nil { + req = req.WithContext(ctx) + } + resp, err := c.client.Do(req) + defer func() { + if resp != nil { + resp.Body.Close() + } + }() + + if err != nil { + return nil, nil, err + } + + var body []byte + done := make(chan struct{}) + go func() { + body, err = ioutil.ReadAll(resp.Body) + close(done) + }() + + select { + case <-ctx.Done(): + <-done + err = resp.Body.Close() + if err == nil { + err = ctx.Err() + } + case <-done: + } + + return resp, body, err +} diff --git a/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go b/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go new file mode 100644 index 0000000000000000000000000000000000000000..138a33b7dad97146028d1a3b494aa4163e0212a9 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go @@ -0,0 +1,1035 @@ +// Copyright 2017 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package v1 provides bindings to the Prometheus HTTP API v1: +// http://prometheus.io/docs/querying/api/ +package v1 + +import ( + "context" + "errors" + "fmt" + "math" + "net/http" + "net/url" + "strconv" + "strings" + "time" + "unsafe" + + json "github.com/json-iterator/go" + + "github.com/prometheus/common/model" + + "github.com/prometheus/client_golang/api" +) + +func init() { + json.RegisterTypeEncoderFunc("model.SamplePair", marshalPointJSON, marshalPointJSONIsEmpty) + json.RegisterTypeDecoderFunc("model.SamplePair", unMarshalPointJSON) +} + +func unMarshalPointJSON(ptr unsafe.Pointer, iter *json.Iterator) { + p := (*model.SamplePair)(ptr) + if !iter.ReadArray() { + iter.ReportError("unmarshal model.SamplePair", "SamplePair must be [timestamp, value]") + return + } + t := iter.ReadNumber() + if err := p.Timestamp.UnmarshalJSON([]byte(t)); err != nil { + iter.ReportError("unmarshal model.SamplePair", err.Error()) + return + } + if !iter.ReadArray() { + iter.ReportError("unmarshal model.SamplePair", "SamplePair missing value") + return + } + + f, err := strconv.ParseFloat(iter.ReadString(), 64) + if err != nil { + iter.ReportError("unmarshal model.SamplePair", err.Error()) + return + } + p.Value = model.SampleValue(f) + + if iter.ReadArray() { + iter.ReportError("unmarshal model.SamplePair", "SamplePair has too many values, must be [timestamp, value]") + return + } +} + +func marshalPointJSON(ptr unsafe.Pointer, stream *json.Stream) { + p := *((*model.SamplePair)(ptr)) + stream.WriteArrayStart() + // Write out the timestamp as a float divided by 1000. + // This is ~3x faster than converting to a float. + t := int64(p.Timestamp) + if t < 0 { + stream.WriteRaw(`-`) + t = -t + } + stream.WriteInt64(t / 1000) + fraction := t % 1000 + if fraction != 0 { + stream.WriteRaw(`.`) + if fraction < 100 { + stream.WriteRaw(`0`) + } + if fraction < 10 { + stream.WriteRaw(`0`) + } + stream.WriteInt64(fraction) + } + stream.WriteMore() + stream.WriteRaw(`"`) + + // Taken from https://github.com/json-iterator/go/blob/master/stream_float.go#L71 as a workaround + // to https://github.com/json-iterator/go/issues/365 (jsoniter, to follow json standard, doesn't allow inf/nan) + buf := stream.Buffer() + abs := math.Abs(float64(p.Value)) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if abs < 1e-6 || abs >= 1e21 { + fmt = 'e' + } + } + buf = strconv.AppendFloat(buf, float64(p.Value), fmt, -1, 64) + stream.SetBuffer(buf) + + stream.WriteRaw(`"`) + stream.WriteArrayEnd() + +} + +func marshalPointJSONIsEmpty(ptr unsafe.Pointer) bool { + return false +} + +const ( + apiPrefix = "/api/v1" + + epAlerts = apiPrefix + "/alerts" + epAlertManagers = apiPrefix + "/alertmanagers" + epQuery = apiPrefix + "/query" + epQueryRange = apiPrefix + "/query_range" + epLabels = apiPrefix + "/labels" + epLabelValues = apiPrefix + "/label/:name/values" + epSeries = apiPrefix + "/series" + epTargets = apiPrefix + "/targets" + epTargetsMetadata = apiPrefix + "/targets/metadata" + epMetadata = apiPrefix + "/metadata" + epRules = apiPrefix + "/rules" + epSnapshot = apiPrefix + "/admin/tsdb/snapshot" + epDeleteSeries = apiPrefix + "/admin/tsdb/delete_series" + epCleanTombstones = apiPrefix + "/admin/tsdb/clean_tombstones" + epConfig = apiPrefix + "/status/config" + epFlags = apiPrefix + "/status/flags" + epRuntimeinfo = apiPrefix + "/status/runtimeinfo" + epTSDB = apiPrefix + "/status/tsdb" +) + +// AlertState models the state of an alert. +type AlertState string + +// ErrorType models the different API error types. +type ErrorType string + +// HealthStatus models the health status of a scrape target. +type HealthStatus string + +// RuleType models the type of a rule. +type RuleType string + +// RuleHealth models the health status of a rule. +type RuleHealth string + +// MetricType models the type of a metric. +type MetricType string + +const ( + // Possible values for AlertState. + AlertStateFiring AlertState = "firing" + AlertStateInactive AlertState = "inactive" + AlertStatePending AlertState = "pending" + + // Possible values for ErrorType. + ErrBadData ErrorType = "bad_data" + ErrTimeout ErrorType = "timeout" + ErrCanceled ErrorType = "canceled" + ErrExec ErrorType = "execution" + ErrBadResponse ErrorType = "bad_response" + ErrServer ErrorType = "server_error" + ErrClient ErrorType = "client_error" + + // Possible values for HealthStatus. + HealthGood HealthStatus = "up" + HealthUnknown HealthStatus = "unknown" + HealthBad HealthStatus = "down" + + // Possible values for RuleType. + RuleTypeRecording RuleType = "recording" + RuleTypeAlerting RuleType = "alerting" + + // Possible values for RuleHealth. + RuleHealthGood = "ok" + RuleHealthUnknown = "unknown" + RuleHealthBad = "err" + + // Possible values for MetricType + MetricTypeCounter MetricType = "counter" + MetricTypeGauge MetricType = "gauge" + MetricTypeHistogram MetricType = "histogram" + MetricTypeGaugeHistogram MetricType = "gaugehistogram" + MetricTypeSummary MetricType = "summary" + MetricTypeInfo MetricType = "info" + MetricTypeStateset MetricType = "stateset" + MetricTypeUnknown MetricType = "unknown" +) + +// Error is an error returned by the API. +type Error struct { + Type ErrorType + Msg string + Detail string +} + +func (e *Error) Error() string { + return fmt.Sprintf("%s: %s", e.Type, e.Msg) +} + +// Range represents a sliced time range. +type Range struct { + // The boundaries of the time range. + Start, End time.Time + // The maximum time between two slices within the boundaries. + Step time.Duration +} + +// API provides bindings for Prometheus's v1 API. +type API interface { + // Alerts returns a list of all active alerts. + Alerts(ctx context.Context) (AlertsResult, error) + // AlertManagers returns an overview of the current state of the Prometheus alert manager discovery. + AlertManagers(ctx context.Context) (AlertManagersResult, error) + // CleanTombstones removes the deleted data from disk and cleans up the existing tombstones. + CleanTombstones(ctx context.Context) error + // Config returns the current Prometheus configuration. + Config(ctx context.Context) (ConfigResult, error) + // DeleteSeries deletes data for a selection of series in a time range. + DeleteSeries(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) error + // Flags returns the flag values that Prometheus was launched with. + Flags(ctx context.Context) (FlagsResult, error) + // LabelNames returns all the unique label names present in the block in sorted order. + LabelNames(ctx context.Context, startTime time.Time, endTime time.Time) ([]string, Warnings, error) + // LabelValues performs a query for the values of the given label. + LabelValues(ctx context.Context, label string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) + // Query performs a query for the given time. + Query(ctx context.Context, query string, ts time.Time) (model.Value, Warnings, error) + // QueryRange performs a query for the given range. + QueryRange(ctx context.Context, query string, r Range) (model.Value, Warnings, error) + // Runtimeinfo returns the various runtime information properties about the Prometheus server. + Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) + // Series finds series by label matchers. + Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, Warnings, error) + // Snapshot creates a snapshot of all current data into snapshots/<datetime>-<rand> + // under the TSDB's data directory and returns the directory as response. + Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) + // Rules returns a list of alerting and recording rules that are currently loaded. + Rules(ctx context.Context) (RulesResult, error) + // Targets returns an overview of the current state of the Prometheus target discovery. + Targets(ctx context.Context) (TargetsResult, error) + // TargetsMetadata returns metadata about metrics currently scraped by the target. + TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, error) + // Metadata returns metadata about metrics currently scraped by the metric name. + Metadata(ctx context.Context, metric string, limit string) (map[string][]Metadata, error) + // TSDB returns the cardinality statistics. + TSDB(ctx context.Context) (TSDBResult, error) +} + +// AlertsResult contains the result from querying the alerts endpoint. +type AlertsResult struct { + Alerts []Alert `json:"alerts"` +} + +// AlertManagersResult contains the result from querying the alertmanagers endpoint. +type AlertManagersResult struct { + Active []AlertManager `json:"activeAlertManagers"` + Dropped []AlertManager `json:"droppedAlertManagers"` +} + +// AlertManager models a configured Alert Manager. +type AlertManager struct { + URL string `json:"url"` +} + +// ConfigResult contains the result from querying the config endpoint. +type ConfigResult struct { + YAML string `json:"yaml"` +} + +// FlagsResult contains the result from querying the flag endpoint. +type FlagsResult map[string]string + +// RuntimeinfoResult contains the result from querying the runtimeinfo endpoint. +type RuntimeinfoResult struct { + StartTime time.Time `json:"startTime"` + CWD string `json:"CWD"` + ReloadConfigSuccess bool `json:"reloadConfigSuccess"` + LastConfigTime time.Time `json:"lastConfigTime"` + ChunkCount int `json:"chunkCount"` + TimeSeriesCount int `json:"timeSeriesCount"` + CorruptionCount int `json:"corruptionCount"` + GoroutineCount int `json:"goroutineCount"` + GOMAXPROCS int `json:"GOMAXPROCS"` + GOGC string `json:"GOGC"` + GODEBUG string `json:"GODEBUG"` + StorageRetention string `json:"storageRetention"` +} + +// SnapshotResult contains the result from querying the snapshot endpoint. +type SnapshotResult struct { + Name string `json:"name"` +} + +// RulesResult contains the result from querying the rules endpoint. +type RulesResult struct { + Groups []RuleGroup `json:"groups"` +} + +// RuleGroup models a rule group that contains a set of recording and alerting rules. +type RuleGroup struct { + Name string `json:"name"` + File string `json:"file"` + Interval float64 `json:"interval"` + Rules Rules `json:"rules"` +} + +// Recording and alerting rules are stored in the same slice to preserve the order +// that rules are returned in by the API. +// +// Rule types can be determined using a type switch: +// switch v := rule.(type) { +// case RecordingRule: +// fmt.Print("got a recording rule") +// case AlertingRule: +// fmt.Print("got a alerting rule") +// default: +// fmt.Printf("unknown rule type %s", v) +// } +type Rules []interface{} + +// AlertingRule models a alerting rule. +type AlertingRule struct { + Name string `json:"name"` + Query string `json:"query"` + Duration float64 `json:"duration"` + Labels model.LabelSet `json:"labels"` + Annotations model.LabelSet `json:"annotations"` + Alerts []*Alert `json:"alerts"` + Health RuleHealth `json:"health"` + LastError string `json:"lastError,omitempty"` +} + +// RecordingRule models a recording rule. +type RecordingRule struct { + Name string `json:"name"` + Query string `json:"query"` + Labels model.LabelSet `json:"labels,omitempty"` + Health RuleHealth `json:"health"` + LastError string `json:"lastError,omitempty"` +} + +// Alert models an active alert. +type Alert struct { + ActiveAt time.Time `json:"activeAt"` + Annotations model.LabelSet + Labels model.LabelSet + State AlertState + Value string +} + +// TargetsResult contains the result from querying the targets endpoint. +type TargetsResult struct { + Active []ActiveTarget `json:"activeTargets"` + Dropped []DroppedTarget `json:"droppedTargets"` +} + +// ActiveTarget models an active Prometheus scrape target. +type ActiveTarget struct { + DiscoveredLabels map[string]string `json:"discoveredLabels"` + Labels model.LabelSet `json:"labels"` + ScrapeURL string `json:"scrapeUrl"` + LastError string `json:"lastError"` + LastScrape time.Time `json:"lastScrape"` + Health HealthStatus `json:"health"` +} + +// DroppedTarget models a dropped Prometheus scrape target. +type DroppedTarget struct { + DiscoveredLabels map[string]string `json:"discoveredLabels"` +} + +// MetricMetadata models the metadata of a metric with its scrape target and name. +type MetricMetadata struct { + Target map[string]string `json:"target"` + Metric string `json:"metric,omitempty"` + Type MetricType `json:"type"` + Help string `json:"help"` + Unit string `json:"unit"` +} + +// Metadata models the metadata of a metric. +type Metadata struct { + Type MetricType `json:"type"` + Help string `json:"help"` + Unit string `json:"unit"` +} + +// queryResult contains result data for a query. +type queryResult struct { + Type model.ValueType `json:"resultType"` + Result interface{} `json:"result"` + + // The decoded value. + v model.Value +} + +// TSDBResult contains the result from querying the tsdb endpoint. +type TSDBResult struct { + SeriesCountByMetricName []Stat `json:"seriesCountByMetricName"` + LabelValueCountByLabelName []Stat `json:"labelValueCountByLabelName"` + MemoryInBytesByLabelName []Stat `json:"memoryInBytesByLabelName"` + SeriesCountByLabelValuePair []Stat `json:"seriesCountByLabelValuePair"` +} + +// Stat models information about statistic value. +type Stat struct { + Name string `json:"name"` + Value uint64 `json:"value"` +} + +func (rg *RuleGroup) UnmarshalJSON(b []byte) error { + v := struct { + Name string `json:"name"` + File string `json:"file"` + Interval float64 `json:"interval"` + Rules []json.RawMessage `json:"rules"` + }{} + + if err := json.Unmarshal(b, &v); err != nil { + return err + } + + rg.Name = v.Name + rg.File = v.File + rg.Interval = v.Interval + + for _, rule := range v.Rules { + alertingRule := AlertingRule{} + if err := json.Unmarshal(rule, &alertingRule); err == nil { + rg.Rules = append(rg.Rules, alertingRule) + continue + } + recordingRule := RecordingRule{} + if err := json.Unmarshal(rule, &recordingRule); err == nil { + rg.Rules = append(rg.Rules, recordingRule) + continue + } + return errors.New("failed to decode JSON into an alerting or recording rule") + } + + return nil +} + +func (r *AlertingRule) UnmarshalJSON(b []byte) error { + v := struct { + Type string `json:"type"` + }{} + if err := json.Unmarshal(b, &v); err != nil { + return err + } + if v.Type == "" { + return errors.New("type field not present in rule") + } + if v.Type != string(RuleTypeAlerting) { + return fmt.Errorf("expected rule of type %s but got %s", string(RuleTypeAlerting), v.Type) + } + + rule := struct { + Name string `json:"name"` + Query string `json:"query"` + Duration float64 `json:"duration"` + Labels model.LabelSet `json:"labels"` + Annotations model.LabelSet `json:"annotations"` + Alerts []*Alert `json:"alerts"` + Health RuleHealth `json:"health"` + LastError string `json:"lastError,omitempty"` + }{} + if err := json.Unmarshal(b, &rule); err != nil { + return err + } + r.Health = rule.Health + r.Annotations = rule.Annotations + r.Name = rule.Name + r.Query = rule.Query + r.Alerts = rule.Alerts + r.Duration = rule.Duration + r.Labels = rule.Labels + r.LastError = rule.LastError + + return nil +} + +func (r *RecordingRule) UnmarshalJSON(b []byte) error { + v := struct { + Type string `json:"type"` + }{} + if err := json.Unmarshal(b, &v); err != nil { + return err + } + if v.Type == "" { + return errors.New("type field not present in rule") + } + if v.Type != string(RuleTypeRecording) { + return fmt.Errorf("expected rule of type %s but got %s", string(RuleTypeRecording), v.Type) + } + + rule := struct { + Name string `json:"name"` + Query string `json:"query"` + Labels model.LabelSet `json:"labels,omitempty"` + Health RuleHealth `json:"health"` + LastError string `json:"lastError,omitempty"` + }{} + if err := json.Unmarshal(b, &rule); err != nil { + return err + } + r.Health = rule.Health + r.Labels = rule.Labels + r.Name = rule.Name + r.LastError = rule.LastError + r.Query = rule.Query + + return nil +} + +func (qr *queryResult) UnmarshalJSON(b []byte) error { + v := struct { + Type model.ValueType `json:"resultType"` + Result json.RawMessage `json:"result"` + }{} + + err := json.Unmarshal(b, &v) + if err != nil { + return err + } + + switch v.Type { + case model.ValScalar: + var sv model.Scalar + err = json.Unmarshal(v.Result, &sv) + qr.v = &sv + + case model.ValVector: + var vv model.Vector + err = json.Unmarshal(v.Result, &vv) + qr.v = vv + + case model.ValMatrix: + var mv model.Matrix + err = json.Unmarshal(v.Result, &mv) + qr.v = mv + + default: + err = fmt.Errorf("unexpected value type %q", v.Type) + } + return err +} + +// NewAPI returns a new API for the client. +// +// It is safe to use the returned API from multiple goroutines. +func NewAPI(c api.Client) API { + return &httpAPI{ + client: &apiClientImpl{ + client: c, + }, + } +} + +type httpAPI struct { + client apiClient +} + +func (h *httpAPI) Alerts(ctx context.Context) (AlertsResult, error) { + u := h.client.URL(epAlerts, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return AlertsResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return AlertsResult{}, err + } + + var res AlertsResult + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) AlertManagers(ctx context.Context) (AlertManagersResult, error) { + u := h.client.URL(epAlertManagers, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return AlertManagersResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return AlertManagersResult{}, err + } + + var res AlertManagersResult + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) CleanTombstones(ctx context.Context) error { + u := h.client.URL(epCleanTombstones, nil) + + req, err := http.NewRequest(http.MethodPost, u.String(), nil) + if err != nil { + return err + } + + _, _, _, err = h.client.Do(ctx, req) + return err +} + +func (h *httpAPI) Config(ctx context.Context) (ConfigResult, error) { + u := h.client.URL(epConfig, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return ConfigResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return ConfigResult{}, err + } + + var res ConfigResult + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) DeleteSeries(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) error { + u := h.client.URL(epDeleteSeries, nil) + q := u.Query() + + for _, m := range matches { + q.Add("match[]", m) + } + + q.Set("start", formatTime(startTime)) + q.Set("end", formatTime(endTime)) + + u.RawQuery = q.Encode() + + req, err := http.NewRequest(http.MethodPost, u.String(), nil) + if err != nil { + return err + } + + _, _, _, err = h.client.Do(ctx, req) + return err +} + +func (h *httpAPI) Flags(ctx context.Context) (FlagsResult, error) { + u := h.client.URL(epFlags, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return FlagsResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return FlagsResult{}, err + } + + var res FlagsResult + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) { + u := h.client.URL(epRuntimeinfo, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return RuntimeinfoResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return RuntimeinfoResult{}, err + } + + var res RuntimeinfoResult + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) LabelNames(ctx context.Context, startTime time.Time, endTime time.Time) ([]string, Warnings, error) { + u := h.client.URL(epLabels, nil) + q := u.Query() + q.Set("start", formatTime(startTime)) + q.Set("end", formatTime(endTime)) + + u.RawQuery = q.Encode() + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return nil, nil, err + } + _, body, w, err := h.client.Do(ctx, req) + if err != nil { + return nil, w, err + } + var labelNames []string + return labelNames, w, json.Unmarshal(body, &labelNames) +} + +func (h *httpAPI) LabelValues(ctx context.Context, label string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) { + u := h.client.URL(epLabelValues, map[string]string{"name": label}) + q := u.Query() + q.Set("start", formatTime(startTime)) + q.Set("end", formatTime(endTime)) + + u.RawQuery = q.Encode() + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return nil, nil, err + } + _, body, w, err := h.client.Do(ctx, req) + if err != nil { + return nil, w, err + } + var labelValues model.LabelValues + return labelValues, w, json.Unmarshal(body, &labelValues) +} + +func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time) (model.Value, Warnings, error) { + u := h.client.URL(epQuery, nil) + q := u.Query() + + q.Set("query", query) + if !ts.IsZero() { + q.Set("time", formatTime(ts)) + } + + _, body, warnings, err := h.client.DoGetFallback(ctx, u, q) + if err != nil { + return nil, warnings, err + } + + var qres queryResult + return model.Value(qres.v), warnings, json.Unmarshal(body, &qres) +} + +func (h *httpAPI) QueryRange(ctx context.Context, query string, r Range) (model.Value, Warnings, error) { + u := h.client.URL(epQueryRange, nil) + q := u.Query() + + q.Set("query", query) + q.Set("start", formatTime(r.Start)) + q.Set("end", formatTime(r.End)) + q.Set("step", strconv.FormatFloat(r.Step.Seconds(), 'f', -1, 64)) + + _, body, warnings, err := h.client.DoGetFallback(ctx, u, q) + if err != nil { + return nil, warnings, err + } + + var qres queryResult + + return model.Value(qres.v), warnings, json.Unmarshal(body, &qres) +} + +func (h *httpAPI) Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, Warnings, error) { + u := h.client.URL(epSeries, nil) + q := u.Query() + + for _, m := range matches { + q.Add("match[]", m) + } + + q.Set("start", formatTime(startTime)) + q.Set("end", formatTime(endTime)) + + u.RawQuery = q.Encode() + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return nil, nil, err + } + + _, body, warnings, err := h.client.Do(ctx, req) + if err != nil { + return nil, warnings, err + } + + var mset []model.LabelSet + return mset, warnings, json.Unmarshal(body, &mset) +} + +func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) { + u := h.client.URL(epSnapshot, nil) + q := u.Query() + + q.Set("skip_head", strconv.FormatBool(skipHead)) + + u.RawQuery = q.Encode() + + req, err := http.NewRequest(http.MethodPost, u.String(), nil) + if err != nil { + return SnapshotResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return SnapshotResult{}, err + } + + var res SnapshotResult + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) Rules(ctx context.Context) (RulesResult, error) { + u := h.client.URL(epRules, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return RulesResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return RulesResult{}, err + } + + var res RulesResult + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) Targets(ctx context.Context) (TargetsResult, error) { + u := h.client.URL(epTargets, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return TargetsResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return TargetsResult{}, err + } + + var res TargetsResult + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, error) { + u := h.client.URL(epTargetsMetadata, nil) + q := u.Query() + + q.Set("match_target", matchTarget) + q.Set("metric", metric) + q.Set("limit", limit) + + u.RawQuery = q.Encode() + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return nil, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return nil, err + } + + var res []MetricMetadata + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) Metadata(ctx context.Context, metric string, limit string) (map[string][]Metadata, error) { + u := h.client.URL(epMetadata, nil) + q := u.Query() + + q.Set("metric", metric) + q.Set("limit", limit) + + u.RawQuery = q.Encode() + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return nil, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return nil, err + } + + var res map[string][]Metadata + return res, json.Unmarshal(body, &res) +} + +func (h *httpAPI) TSDB(ctx context.Context) (TSDBResult, error) { + u := h.client.URL(epTSDB, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return TSDBResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return TSDBResult{}, err + } + + var res TSDBResult + return res, json.Unmarshal(body, &res) + +} + +// Warnings is an array of non critical errors +type Warnings []string + +// apiClient wraps a regular client and processes successful API responses. +// Successful also includes responses that errored at the API level. +type apiClient interface { + URL(ep string, args map[string]string) *url.URL + Do(context.Context, *http.Request) (*http.Response, []byte, Warnings, error) + DoGetFallback(ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Warnings, error) +} + +type apiClientImpl struct { + client api.Client +} + +type apiResponse struct { + Status string `json:"status"` + Data json.RawMessage `json:"data"` + ErrorType ErrorType `json:"errorType"` + Error string `json:"error"` + Warnings []string `json:"warnings,omitempty"` +} + +func apiError(code int) bool { + // These are the codes that Prometheus sends when it returns an error. + return code == http.StatusUnprocessableEntity || code == http.StatusBadRequest +} + +func errorTypeAndMsgFor(resp *http.Response) (ErrorType, string) { + switch resp.StatusCode / 100 { + case 4: + return ErrClient, fmt.Sprintf("client error: %d", resp.StatusCode) + case 5: + return ErrServer, fmt.Sprintf("server error: %d", resp.StatusCode) + } + return ErrBadResponse, fmt.Sprintf("bad response code %d", resp.StatusCode) +} + +func (h *apiClientImpl) URL(ep string, args map[string]string) *url.URL { + return h.client.URL(ep, args) +} + +func (h *apiClientImpl) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, Warnings, error) { + resp, body, err := h.client.Do(ctx, req) + if err != nil { + return resp, body, nil, err + } + + code := resp.StatusCode + + if code/100 != 2 && !apiError(code) { + errorType, errorMsg := errorTypeAndMsgFor(resp) + return resp, body, nil, &Error{ + Type: errorType, + Msg: errorMsg, + Detail: string(body), + } + } + + var result apiResponse + + if http.StatusNoContent != code { + if jsonErr := json.Unmarshal(body, &result); jsonErr != nil { + return resp, body, nil, &Error{ + Type: ErrBadResponse, + Msg: jsonErr.Error(), + } + } + } + + if apiError(code) && result.Status == "success" { + err = &Error{ + Type: ErrBadResponse, + Msg: "inconsistent body for response code", + } + } + + if result.Status == "error" { + err = &Error{ + Type: result.ErrorType, + Msg: result.Error, + } + } + + return resp, []byte(result.Data), result.Warnings, err + +} + +// DoGetFallback will attempt to do the request as-is, and on a 405 or 501 it +// will fallback to a GET request. +func (h *apiClientImpl) DoGetFallback(ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Warnings, error) { + req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(args.Encode())) + if err != nil { + return nil, nil, nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + resp, body, warnings, err := h.Do(ctx, req) + if resp != nil && (resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotImplemented) { + u.RawQuery = args.Encode() + req, err = http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return nil, nil, warnings, err + } + + } else { + if err != nil { + return resp, body, warnings, err + } + return resp, body, warnings, nil + } + return h.Do(ctx, req) +} + +func formatTime(t time.Time) string { + return strconv.FormatFloat(float64(t.Unix())+float64(t.Nanosecond())/1e9, 'f', -1, 64) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 1625b6827ec11a050140864d155b7dc356f2770a..1c7c5e2ab03df791f669b2f01bdd061462c371c1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -63,6 +63,8 @@ github.com/grpc-ecosystem/grpc-gateway/utilities github.com/jmcvetta/randutil # github.com/jonboulle/clockwork v0.1.0 github.com/jonboulle/clockwork +# github.com/json-iterator/go v1.1.10 +github.com/json-iterator/go # github.com/konsorten/go-windows-terminal-sequences v1.0.3 github.com/konsorten/go-windows-terminal-sequences # github.com/lpar/gzipped v1.1.1-0.20190413023519-5d9a18ea7f47 @@ -73,14 +75,21 @@ github.com/matttproud/golang_protobuf_extensions/pbutil # github.com/miekg/dns v1.1.38 ## explicit github.com/miekg/dns +# github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd +github.com/modern-go/concurrent +# github.com/modern-go/reflect2 v1.0.1 +github.com/modern-go/reflect2 # github.com/prometheus/client_golang v1.9.0 ## explicit +github.com/prometheus/client_golang/api +github.com/prometheus/client_golang/api/prometheus/v1 github.com/prometheus/client_golang/prometheus github.com/prometheus/client_golang/prometheus/internal github.com/prometheus/client_golang/prometheus/promhttp # github.com/prometheus/client_model v0.2.0 github.com/prometheus/client_model/go # github.com/prometheus/common v0.15.0 +## explicit github.com/prometheus/common/expfmt github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg github.com/prometheus/common/model