From 4b25d4e8dbdfbbee7a0b24d801dffe09a17c0212 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 3 Apr 2015 18:55:48 -0700 Subject: [PATCH 1/3] Use verifyError instead of parsResponse, also get rid of mxj dependency --- pkg/api/api_test.go | 51 ++++++--------------------------------------- 1 file changed, 6 insertions(+), 45 deletions(-) diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index 367226012..50d07a6ea 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -18,12 +18,9 @@ package api_test import ( "bytes" - "encoding/xml" "io" "io/ioutil" "log" - "net/http" - "net/http/httptest" "os" "reflect" "strconv" @@ -31,7 +28,10 @@ import ( "testing" "time" - "github.com/clbanning/mxj" + "encoding/xml" + "net/http" + "net/http/httptest" + "github.com/minio-io/minio/pkg/api" "github.com/minio-io/minio/pkg/drivers" "github.com/minio-io/minio/pkg/drivers/donut" @@ -116,34 +116,6 @@ func (s *MySuite) TearDownTest(c *C) { s.Root = "" } -/* **** SAMPLE ERROR RESPONSE **** - - - AccessDenied - Access Denied - /mybucket/myphoto.jpg - F19772218238A85A - GuWkjyviSiGHizehqpmsD1ndz5NClSP19DOT+s2mv7gXGQ8/X1lhbDGiIJEXpGFD - -*/ - -type responseMap struct { - res *http.Response // response headers - resMsg mxj.Map // Keys: Code, Message, Resource, RequestId, HostId -} - -// parseResponse returns a new initialized S3.Error structure -func parseResponse(res *http.Response) (*responseMap, error) { - var err error - resp := responseMap{} - resp.res = res - resp.resMsg, err = mxj.NewMapXmlReader(res.Body) - if err != nil { - return nil, err - } - return &resp, nil -} - func (s *MySuite) TestNonExistantObject(c *C) { switch driver := s.Driver.(type) { case *mocks.Driver: @@ -303,13 +275,7 @@ func (s *MySuite) TestMultipleObjects(c *C) { typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNotFound{}).Once() response, err := http.Get(testServer.URL + "/bucket/object") c.Assert(err, IsNil) - responseMap, err := parseResponse(response) - c.Assert(err, IsNil) - c.Assert(responseMap.res.StatusCode, Equals, http.StatusNotFound) - values, err := responseMap.resMsg.ValuesForKey("Code") - c.Assert(err, IsNil) - c.Assert(values[0], Equals, "NoSuchKey") - + verifyError(c, response, "NoSuchKey", "The specified key does not exist.", http.StatusNotFound) //// test object 1 // get object @@ -416,12 +382,7 @@ func (s *MySuite) TestHeader(c *C) { typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNotFound{}).Once() response, err := http.Get(testServer.URL + "/bucket/object") c.Assert(err, IsNil) - responseMap, err := parseResponse(response) - c.Assert(err, IsNil) - c.Assert(responseMap.res.StatusCode, Equals, http.StatusNotFound) - values, err := responseMap.resMsg.ValuesForKey("Code") - c.Assert(err, IsNil) - c.Assert(values[0], Equals, "NoSuchKey") + verifyError(c, response, "NoSuchKey", "The specified key does not exist.", http.StatusNotFound) buffer := bytes.NewBufferString("hello world") typedDriver.On("CreateBucket", "bucket").Return(nil).Once() From 4079dd1d12b4dc7d86fa8b553ac78a186e33ae12 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 3 Apr 2015 18:57:40 -0700 Subject: [PATCH 2/3] Commit testify,objx, gorilla/mux, minio-io/erasure gopkg.in/check.v1 --- pkg/api/Godeps/Godeps.json | 41 + pkg/api/Godeps/Readme | 5 + pkg/api/Godeps/_workspace/.gitignore | 2 + .../github.com/gorilla/context/.travis.yml | 7 + .../src/github.com/gorilla/context/LICENSE | 27 + .../src/github.com/gorilla/context/README.md | 7 + .../src/github.com/gorilla/context/context.go | 143 + .../gorilla/context/context_test.go | 161 + .../src/github.com/gorilla/context/doc.go | 82 + .../src/github.com/gorilla/mux/.travis.yml | 7 + .../src/github.com/gorilla/mux/LICENSE | 27 + .../src/github.com/gorilla/mux/README.md | 7 + .../src/github.com/gorilla/mux/bench_test.go | 21 + .../src/github.com/gorilla/mux/doc.go | 199 + .../src/github.com/gorilla/mux/mux.go | 353 + .../src/github.com/gorilla/mux/mux_test.go | 943 +++ .../src/github.com/gorilla/mux/old_test.go | 714 ++ .../src/github.com/gorilla/mux/regexp.go | 276 + .../src/github.com/gorilla/mux/route.go | 524 ++ .../github.com/minio-io/erasure/.gitignore | 6 + .../github.com/minio-io/erasure/BUILDDEPS.md | 80 + .../minio-io/erasure/CONTRIBUTING.md | 30 + .../github.com/minio-io/erasure/LICENSE.INTEL | 26 + .../github.com/minio-io/erasure/LICENSE.MINIO | 202 + .../src/github.com/minio-io/erasure/README.md | 25 + .../minio-io/erasure/RELEASE-NOTES.INTEL | 49 + .../minio-io/erasure/RELEASE-NOTES.MINIO | 3 + .../minio-io/erasure/cauchy_test.go | 71 + .../src/github.com/minio-io/erasure/ctypes.go | 59 + .../src/github.com/minio-io/erasure/doc.go | 67 + .../erasure/docs/isa-l_open_src_2.10.pdf | 5429 ++++++++++++++ .../erasure/docs/isa-l_open_src_2.13.pdf | Bin 0 -> 270361 bytes .../src/github.com/minio-io/erasure/ec_base.c | 348 + .../src/github.com/minio-io/erasure/ec_base.h | 6680 +++++++++++++++++ .../src/github.com/minio-io/erasure/ec_code.h | 933 +++ .../minio-io/erasure/ec_highlevel_func.c | 267 + .../github.com/minio-io/erasure/ec_isal-l.h | 41 + .../minio-io/erasure/ec_minio_common.h | 39 + .../minio-io/erasure/ec_minio_decode.c | 134 + .../minio-io/erasure/ec_minio_encode.c | 59 + .../minio-io/erasure/ec_multibinary.asm | 462 ++ .../minio-io/erasure/ec_reg_sizes.asm | 96 + .../github.com/minio-io/erasure/ec_types.h | 80 + .../minio-io/erasure/erasure_decode.go | 122 + .../minio-io/erasure/erasure_encode.go | 197 + .../minio-io/erasure/erasure_yasm_darwin.go | 43 + .../minio-io/erasure/erasure_yasm_linux.go | 43 + .../minio-io/erasure/erasure_yasm_windows.go | 43 + .../erasure/gf_2vect_dot_prod_avx.asm | 381 + .../erasure/gf_2vect_dot_prod_avx2.asm | 398 + .../erasure/gf_2vect_dot_prod_sse.asm | 383 + .../minio-io/erasure/gf_2vect_mad_avx.asm | 264 + .../minio-io/erasure/gf_2vect_mad_avx2.asm | 280 + .../minio-io/erasure/gf_2vect_mad_sse.asm | 267 + .../erasure/gf_3vect_dot_prod_avx.asm | 421 ++ .../erasure/gf_3vect_dot_prod_avx2.asm | 441 ++ .../erasure/gf_3vect_dot_prod_sse.asm | 422 ++ .../minio-io/erasure/gf_3vect_mad_avx.asm | 315 + .../minio-io/erasure/gf_3vect_mad_avx2.asm | 347 + .../minio-io/erasure/gf_3vect_mad_sse.asm | 326 + .../erasure/gf_4vect_dot_prod_avx.asm | 489 ++ .../erasure/gf_4vect_dot_prod_avx2.asm | 510 ++ .../erasure/gf_4vect_dot_prod_sse.asm | 491 ++ .../minio-io/erasure/gf_4vect_mad_avx.asm | 370 + .../minio-io/erasure/gf_4vect_mad_avx2.asm | 371 + .../minio-io/erasure/gf_4vect_mad_sse.asm | 375 + .../erasure/gf_5vect_dot_prod_avx.asm | 348 + .../erasure/gf_5vect_dot_prod_avx2.asm | 362 + .../erasure/gf_5vect_dot_prod_sse.asm | 349 + .../minio-io/erasure/gf_5vect_mad_avx.asm | 401 + .../minio-io/erasure/gf_5vect_mad_avx2.asm | 393 + .../minio-io/erasure/gf_5vect_mad_sse.asm | 409 + .../erasure/gf_6vect_dot_prod_avx.asm | 360 + .../erasure/gf_6vect_dot_prod_avx2.asm | 373 + .../erasure/gf_6vect_dot_prod_sse.asm | 360 + .../minio-io/erasure/gf_6vect_mad_avx.asm | 433 ++ .../minio-io/erasure/gf_6vect_mad_avx2.asm | 435 ++ .../minio-io/erasure/gf_6vect_mad_sse.asm | 446 ++ .../minio-io/erasure/gf_vect_dot_prod_avx.asm | 303 + .../erasure/gf_vect_dot_prod_avx2.asm | 315 + .../minio-io/erasure/gf_vect_dot_prod_sse.asm | 303 + .../minio-io/erasure/gf_vect_mad_avx.asm | 223 + .../minio-io/erasure/gf_vect_mad_avx2.asm | 233 + .../minio-io/erasure/gf_vect_mad_sse.asm | 224 + .../github.com/minio-io/erasure/gf_vect_mul.h | 148 + .../minio-io/erasure/gf_vect_mul_avx.asm | 189 + .../minio-io/erasure/gf_vect_mul_sse.asm | 195 + .../src/github.com/minio-io/erasure/stdint.go | 38 + .../minio-io/erasure/vandermonde_test.go | 66 + .../src/github.com/minio-io/iodine/.gitignore | 24 + .../src/github.com/minio-io/iodine/LICENSE | 202 + .../src/github.com/minio-io/iodine/README.md | 2 + .../src/github.com/minio-io/iodine/iodine.go | 201 + .../github.com/minio-io/iodine/iodine_test.go | 97 + .../src/github.com/stretchr/objx/.gitignore | 22 + .../src/github.com/stretchr/objx/LICENSE.md | 23 + .../src/github.com/stretchr/objx/README.md | 3 + .../src/github.com/stretchr/objx/accessors.go | 179 + .../stretchr/objx/accessors_test.go | 145 + .../stretchr/objx/codegen/array-access.txt | 14 + .../stretchr/objx/codegen/index.html | 86 + .../stretchr/objx/codegen/template.txt | 286 + .../stretchr/objx/codegen/types_list.txt | 20 + .../src/github.com/stretchr/objx/constants.go | 13 + .../github.com/stretchr/objx/conversions.go | 117 + .../stretchr/objx/conversions_test.go | 94 + .../src/github.com/stretchr/objx/doc.go | 72 + .../github.com/stretchr/objx/fixture_test.go | 98 + .../src/github.com/stretchr/objx/map.go | 222 + .../github.com/stretchr/objx/map_for_test.go | 10 + .../src/github.com/stretchr/objx/map_test.go | 147 + .../src/github.com/stretchr/objx/mutations.go | 81 + .../stretchr/objx/mutations_test.go | 77 + .../src/github.com/stretchr/objx/security.go | 14 + .../github.com/stretchr/objx/security_test.go | 12 + .../stretchr/objx/simple_example_test.go | 41 + .../src/github.com/stretchr/objx/tests.go | 17 + .../github.com/stretchr/objx/tests_test.go | 24 + .../stretchr/objx/type_specific_codegen.go | 2881 +++++++ .../objx/type_specific_codegen_test.go | 2867 +++++++ .../src/github.com/stretchr/objx/value.go | 13 + .../github.com/stretchr/objx/value_test.go | 1 + .../stretchr/testify/assert/assertions.go | 805 ++ .../testify/assert/assertions_test.go | 768 ++ .../github.com/stretchr/testify/assert/doc.go | 150 + .../stretchr/testify/assert/errors.go | 10 + .../testify/assert/forward_assertions.go | 262 + .../testify/assert/forward_assertions_test.go | 526 ++ .../testify/assert/http_assertions.go | 157 + .../testify/assert/http_assertions_test.go | 86 + .../github.com/stretchr/testify/mock/doc.go | 43 + .../github.com/stretchr/testify/mock/mock.go | 510 ++ .../stretchr/testify/mock/mock_test.go | 669 ++ .../src/gopkg.in/check.v1/.gitignore | 4 + .../_workspace/src/gopkg.in/check.v1/LICENSE | 25 + .../src/gopkg.in/check.v1/README.md | 20 + .../_workspace/src/gopkg.in/check.v1/TODO | 2 + .../src/gopkg.in/check.v1/benchmark.go | 163 + .../src/gopkg.in/check.v1/benchmark_test.go | 91 + .../src/gopkg.in/check.v1/bootstrap_test.go | 82 + .../_workspace/src/gopkg.in/check.v1/check.go | 945 +++ .../src/gopkg.in/check.v1/check_test.go | 207 + .../src/gopkg.in/check.v1/checkers.go | 458 ++ .../src/gopkg.in/check.v1/checkers_test.go | 272 + .../src/gopkg.in/check.v1/export_test.go | 9 + .../src/gopkg.in/check.v1/fixture_test.go | 484 ++ .../src/gopkg.in/check.v1/foundation_test.go | 335 + .../src/gopkg.in/check.v1/helpers.go | 231 + .../src/gopkg.in/check.v1/helpers_test.go | 519 ++ .../src/gopkg.in/check.v1/printer.go | 168 + .../src/gopkg.in/check.v1/printer_test.go | 104 + .../_workspace/src/gopkg.in/check.v1/run.go | 175 + .../src/gopkg.in/check.v1/run_test.go | 419 ++ 153 files changed, 49741 insertions(+) create mode 100644 pkg/api/Godeps/Godeps.json create mode 100644 pkg/api/Godeps/Readme create mode 100644 pkg/api/Godeps/_workspace/.gitignore create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/context/.travis.yml create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/context/LICENSE create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/context/README.md create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/context/context.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/context/context_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/context/doc.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/LICENSE create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/README.md create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/bench_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/doc.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/mux.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/mux_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/old_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/regexp.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/route.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/.gitignore create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/BUILDDEPS.md create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/CONTRIBUTING.md create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/LICENSE.INTEL create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/LICENSE.MINIO create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/README.md create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/RELEASE-NOTES.INTEL create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/RELEASE-NOTES.MINIO create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/cauchy_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ctypes.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/doc.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/docs/isa-l_open_src_2.10.pdf create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/docs/isa-l_open_src_2.13.pdf create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_base.c create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_base.h create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_code.h create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_highlevel_func.c create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_isal-l.h create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_common.h create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_decode.c create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_encode.c create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_multibinary.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_reg_sizes.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_types.h create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_decode.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_encode.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_darwin.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_linux.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_windows.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_avx2.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul.h create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul_avx.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul_sse.asm create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/stdint.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/vandermonde_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/.gitignore create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/LICENSE create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/README.md create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/iodine.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/iodine_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/.gitignore create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/LICENSE.md create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/README.md create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/accessors.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/accessors_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/array-access.txt create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/index.html create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/template.txt create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/types_list.txt create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/constants.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/conversions.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/conversions_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/doc.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/fixture_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map_for_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/mutations.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/mutations_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/security.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/security_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/simple_example_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/tests.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/tests_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/value.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/value_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/errors.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions_test.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/doc.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go create mode 100644 pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/.gitignore create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/LICENSE create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/README.md create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/TODO create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/check.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/check_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/checkers.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/export_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/helpers.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/printer.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/run.go create mode 100644 pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go diff --git a/pkg/api/Godeps/Godeps.json b/pkg/api/Godeps/Godeps.json new file mode 100644 index 000000000..1cd7f813f --- /dev/null +++ b/pkg/api/Godeps/Godeps.json @@ -0,0 +1,41 @@ +{ + "ImportPath": "github.com/minio-io/minio/pkg/api", + "GoVersion": "go1.4", + "Packages": [ + "./..." + ], + "Deps": [ + { + "ImportPath": "github.com/gorilla/context", + "Rev": "50c25fb3b2b3b3cc724e9b6ac75fb44b3bccd0da" + }, + { + "ImportPath": "github.com/gorilla/mux", + "Rev": "e444e69cbd2e2e3e0749a2f3c717cec491552bbf" + }, + { + "ImportPath": "github.com/minio-io/erasure", + "Rev": "3cece1a107115563682604b1430418e28f65dd80" + }, + { + "ImportPath": "github.com/minio-io/iodine", + "Rev": "55cc4d4256c68fbd6f0775f1a25e37e6a2f6457e" + }, + { + "ImportPath": "github.com/stretchr/objx", + "Rev": "cbeaeb16a013161a98496fad62933b1d21786672" + }, + { + "ImportPath": "github.com/stretchr/testify/assert", + "Rev": "e4ec8152c15fc46bd5056ce65997a07c7d415325" + }, + { + "ImportPath": "github.com/stretchr/testify/mock", + "Rev": "e4ec8152c15fc46bd5056ce65997a07c7d415325" + }, + { + "ImportPath": "gopkg.in/check.v1", + "Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673" + } + ] +} diff --git a/pkg/api/Godeps/Readme b/pkg/api/Godeps/Readme new file mode 100644 index 000000000..4cdaa53d5 --- /dev/null +++ b/pkg/api/Godeps/Readme @@ -0,0 +1,5 @@ +This directory tree is generated automatically by godep. + +Please do not edit. + +See https://github.com/tools/godep for more information. diff --git a/pkg/api/Godeps/_workspace/.gitignore b/pkg/api/Godeps/_workspace/.gitignore new file mode 100644 index 000000000..f037d684e --- /dev/null +++ b/pkg/api/Godeps/_workspace/.gitignore @@ -0,0 +1,2 @@ +/pkg +/bin diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/.travis.yml b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/.travis.yml new file mode 100644 index 000000000..d87d46576 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/.travis.yml @@ -0,0 +1,7 @@ +language: go + +go: + - 1.0 + - 1.1 + - 1.2 + - tip diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/LICENSE b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/LICENSE new file mode 100644 index 000000000..0e5fb8728 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 Rodrigo Moraes. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/README.md b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/README.md new file mode 100644 index 000000000..c60a31b05 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/README.md @@ -0,0 +1,7 @@ +context +======= +[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context) + +gorilla/context is a general purpose registry for global request variables. + +Read the full documentation here: http://www.gorillatoolkit.org/pkg/context diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/context.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/context.go new file mode 100644 index 000000000..81cb128b1 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/context.go @@ -0,0 +1,143 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package context + +import ( + "net/http" + "sync" + "time" +) + +var ( + mutex sync.RWMutex + data = make(map[*http.Request]map[interface{}]interface{}) + datat = make(map[*http.Request]int64) +) + +// Set stores a value for a given key in a given request. +func Set(r *http.Request, key, val interface{}) { + mutex.Lock() + if data[r] == nil { + data[r] = make(map[interface{}]interface{}) + datat[r] = time.Now().Unix() + } + data[r][key] = val + mutex.Unlock() +} + +// Get returns a value stored for a given key in a given request. +func Get(r *http.Request, key interface{}) interface{} { + mutex.RLock() + if ctx := data[r]; ctx != nil { + value := ctx[key] + mutex.RUnlock() + return value + } + mutex.RUnlock() + return nil +} + +// GetOk returns stored value and presence state like multi-value return of map access. +func GetOk(r *http.Request, key interface{}) (interface{}, bool) { + mutex.RLock() + if _, ok := data[r]; ok { + value, ok := data[r][key] + mutex.RUnlock() + return value, ok + } + mutex.RUnlock() + return nil, false +} + +// GetAll returns all stored values for the request as a map. Nil is returned for invalid requests. +func GetAll(r *http.Request) map[interface{}]interface{} { + mutex.RLock() + if context, ok := data[r]; ok { + result := make(map[interface{}]interface{}, len(context)) + for k, v := range context { + result[k] = v + } + mutex.RUnlock() + return result + } + mutex.RUnlock() + return nil +} + +// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if +// the request was registered. +func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) { + mutex.RLock() + context, ok := data[r] + result := make(map[interface{}]interface{}, len(context)) + for k, v := range context { + result[k] = v + } + mutex.RUnlock() + return result, ok +} + +// Delete removes a value stored for a given key in a given request. +func Delete(r *http.Request, key interface{}) { + mutex.Lock() + if data[r] != nil { + delete(data[r], key) + } + mutex.Unlock() +} + +// Clear removes all values stored for a given request. +// +// This is usually called by a handler wrapper to clean up request +// variables at the end of a request lifetime. See ClearHandler(). +func Clear(r *http.Request) { + mutex.Lock() + clear(r) + mutex.Unlock() +} + +// clear is Clear without the lock. +func clear(r *http.Request) { + delete(data, r) + delete(datat, r) +} + +// Purge removes request data stored for longer than maxAge, in seconds. +// It returns the amount of requests removed. +// +// If maxAge <= 0, all request data is removed. +// +// This is only used for sanity check: in case context cleaning was not +// properly set some request data can be kept forever, consuming an increasing +// amount of memory. In case this is detected, Purge() must be called +// periodically until the problem is fixed. +func Purge(maxAge int) int { + mutex.Lock() + count := 0 + if maxAge <= 0 { + count = len(data) + data = make(map[*http.Request]map[interface{}]interface{}) + datat = make(map[*http.Request]int64) + } else { + min := time.Now().Unix() - int64(maxAge) + for r := range data { + if datat[r] < min { + clear(r) + count++ + } + } + } + mutex.Unlock() + return count +} + +// ClearHandler wraps an http.Handler and clears request values at the end +// of a request lifetime. +func ClearHandler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer Clear(r) + h.ServeHTTP(w, r) + }) +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/context_test.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/context_test.go new file mode 100644 index 000000000..9814c501e --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/context_test.go @@ -0,0 +1,161 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package context + +import ( + "net/http" + "testing" +) + +type keyType int + +const ( + key1 keyType = iota + key2 +) + +func TestContext(t *testing.T) { + assertEqual := func(val interface{}, exp interface{}) { + if val != exp { + t.Errorf("Expected %v, got %v.", exp, val) + } + } + + r, _ := http.NewRequest("GET", "http://localhost:8080/", nil) + emptyR, _ := http.NewRequest("GET", "http://localhost:8080/", nil) + + // Get() + assertEqual(Get(r, key1), nil) + + // Set() + Set(r, key1, "1") + assertEqual(Get(r, key1), "1") + assertEqual(len(data[r]), 1) + + Set(r, key2, "2") + assertEqual(Get(r, key2), "2") + assertEqual(len(data[r]), 2) + + //GetOk + value, ok := GetOk(r, key1) + assertEqual(value, "1") + assertEqual(ok, true) + + value, ok = GetOk(r, "not exists") + assertEqual(value, nil) + assertEqual(ok, false) + + Set(r, "nil value", nil) + value, ok = GetOk(r, "nil value") + assertEqual(value, nil) + assertEqual(ok, true) + + // GetAll() + values := GetAll(r) + assertEqual(len(values), 3) + + // GetAll() for empty request + values = GetAll(emptyR) + if values != nil { + t.Error("GetAll didn't return nil value for invalid request") + } + + // GetAllOk() + values, ok = GetAllOk(r) + assertEqual(len(values), 3) + assertEqual(ok, true) + + // GetAllOk() for empty request + values, ok = GetAllOk(emptyR) + assertEqual(value, nil) + assertEqual(ok, false) + + // Delete() + Delete(r, key1) + assertEqual(Get(r, key1), nil) + assertEqual(len(data[r]), 2) + + Delete(r, key2) + assertEqual(Get(r, key2), nil) + assertEqual(len(data[r]), 1) + + // Clear() + Clear(r) + assertEqual(len(data), 0) +} + +func parallelReader(r *http.Request, key string, iterations int, wait, done chan struct{}) { + <-wait + for i := 0; i < iterations; i++ { + Get(r, key) + } + done <- struct{}{} + +} + +func parallelWriter(r *http.Request, key, value string, iterations int, wait, done chan struct{}) { + <-wait + for i := 0; i < iterations; i++ { + Set(r, key, value) + } + done <- struct{}{} + +} + +func benchmarkMutex(b *testing.B, numReaders, numWriters, iterations int) { + + b.StopTimer() + r, _ := http.NewRequest("GET", "http://localhost:8080/", nil) + done := make(chan struct{}) + b.StartTimer() + + for i := 0; i < b.N; i++ { + wait := make(chan struct{}) + + for i := 0; i < numReaders; i++ { + go parallelReader(r, "test", iterations, wait, done) + } + + for i := 0; i < numWriters; i++ { + go parallelWriter(r, "test", "123", iterations, wait, done) + } + + close(wait) + + for i := 0; i < numReaders+numWriters; i++ { + <-done + } + + } + +} + +func BenchmarkMutexSameReadWrite1(b *testing.B) { + benchmarkMutex(b, 1, 1, 32) +} +func BenchmarkMutexSameReadWrite2(b *testing.B) { + benchmarkMutex(b, 2, 2, 32) +} +func BenchmarkMutexSameReadWrite4(b *testing.B) { + benchmarkMutex(b, 4, 4, 32) +} +func BenchmarkMutex1(b *testing.B) { + benchmarkMutex(b, 2, 8, 32) +} +func BenchmarkMutex2(b *testing.B) { + benchmarkMutex(b, 16, 4, 64) +} +func BenchmarkMutex3(b *testing.B) { + benchmarkMutex(b, 1, 2, 128) +} +func BenchmarkMutex4(b *testing.B) { + benchmarkMutex(b, 128, 32, 256) +} +func BenchmarkMutex5(b *testing.B) { + benchmarkMutex(b, 1024, 2048, 64) +} +func BenchmarkMutex6(b *testing.B) { + benchmarkMutex(b, 2048, 1024, 512) +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/doc.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/doc.go new file mode 100644 index 000000000..73c740031 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/context/doc.go @@ -0,0 +1,82 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package context stores values shared during a request lifetime. + +For example, a router can set variables extracted from the URL and later +application handlers can access those values, or it can be used to store +sessions values to be saved at the end of a request. There are several +others common uses. + +The idea was posted by Brad Fitzpatrick to the go-nuts mailing list: + + http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53 + +Here's the basic usage: first define the keys that you will need. The key +type is interface{} so a key can be of any type that supports equality. +Here we define a key using a custom int type to avoid name collisions: + + package foo + + import ( + "github.com/gorilla/context" + ) + + type key int + + const MyKey key = 0 + +Then set a variable. Variables are bound to an http.Request object, so you +need a request instance to set a value: + + context.Set(r, MyKey, "bar") + +The application can later access the variable using the same key you provided: + + func MyHandler(w http.ResponseWriter, r *http.Request) { + // val is "bar". + val := context.Get(r, foo.MyKey) + + // returns ("bar", true) + val, ok := context.GetOk(r, foo.MyKey) + // ... + } + +And that's all about the basic usage. We discuss some other ideas below. + +Any type can be stored in the context. To enforce a given type, make the key +private and wrap Get() and Set() to accept and return values of a specific +type: + + type key int + + const mykey key = 0 + + // GetMyKey returns a value for this package from the request values. + func GetMyKey(r *http.Request) SomeType { + if rv := context.Get(r, mykey); rv != nil { + return rv.(SomeType) + } + return nil + } + + // SetMyKey sets a value for this package in the request values. + func SetMyKey(r *http.Request, val SomeType) { + context.Set(r, mykey, val) + } + +Variables must be cleared at the end of a request, to remove all values +that were stored. This can be done in an http.Handler, after a request was +served. Just call Clear() passing the request: + + context.Clear(r) + +...or use ClearHandler(), which conveniently wraps an http.Handler to clear +variables at the end of a request lifetime. + +The Routers from the packages gorilla/mux and gorilla/pat call Clear() +so if you are using either of them you don't need to clear the context manually. +*/ +package context diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml new file mode 100644 index 000000000..d87d46576 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml @@ -0,0 +1,7 @@ +language: go + +go: + - 1.0 + - 1.1 + - 1.2 + - tip diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/LICENSE b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/LICENSE new file mode 100644 index 000000000..0e5fb8728 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 Rodrigo Moraes. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/README.md b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/README.md new file mode 100644 index 000000000..e60301b03 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/README.md @@ -0,0 +1,7 @@ +mux +=== +[![Build Status](https://travis-ci.org/gorilla/mux.png?branch=master)](https://travis-ci.org/gorilla/mux) + +gorilla/mux is a powerful URL router and dispatcher. + +Read the full documentation here: http://www.gorillatoolkit.org/pkg/mux diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/bench_test.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/bench_test.go new file mode 100644 index 000000000..c5f97b2b2 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/bench_test.go @@ -0,0 +1,21 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "net/http" + "testing" +) + +func BenchmarkMux(b *testing.B) { + router := new(Router) + handler := func(w http.ResponseWriter, r *http.Request) {} + router.HandleFunc("/v1/{v1}", handler) + + request, _ := http.NewRequest("GET", "/v1/anything", nil) + for i := 0; i < b.N; i++ { + router.ServeHTTP(nil, request) + } +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/doc.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/doc.go new file mode 100644 index 000000000..b2deed34c --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/doc.go @@ -0,0 +1,199 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package gorilla/mux implements a request router and dispatcher. + +The name mux stands for "HTTP request multiplexer". Like the standard +http.ServeMux, mux.Router matches incoming requests against a list of +registered routes and calls a handler for the route that matches the URL +or other conditions. The main features are: + + * Requests can be matched based on URL host, path, path prefix, schemes, + header and query values, HTTP methods or using custom matchers. + * URL hosts and paths can have variables with an optional regular + expression. + * Registered URLs can be built, or "reversed", which helps maintaining + references to resources. + * Routes can be used as subrouters: nested routes are only tested if the + parent route matches. This is useful to define groups of routes that + share common conditions like a host, a path prefix or other repeated + attributes. As a bonus, this optimizes request matching. + * It implements the http.Handler interface so it is compatible with the + standard http.ServeMux. + +Let's start registering a couple of URL paths and handlers: + + func main() { + r := mux.NewRouter() + r.HandleFunc("/", HomeHandler) + r.HandleFunc("/products", ProductsHandler) + r.HandleFunc("/articles", ArticlesHandler) + http.Handle("/", r) + } + +Here we register three routes mapping URL paths to handlers. This is +equivalent to how http.HandleFunc() works: if an incoming request URL matches +one of the paths, the corresponding handler is called passing +(http.ResponseWriter, *http.Request) as parameters. + +Paths can have variables. They are defined using the format {name} or +{name:pattern}. If a regular expression pattern is not defined, the matched +variable will be anything until the next slash. For example: + + r := mux.NewRouter() + r.HandleFunc("/products/{key}", ProductHandler) + r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) + r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) + +The names are used to create a map of route variables which can be retrieved +calling mux.Vars(): + + vars := mux.Vars(request) + category := vars["category"] + +And this is all you need to know about the basic usage. More advanced options +are explained below. + +Routes can also be restricted to a domain or subdomain. Just define a host +pattern to be matched. They can also have variables: + + r := mux.NewRouter() + // Only matches if domain is "www.domain.com". + r.Host("www.domain.com") + // Matches a dynamic subdomain. + r.Host("{subdomain:[a-z]+}.domain.com") + +There are several other matchers that can be added. To match path prefixes: + + r.PathPrefix("/products/") + +...or HTTP methods: + + r.Methods("GET", "POST") + +...or URL schemes: + + r.Schemes("https") + +...or header values: + + r.Headers("X-Requested-With", "XMLHttpRequest") + +...or query values: + + r.Queries("key", "value") + +...or to use a custom matcher function: + + r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { + return r.ProtoMajor == 0 + }) + +...and finally, it is possible to combine several matchers in a single route: + + r.HandleFunc("/products", ProductsHandler). + Host("www.domain.com"). + Methods("GET"). + Schemes("http") + +Setting the same matching conditions again and again can be boring, so we have +a way to group several routes that share the same requirements. +We call it "subrouting". + +For example, let's say we have several URLs that should only match when the +host is "www.domain.com". Create a route for that host and get a "subrouter" +from it: + + r := mux.NewRouter() + s := r.Host("www.domain.com").Subrouter() + +Then register routes in the subrouter: + + s.HandleFunc("/products/", ProductsHandler) + s.HandleFunc("/products/{key}", ProductHandler) + s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) + +The three URL paths we registered above will only be tested if the domain is +"www.domain.com", because the subrouter is tested first. This is not +only convenient, but also optimizes request matching. You can create +subrouters combining any attribute matchers accepted by a route. + +Subrouters can be used to create domain or path "namespaces": you define +subrouters in a central place and then parts of the app can register its +paths relatively to a given subrouter. + +There's one more thing about subroutes. When a subrouter has a path prefix, +the inner routes use it as base for their paths: + + r := mux.NewRouter() + s := r.PathPrefix("/products").Subrouter() + // "/products/" + s.HandleFunc("/", ProductsHandler) + // "/products/{key}/" + s.HandleFunc("/{key}/", ProductHandler) + // "/products/{key}/details" + s.HandleFunc("/{key}/details", ProductDetailsHandler) + +Now let's see how to build registered URLs. + +Routes can be named. All routes that define a name can have their URLs built, +or "reversed". We define a name calling Name() on a route. For example: + + r := mux.NewRouter() + r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). + Name("article") + +To build a URL, get the route and call the URL() method, passing a sequence of +key/value pairs for the route variables. For the previous route, we would do: + + url, err := r.Get("article").URL("category", "technology", "id", "42") + +...and the result will be a url.URL with the following path: + + "/articles/technology/42" + +This also works for host variables: + + r := mux.NewRouter() + r.Host("{subdomain}.domain.com"). + Path("/articles/{category}/{id:[0-9]+}"). + HandlerFunc(ArticleHandler). + Name("article") + + // url.String() will be "http://news.domain.com/articles/technology/42" + url, err := r.Get("article").URL("subdomain", "news", + "category", "technology", + "id", "42") + +All variables defined in the route are required, and their values must +conform to the corresponding patterns. These requirements guarantee that a +generated URL will always match a registered route -- the only exception is +for explicitly defined "build-only" routes which never match. + +There's also a way to build only the URL host or path for a route: +use the methods URLHost() or URLPath() instead. For the previous route, +we would do: + + // "http://news.domain.com/" + host, err := r.Get("article").URLHost("subdomain", "news") + + // "/articles/technology/42" + path, err := r.Get("article").URLPath("category", "technology", "id", "42") + +And if you use subrouters, host and path defined separately can be built +as well: + + r := mux.NewRouter() + s := r.Host("{subdomain}.domain.com").Subrouter() + s.Path("/articles/{category}/{id:[0-9]+}"). + HandlerFunc(ArticleHandler). + Name("article") + + // "http://news.domain.com/articles/technology/42" + url, err := r.Get("article").URL("subdomain", "news", + "category", "technology", + "id", "42") +*/ +package mux diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/mux.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/mux.go new file mode 100644 index 000000000..5b5f8e7db --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/mux.go @@ -0,0 +1,353 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "fmt" + "net/http" + "path" + + "github.com/gorilla/context" +) + +// NewRouter returns a new router instance. +func NewRouter() *Router { + return &Router{namedRoutes: make(map[string]*Route), KeepContext: false} +} + +// Router registers routes to be matched and dispatches a handler. +// +// It implements the http.Handler interface, so it can be registered to serve +// requests: +// +// var router = mux.NewRouter() +// +// func main() { +// http.Handle("/", router) +// } +// +// Or, for Google App Engine, register it in a init() function: +// +// func init() { +// http.Handle("/", router) +// } +// +// This will send all incoming requests to the router. +type Router struct { + // Configurable Handler to be used when no route matches. + NotFoundHandler http.Handler + // Parent route, if this is a subrouter. + parent parentRoute + // Routes to be matched, in order. + routes []*Route + // Routes by name for URL building. + namedRoutes map[string]*Route + // See Router.StrictSlash(). This defines the flag for new routes. + strictSlash bool + // If true, do not clear the request context after handling the request + KeepContext bool +} + +// Match matches registered routes against the request. +func (r *Router) Match(req *http.Request, match *RouteMatch) bool { + for _, route := range r.routes { + if route.Match(req, match) { + return true + } + } + return false +} + +// ServeHTTP dispatches the handler registered in the matched route. +// +// When there is a match, the route variables can be retrieved calling +// mux.Vars(request). +func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { + // Clean path to canonical form and redirect. + if p := cleanPath(req.URL.Path); p != req.URL.Path { + + // Added 3 lines (Philip Schlump) - It was droping the query string and #whatever from query. + // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue: + // http://code.google.com/p/go/issues/detail?id=5252 + url := *req.URL + url.Path = p + p = url.String() + + w.Header().Set("Location", p) + w.WriteHeader(http.StatusMovedPermanently) + return + } + var match RouteMatch + var handler http.Handler + if r.Match(req, &match) { + handler = match.Handler + setVars(req, match.Vars) + setCurrentRoute(req, match.Route) + } + if handler == nil { + handler = r.NotFoundHandler + if handler == nil { + handler = http.NotFoundHandler() + } + } + if !r.KeepContext { + defer context.Clear(req) + } + handler.ServeHTTP(w, req) +} + +// Get returns a route registered with the given name. +func (r *Router) Get(name string) *Route { + return r.getNamedRoutes()[name] +} + +// GetRoute returns a route registered with the given name. This method +// was renamed to Get() and remains here for backwards compatibility. +func (r *Router) GetRoute(name string) *Route { + return r.getNamedRoutes()[name] +} + +// StrictSlash defines the trailing slash behavior for new routes. The initial +// value is false. +// +// When true, if the route path is "/path/", accessing "/path" will redirect +// to the former and vice versa. In other words, your application will always +// see the path as specified in the route. +// +// When false, if the route path is "/path", accessing "/path/" will not match +// this route and vice versa. +// +// Special case: when a route sets a path prefix using the PathPrefix() method, +// strict slash is ignored for that route because the redirect behavior can't +// be determined from a prefix alone. However, any subrouters created from that +// route inherit the original StrictSlash setting. +func (r *Router) StrictSlash(value bool) *Router { + r.strictSlash = value + return r +} + +// ---------------------------------------------------------------------------- +// parentRoute +// ---------------------------------------------------------------------------- + +// getNamedRoutes returns the map where named routes are registered. +func (r *Router) getNamedRoutes() map[string]*Route { + if r.namedRoutes == nil { + if r.parent != nil { + r.namedRoutes = r.parent.getNamedRoutes() + } else { + r.namedRoutes = make(map[string]*Route) + } + } + return r.namedRoutes +} + +// getRegexpGroup returns regexp definitions from the parent route, if any. +func (r *Router) getRegexpGroup() *routeRegexpGroup { + if r.parent != nil { + return r.parent.getRegexpGroup() + } + return nil +} + +// ---------------------------------------------------------------------------- +// Route factories +// ---------------------------------------------------------------------------- + +// NewRoute registers an empty route. +func (r *Router) NewRoute() *Route { + route := &Route{parent: r, strictSlash: r.strictSlash} + r.routes = append(r.routes, route) + return route +} + +// Handle registers a new route with a matcher for the URL path. +// See Route.Path() and Route.Handler(). +func (r *Router) Handle(path string, handler http.Handler) *Route { + return r.NewRoute().Path(path).Handler(handler) +} + +// HandleFunc registers a new route with a matcher for the URL path. +// See Route.Path() and Route.HandlerFunc(). +func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, + *http.Request)) *Route { + return r.NewRoute().Path(path).HandlerFunc(f) +} + +// Headers registers a new route with a matcher for request header values. +// See Route.Headers(). +func (r *Router) Headers(pairs ...string) *Route { + return r.NewRoute().Headers(pairs...) +} + +// Host registers a new route with a matcher for the URL host. +// See Route.Host(). +func (r *Router) Host(tpl string) *Route { + return r.NewRoute().Host(tpl) +} + +// MatcherFunc registers a new route with a custom matcher function. +// See Route.MatcherFunc(). +func (r *Router) MatcherFunc(f MatcherFunc) *Route { + return r.NewRoute().MatcherFunc(f) +} + +// Methods registers a new route with a matcher for HTTP methods. +// See Route.Methods(). +func (r *Router) Methods(methods ...string) *Route { + return r.NewRoute().Methods(methods...) +} + +// Path registers a new route with a matcher for the URL path. +// See Route.Path(). +func (r *Router) Path(tpl string) *Route { + return r.NewRoute().Path(tpl) +} + +// PathPrefix registers a new route with a matcher for the URL path prefix. +// See Route.PathPrefix(). +func (r *Router) PathPrefix(tpl string) *Route { + return r.NewRoute().PathPrefix(tpl) +} + +// Queries registers a new route with a matcher for URL query values. +// See Route.Queries(). +func (r *Router) Queries(pairs ...string) *Route { + return r.NewRoute().Queries(pairs...) +} + +// Schemes registers a new route with a matcher for URL schemes. +// See Route.Schemes(). +func (r *Router) Schemes(schemes ...string) *Route { + return r.NewRoute().Schemes(schemes...) +} + +// ---------------------------------------------------------------------------- +// Context +// ---------------------------------------------------------------------------- + +// RouteMatch stores information about a matched route. +type RouteMatch struct { + Route *Route + Handler http.Handler + Vars map[string]string +} + +type contextKey int + +const ( + varsKey contextKey = iota + routeKey +) + +// Vars returns the route variables for the current request, if any. +func Vars(r *http.Request) map[string]string { + if rv := context.Get(r, varsKey); rv != nil { + return rv.(map[string]string) + } + return nil +} + +// CurrentRoute returns the matched route for the current request, if any. +func CurrentRoute(r *http.Request) *Route { + if rv := context.Get(r, routeKey); rv != nil { + return rv.(*Route) + } + return nil +} + +func setVars(r *http.Request, val interface{}) { + context.Set(r, varsKey, val) +} + +func setCurrentRoute(r *http.Request, val interface{}) { + context.Set(r, routeKey, val) +} + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +// cleanPath returns the canonical path for p, eliminating . and .. elements. +// Borrowed from the net/http package. +func cleanPath(p string) string { + if p == "" { + return "/" + } + if p[0] != '/' { + p = "/" + p + } + np := path.Clean(p) + // path.Clean removes trailing slash except for root; + // put the trailing slash back if necessary. + if p[len(p)-1] == '/' && np != "/" { + np += "/" + } + return np +} + +// uniqueVars returns an error if two slices contain duplicated strings. +func uniqueVars(s1, s2 []string) error { + for _, v1 := range s1 { + for _, v2 := range s2 { + if v1 == v2 { + return fmt.Errorf("mux: duplicated route variable %q", v2) + } + } + } + return nil +} + +// mapFromPairs converts variadic string parameters to a string map. +func mapFromPairs(pairs ...string) (map[string]string, error) { + length := len(pairs) + if length%2 != 0 { + return nil, fmt.Errorf( + "mux: number of parameters must be multiple of 2, got %v", pairs) + } + m := make(map[string]string, length/2) + for i := 0; i < length; i += 2 { + m[pairs[i]] = pairs[i+1] + } + return m, nil +} + +// matchInArray returns true if the given string value is in the array. +func matchInArray(arr []string, value string) bool { + for _, v := range arr { + if v == value { + return true + } + } + return false +} + +// matchMap returns true if the given key/value pairs exist in a given map. +func matchMap(toCheck map[string]string, toMatch map[string][]string, + canonicalKey bool) bool { + for k, v := range toCheck { + // Check if key exists. + if canonicalKey { + k = http.CanonicalHeaderKey(k) + } + if values := toMatch[k]; values == nil { + return false + } else if v != "" { + // If value was defined as an empty string we only check that the + // key exists. Otherwise we also check for equality. + valueExists := false + for _, value := range values { + if v == value { + valueExists = true + break + } + } + if !valueExists { + return false + } + } + } + return true +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/mux_test.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/mux_test.go new file mode 100644 index 000000000..e455bce8f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/mux_test.go @@ -0,0 +1,943 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "fmt" + "net/http" + "testing" + + "github.com/gorilla/context" +) + +type routeTest struct { + title string // title of the test + route *Route // the route being tested + request *http.Request // a request to test the route + vars map[string]string // the expected vars of the match + host string // the expected host of the match + path string // the expected path of the match + shouldMatch bool // whether the request is expected to match the route at all + shouldRedirect bool // whether the request should result in a redirect +} + +func TestHost(t *testing.T) { + // newRequestHost a new request with a method, url, and host header + newRequestHost := func(method, url, host string) *http.Request { + req, err := http.NewRequest(method, url, nil) + if err != nil { + panic(err) + } + req.Host = host + return req + } + + tests := []routeTest{ + { + title: "Host route match", + route: new(Route).Host("aaa.bbb.ccc"), + request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), + vars: map[string]string{}, + host: "aaa.bbb.ccc", + path: "", + shouldMatch: true, + }, + { + title: "Host route, wrong host in request URL", + route: new(Route).Host("aaa.bbb.ccc"), + request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), + vars: map[string]string{}, + host: "aaa.bbb.ccc", + path: "", + shouldMatch: false, + }, + { + title: "Host route with port, match", + route: new(Route).Host("aaa.bbb.ccc:1234"), + request: newRequest("GET", "http://aaa.bbb.ccc:1234/111/222/333"), + vars: map[string]string{}, + host: "aaa.bbb.ccc:1234", + path: "", + shouldMatch: true, + }, + { + title: "Host route with port, wrong port in request URL", + route: new(Route).Host("aaa.bbb.ccc:1234"), + request: newRequest("GET", "http://aaa.bbb.ccc:9999/111/222/333"), + vars: map[string]string{}, + host: "aaa.bbb.ccc:1234", + path: "", + shouldMatch: false, + }, + { + title: "Host route, match with host in request header", + route: new(Route).Host("aaa.bbb.ccc"), + request: newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc"), + vars: map[string]string{}, + host: "aaa.bbb.ccc", + path: "", + shouldMatch: true, + }, + { + title: "Host route, wrong host in request header", + route: new(Route).Host("aaa.bbb.ccc"), + request: newRequestHost("GET", "/111/222/333", "aaa.222.ccc"), + vars: map[string]string{}, + host: "aaa.bbb.ccc", + path: "", + shouldMatch: false, + }, + // BUG {new(Route).Host("aaa.bbb.ccc:1234"), newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:1234"), map[string]string{}, "aaa.bbb.ccc:1234", "", true}, + { + title: "Host route with port, wrong host in request header", + route: new(Route).Host("aaa.bbb.ccc:1234"), + request: newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:9999"), + vars: map[string]string{}, + host: "aaa.bbb.ccc:1234", + path: "", + shouldMatch: false, + }, + { + title: "Host route with pattern, match", + route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc"), + request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), + vars: map[string]string{"v1": "bbb"}, + host: "aaa.bbb.ccc", + path: "", + shouldMatch: true, + }, + { + title: "Host route with pattern, wrong host in request URL", + route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc"), + request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), + vars: map[string]string{"v1": "bbb"}, + host: "aaa.bbb.ccc", + path: "", + shouldMatch: false, + }, + { + title: "Host route with multiple patterns, match", + route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}"), + request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), + vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc"}, + host: "aaa.bbb.ccc", + path: "", + shouldMatch: true, + }, + { + title: "Host route with multiple patterns, wrong host in request URL", + route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}"), + request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), + vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc"}, + host: "aaa.bbb.ccc", + path: "", + shouldMatch: false, + }, + } + for _, test := range tests { + testRoute(t, test) + } +} + +func TestPath(t *testing.T) { + tests := []routeTest{ + { + title: "Path route, match", + route: new(Route).Path("/111/222/333"), + request: newRequest("GET", "http://localhost/111/222/333"), + vars: map[string]string{}, + host: "", + path: "/111/222/333", + shouldMatch: true, + }, + { + title: "Path route, match with trailing slash in request and path", + route: new(Route).Path("/111/"), + request: newRequest("GET", "http://localhost/111/"), + vars: map[string]string{}, + host: "", + path: "/111/", + shouldMatch: true, + }, + { + title: "Path route, do not match with trailing slash in path", + route: new(Route).Path("/111/"), + request: newRequest("GET", "http://localhost/111"), + vars: map[string]string{}, + host: "", + path: "/111", + shouldMatch: false, + }, + { + title: "Path route, do not match with trailing slash in request", + route: new(Route).Path("/111"), + request: newRequest("GET", "http://localhost/111/"), + vars: map[string]string{}, + host: "", + path: "/111/", + shouldMatch: false, + }, + { + title: "Path route, wrong path in request in request URL", + route: new(Route).Path("/111/222/333"), + request: newRequest("GET", "http://localhost/1/2/3"), + vars: map[string]string{}, + host: "", + path: "/111/222/333", + shouldMatch: false, + }, + { + title: "Path route with pattern, match", + route: new(Route).Path("/111/{v1:[0-9]{3}}/333"), + request: newRequest("GET", "http://localhost/111/222/333"), + vars: map[string]string{"v1": "222"}, + host: "", + path: "/111/222/333", + shouldMatch: true, + }, + { + title: "Path route with pattern, URL in request does not match", + route: new(Route).Path("/111/{v1:[0-9]{3}}/333"), + request: newRequest("GET", "http://localhost/111/aaa/333"), + vars: map[string]string{"v1": "222"}, + host: "", + path: "/111/222/333", + shouldMatch: false, + }, + { + title: "Path route with multiple patterns, match", + route: new(Route).Path("/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}"), + request: newRequest("GET", "http://localhost/111/222/333"), + vars: map[string]string{"v1": "111", "v2": "222", "v3": "333"}, + host: "", + path: "/111/222/333", + shouldMatch: true, + }, + { + title: "Path route with multiple patterns, URL in request does not match", + route: new(Route).Path("/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}"), + request: newRequest("GET", "http://localhost/111/aaa/333"), + vars: map[string]string{"v1": "111", "v2": "222", "v3": "333"}, + host: "", + path: "/111/222/333", + shouldMatch: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } +} + +func TestPathPrefix(t *testing.T) { + tests := []routeTest{ + { + title: "PathPrefix route, match", + route: new(Route).PathPrefix("/111"), + request: newRequest("GET", "http://localhost/111/222/333"), + vars: map[string]string{}, + host: "", + path: "/111", + shouldMatch: true, + }, + { + title: "PathPrefix route, match substring", + route: new(Route).PathPrefix("/1"), + request: newRequest("GET", "http://localhost/111/222/333"), + vars: map[string]string{}, + host: "", + path: "/1", + shouldMatch: true, + }, + { + title: "PathPrefix route, URL prefix in request does not match", + route: new(Route).PathPrefix("/111"), + request: newRequest("GET", "http://localhost/1/2/3"), + vars: map[string]string{}, + host: "", + path: "/111", + shouldMatch: false, + }, + { + title: "PathPrefix route with pattern, match", + route: new(Route).PathPrefix("/111/{v1:[0-9]{3}}"), + request: newRequest("GET", "http://localhost/111/222/333"), + vars: map[string]string{"v1": "222"}, + host: "", + path: "/111/222", + shouldMatch: true, + }, + { + title: "PathPrefix route with pattern, URL prefix in request does not match", + route: new(Route).PathPrefix("/111/{v1:[0-9]{3}}"), + request: newRequest("GET", "http://localhost/111/aaa/333"), + vars: map[string]string{"v1": "222"}, + host: "", + path: "/111/222", + shouldMatch: false, + }, + { + title: "PathPrefix route with multiple patterns, match", + route: new(Route).PathPrefix("/{v1:[0-9]{3}}/{v2:[0-9]{3}}"), + request: newRequest("GET", "http://localhost/111/222/333"), + vars: map[string]string{"v1": "111", "v2": "222"}, + host: "", + path: "/111/222", + shouldMatch: true, + }, + { + title: "PathPrefix route with multiple patterns, URL prefix in request does not match", + route: new(Route).PathPrefix("/{v1:[0-9]{3}}/{v2:[0-9]{3}}"), + request: newRequest("GET", "http://localhost/111/aaa/333"), + vars: map[string]string{"v1": "111", "v2": "222"}, + host: "", + path: "/111/222", + shouldMatch: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } +} + +func TestHostPath(t *testing.T) { + tests := []routeTest{ + { + title: "Host and Path route, match", + route: new(Route).Host("aaa.bbb.ccc").Path("/111/222/333"), + request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Host and Path route, wrong host in request URL", + route: new(Route).Host("aaa.bbb.ccc").Path("/111/222/333"), + request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: false, + }, + { + title: "Host and Path route with pattern, match", + route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"), + request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), + vars: map[string]string{"v1": "bbb", "v2": "222"}, + host: "aaa.bbb.ccc", + path: "/111/222/333", + shouldMatch: true, + }, + { + title: "Host and Path route with pattern, URL in request does not match", + route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"), + request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), + vars: map[string]string{"v1": "bbb", "v2": "222"}, + host: "aaa.bbb.ccc", + path: "/111/222/333", + shouldMatch: false, + }, + { + title: "Host and Path route with multiple patterns, match", + route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}").Path("/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}"), + request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), + vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc", "v4": "111", "v5": "222", "v6": "333"}, + host: "aaa.bbb.ccc", + path: "/111/222/333", + shouldMatch: true, + }, + { + title: "Host and Path route with multiple patterns, URL in request does not match", + route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}").Path("/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}"), + request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), + vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc", "v4": "111", "v5": "222", "v6": "333"}, + host: "aaa.bbb.ccc", + path: "/111/222/333", + shouldMatch: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } +} + +func TestHeaders(t *testing.T) { + // newRequestHeaders creates a new request with a method, url, and headers + newRequestHeaders := func(method, url string, headers map[string]string) *http.Request { + req, err := http.NewRequest(method, url, nil) + if err != nil { + panic(err) + } + for k, v := range headers { + req.Header.Add(k, v) + } + return req + } + + tests := []routeTest{ + { + title: "Headers route, match", + route: new(Route).Headers("foo", "bar", "baz", "ding"), + request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar", "baz": "ding"}), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Headers route, bad header values", + route: new(Route).Headers("foo", "bar", "baz", "ding"), + request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar", "baz": "dong"}), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } + +} + +func TestMethods(t *testing.T) { + tests := []routeTest{ + { + title: "Methods route, match GET", + route: new(Route).Methods("GET", "POST"), + request: newRequest("GET", "http://localhost"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Methods route, match POST", + route: new(Route).Methods("GET", "POST"), + request: newRequest("POST", "http://localhost"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Methods route, bad method", + route: new(Route).Methods("GET", "POST"), + request: newRequest("PUT", "http://localhost"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } +} + +func TestQueries(t *testing.T) { + tests := []routeTest{ + { + title: "Queries route, match", + route: new(Route).Queries("foo", "bar", "baz", "ding"), + request: newRequest("GET", "http://localhost?foo=bar&baz=ding"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Queries route, match with a query string", + route: new(Route).Host("www.example.com").Path("/api").Queries("foo", "bar", "baz", "ding"), + request: newRequest("GET", "http://www.example.com/api?foo=bar&baz=ding"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Queries route, match with a query string out of order", + route: new(Route).Host("www.example.com").Path("/api").Queries("foo", "bar", "baz", "ding"), + request: newRequest("GET", "http://www.example.com/api?baz=ding&foo=bar"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Queries route, bad query", + route: new(Route).Queries("foo", "bar", "baz", "ding"), + request: newRequest("GET", "http://localhost?foo=bar&baz=dong"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: false, + }, + { + title: "Queries route with pattern, match", + route: new(Route).Queries("foo", "{v1}"), + request: newRequest("GET", "http://localhost?foo=bar"), + vars: map[string]string{"v1": "bar"}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Queries route with multiple patterns, match", + route: new(Route).Queries("foo", "{v1}", "baz", "{v2}"), + request: newRequest("GET", "http://localhost?foo=bar&baz=ding"), + vars: map[string]string{"v1": "bar", "v2": "ding"}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Queries route with regexp pattern, match", + route: new(Route).Queries("foo", "{v1:[0-9]+}"), + request: newRequest("GET", "http://localhost?foo=10"), + vars: map[string]string{"v1": "10"}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Queries route with regexp pattern, regexp does not match", + route: new(Route).Queries("foo", "{v1:[0-9]+}"), + request: newRequest("GET", "http://localhost?foo=a"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } +} + +func TestSchemes(t *testing.T) { + tests := []routeTest{ + // Schemes + { + title: "Schemes route, match https", + route: new(Route).Schemes("https", "ftp"), + request: newRequest("GET", "https://localhost"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Schemes route, match ftp", + route: new(Route).Schemes("https", "ftp"), + request: newRequest("GET", "ftp://localhost"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "Schemes route, bad scheme", + route: new(Route).Schemes("https", "ftp"), + request: newRequest("GET", "http://localhost"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: false, + }, + } + for _, test := range tests { + testRoute(t, test) + } +} + +func TestMatcherFunc(t *testing.T) { + m := func(r *http.Request, m *RouteMatch) bool { + if r.URL.Host == "aaa.bbb.ccc" { + return true + } + return false + } + + tests := []routeTest{ + { + title: "MatchFunc route, match", + route: new(Route).MatcherFunc(m), + request: newRequest("GET", "http://aaa.bbb.ccc"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: true, + }, + { + title: "MatchFunc route, non-match", + route: new(Route).MatcherFunc(m), + request: newRequest("GET", "http://aaa.222.ccc"), + vars: map[string]string{}, + host: "", + path: "", + shouldMatch: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } +} + +func TestSubRouter(t *testing.T) { + subrouter1 := new(Route).Host("{v1:[a-z]+}.google.com").Subrouter() + subrouter2 := new(Route).PathPrefix("/foo/{v1}").Subrouter() + + tests := []routeTest{ + { + route: subrouter1.Path("/{v2:[a-z]+}"), + request: newRequest("GET", "http://aaa.google.com/bbb"), + vars: map[string]string{"v1": "aaa", "v2": "bbb"}, + host: "aaa.google.com", + path: "/bbb", + shouldMatch: true, + }, + { + route: subrouter1.Path("/{v2:[a-z]+}"), + request: newRequest("GET", "http://111.google.com/111"), + vars: map[string]string{"v1": "aaa", "v2": "bbb"}, + host: "aaa.google.com", + path: "/bbb", + shouldMatch: false, + }, + { + route: subrouter2.Path("/baz/{v2}"), + request: newRequest("GET", "http://localhost/foo/bar/baz/ding"), + vars: map[string]string{"v1": "bar", "v2": "ding"}, + host: "", + path: "/foo/bar/baz/ding", + shouldMatch: true, + }, + { + route: subrouter2.Path("/baz/{v2}"), + request: newRequest("GET", "http://localhost/foo/bar"), + vars: map[string]string{"v1": "bar", "v2": "ding"}, + host: "", + path: "/foo/bar/baz/ding", + shouldMatch: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } +} + +func TestNamedRoutes(t *testing.T) { + r1 := NewRouter() + r1.NewRoute().Name("a") + r1.NewRoute().Name("b") + r1.NewRoute().Name("c") + + r2 := r1.NewRoute().Subrouter() + r2.NewRoute().Name("d") + r2.NewRoute().Name("e") + r2.NewRoute().Name("f") + + r3 := r2.NewRoute().Subrouter() + r3.NewRoute().Name("g") + r3.NewRoute().Name("h") + r3.NewRoute().Name("i") + + if r1.namedRoutes == nil || len(r1.namedRoutes) != 9 { + t.Errorf("Expected 9 named routes, got %v", r1.namedRoutes) + } else if r1.Get("i") == nil { + t.Errorf("Subroute name not registered") + } +} + +func TestStrictSlash(t *testing.T) { + r := NewRouter() + r.StrictSlash(true) + + tests := []routeTest{ + { + title: "Redirect path without slash", + route: r.NewRoute().Path("/111/"), + request: newRequest("GET", "http://localhost/111"), + vars: map[string]string{}, + host: "", + path: "/111/", + shouldMatch: true, + shouldRedirect: true, + }, + { + title: "Do not redirect path with slash", + route: r.NewRoute().Path("/111/"), + request: newRequest("GET", "http://localhost/111/"), + vars: map[string]string{}, + host: "", + path: "/111/", + shouldMatch: true, + shouldRedirect: false, + }, + { + title: "Redirect path with slash", + route: r.NewRoute().Path("/111"), + request: newRequest("GET", "http://localhost/111/"), + vars: map[string]string{}, + host: "", + path: "/111", + shouldMatch: true, + shouldRedirect: true, + }, + { + title: "Do not redirect path without slash", + route: r.NewRoute().Path("/111"), + request: newRequest("GET", "http://localhost/111"), + vars: map[string]string{}, + host: "", + path: "/111", + shouldMatch: true, + shouldRedirect: false, + }, + { + title: "Propagate StrictSlash to subrouters", + route: r.NewRoute().PathPrefix("/static/").Subrouter().Path("/images/"), + request: newRequest("GET", "http://localhost/static/images"), + vars: map[string]string{}, + host: "", + path: "/static/images/", + shouldMatch: true, + shouldRedirect: true, + }, + { + title: "Ignore StrictSlash for path prefix", + route: r.NewRoute().PathPrefix("/static/"), + request: newRequest("GET", "http://localhost/static/logo.png"), + vars: map[string]string{}, + host: "", + path: "/static/", + shouldMatch: true, + shouldRedirect: false, + }, + } + + for _, test := range tests { + testRoute(t, test) + } +} + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +func getRouteTemplate(route *Route) string { + host, path := "none", "none" + if route.regexp != nil { + if route.regexp.host != nil { + host = route.regexp.host.template + } + if route.regexp.path != nil { + path = route.regexp.path.template + } + } + return fmt.Sprintf("Host: %v, Path: %v", host, path) +} + +func testRoute(t *testing.T, test routeTest) { + request := test.request + route := test.route + vars := test.vars + shouldMatch := test.shouldMatch + host := test.host + path := test.path + url := test.host + test.path + shouldRedirect := test.shouldRedirect + + var match RouteMatch + ok := route.Match(request, &match) + if ok != shouldMatch { + msg := "Should match" + if !shouldMatch { + msg = "Should not match" + } + t.Errorf("(%v) %v:\nRoute: %#v\nRequest: %#v\nVars: %v\n", test.title, msg, route, request, vars) + return + } + if shouldMatch { + if test.vars != nil && !stringMapEqual(test.vars, match.Vars) { + t.Errorf("(%v) Vars not equal: expected %v, got %v", test.title, vars, match.Vars) + return + } + if host != "" { + u, _ := test.route.URLHost(mapToPairs(match.Vars)...) + if host != u.Host { + t.Errorf("(%v) URLHost not equal: expected %v, got %v -- %v", test.title, host, u.Host, getRouteTemplate(route)) + return + } + } + if path != "" { + u, _ := route.URLPath(mapToPairs(match.Vars)...) + if path != u.Path { + t.Errorf("(%v) URLPath not equal: expected %v, got %v -- %v", test.title, path, u.Path, getRouteTemplate(route)) + return + } + } + if url != "" { + u, _ := route.URL(mapToPairs(match.Vars)...) + if url != u.Host+u.Path { + t.Errorf("(%v) URL not equal: expected %v, got %v -- %v", test.title, url, u.Host+u.Path, getRouteTemplate(route)) + return + } + } + if shouldRedirect && match.Handler == nil { + t.Errorf("(%v) Did not redirect", test.title) + return + } + if !shouldRedirect && match.Handler != nil { + t.Errorf("(%v) Unexpected redirect", test.title) + return + } + } +} + +// Tests that the context is cleared or not cleared properly depending on +// the configuration of the router +func TestKeepContext(t *testing.T) { + func1 := func(w http.ResponseWriter, r *http.Request) {} + + r := NewRouter() + r.HandleFunc("/", func1).Name("func1") + + req, _ := http.NewRequest("GET", "http://localhost/", nil) + context.Set(req, "t", 1) + + res := new(http.ResponseWriter) + r.ServeHTTP(*res, req) + + if _, ok := context.GetOk(req, "t"); ok { + t.Error("Context should have been cleared at end of request") + } + + r.KeepContext = true + + req, _ = http.NewRequest("GET", "http://localhost/", nil) + context.Set(req, "t", 1) + + r.ServeHTTP(*res, req) + if _, ok := context.GetOk(req, "t"); !ok { + t.Error("Context should NOT have been cleared at end of request") + } + +} + +type TestA301ResponseWriter struct { + hh http.Header + status int +} + +func (ho TestA301ResponseWriter) Header() http.Header { + return http.Header(ho.hh) +} + +func (ho TestA301ResponseWriter) Write(b []byte) (int, error) { + return 0, nil +} + +func (ho TestA301ResponseWriter) WriteHeader(code int) { + ho.status = code +} + +func Test301Redirect(t *testing.T) { + m := make(http.Header) + + func1 := func(w http.ResponseWriter, r *http.Request) {} + func2 := func(w http.ResponseWriter, r *http.Request) {} + + r := NewRouter() + r.HandleFunc("/api/", func2).Name("func2") + r.HandleFunc("/", func1).Name("func1") + + req, _ := http.NewRequest("GET", "http://localhost//api/?abc=def", nil) + + res := TestA301ResponseWriter{ + hh: m, + status: 0, + } + r.ServeHTTP(&res, req) + + if "http://localhost/api/?abc=def" != res.hh["Location"][0] { + t.Errorf("Should have complete URL with query string") + } +} + +// https://plus.google.com/101022900381697718949/posts/eWy6DjFJ6uW +func TestSubrouterHeader(t *testing.T) { + expected := "func1 response" + func1 := func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, expected) + } + func2 := func(http.ResponseWriter, *http.Request) {} + + r := NewRouter() + s := r.Headers("SomeSpecialHeader", "").Subrouter() + s.HandleFunc("/", func1).Name("func1") + r.HandleFunc("/", func2).Name("func2") + + req, _ := http.NewRequest("GET", "http://localhost/", nil) + req.Header.Add("SomeSpecialHeader", "foo") + match := new(RouteMatch) + matched := r.Match(req, match) + if !matched { + t.Errorf("Should match request") + } + if match.Route.GetName() != "func1" { + t.Errorf("Expecting func1 handler, got %s", match.Route.GetName()) + } + resp := NewRecorder() + match.Handler.ServeHTTP(resp, req) + if resp.Body.String() != expected { + t.Errorf("Expecting %q", expected) + } +} + +// mapToPairs converts a string map to a slice of string pairs +func mapToPairs(m map[string]string) []string { + var i int + p := make([]string, len(m)*2) + for k, v := range m { + p[i] = k + p[i+1] = v + i += 2 + } + return p +} + +// stringMapEqual checks the equality of two string maps +func stringMapEqual(m1, m2 map[string]string) bool { + nil1 := m1 == nil + nil2 := m2 == nil + if nil1 != nil2 || len(m1) != len(m2) { + return false + } + for k, v := range m1 { + if v != m2[k] { + return false + } + } + return true +} + +// newRequest is a helper function to create a new request with a method and url +func newRequest(method, url string) *http.Request { + req, err := http.NewRequest(method, url, nil) + if err != nil { + panic(err) + } + return req +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/old_test.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/old_test.go new file mode 100644 index 000000000..1f7c190c0 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/old_test.go @@ -0,0 +1,714 @@ +// Old tests ported to Go1. This is a mess. Want to drop it one day. + +// Copyright 2011 Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "bytes" + "net/http" + "testing" +) + +// ---------------------------------------------------------------------------- +// ResponseRecorder +// ---------------------------------------------------------------------------- +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// ResponseRecorder is an implementation of http.ResponseWriter that +// records its mutations for later inspection in tests. +type ResponseRecorder struct { + Code int // the HTTP response code from WriteHeader + HeaderMap http.Header // the HTTP response headers + Body *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to + Flushed bool +} + +// NewRecorder returns an initialized ResponseRecorder. +func NewRecorder() *ResponseRecorder { + return &ResponseRecorder{ + HeaderMap: make(http.Header), + Body: new(bytes.Buffer), + } +} + +// DefaultRemoteAddr is the default remote address to return in RemoteAddr if +// an explicit DefaultRemoteAddr isn't set on ResponseRecorder. +const DefaultRemoteAddr = "1.2.3.4" + +// Header returns the response headers. +func (rw *ResponseRecorder) Header() http.Header { + return rw.HeaderMap +} + +// Write always succeeds and writes to rw.Body, if not nil. +func (rw *ResponseRecorder) Write(buf []byte) (int, error) { + if rw.Body != nil { + rw.Body.Write(buf) + } + if rw.Code == 0 { + rw.Code = http.StatusOK + } + return len(buf), nil +} + +// WriteHeader sets rw.Code. +func (rw *ResponseRecorder) WriteHeader(code int) { + rw.Code = code +} + +// Flush sets rw.Flushed to true. +func (rw *ResponseRecorder) Flush() { + rw.Flushed = true +} + +// ---------------------------------------------------------------------------- + +func TestRouteMatchers(t *testing.T) { + var scheme, host, path, query, method string + var headers map[string]string + var resultVars map[bool]map[string]string + + router := NewRouter() + router.NewRoute().Host("{var1}.google.com"). + Path("/{var2:[a-z]+}/{var3:[0-9]+}"). + Queries("foo", "bar"). + Methods("GET"). + Schemes("https"). + Headers("x-requested-with", "XMLHttpRequest") + router.NewRoute().Host("www.{var4}.com"). + PathPrefix("/foo/{var5:[a-z]+}/{var6:[0-9]+}"). + Queries("baz", "ding"). + Methods("POST"). + Schemes("http"). + Headers("Content-Type", "application/json") + + reset := func() { + // Everything match. + scheme = "https" + host = "www.google.com" + path = "/product/42" + query = "?foo=bar" + method = "GET" + headers = map[string]string{"X-Requested-With": "XMLHttpRequest"} + resultVars = map[bool]map[string]string{ + true: {"var1": "www", "var2": "product", "var3": "42"}, + false: {}, + } + } + + reset2 := func() { + // Everything match. + scheme = "http" + host = "www.google.com" + path = "/foo/product/42/path/that/is/ignored" + query = "?baz=ding" + method = "POST" + headers = map[string]string{"Content-Type": "application/json"} + resultVars = map[bool]map[string]string{ + true: {"var4": "google", "var5": "product", "var6": "42"}, + false: {}, + } + } + + match := func(shouldMatch bool) { + url := scheme + "://" + host + path + query + request, _ := http.NewRequest(method, url, nil) + for key, value := range headers { + request.Header.Add(key, value) + } + + var routeMatch RouteMatch + matched := router.Match(request, &routeMatch) + if matched != shouldMatch { + // Need better messages. :) + if matched { + t.Errorf("Should match.") + } else { + t.Errorf("Should not match.") + } + } + + if matched { + currentRoute := routeMatch.Route + if currentRoute == nil { + t.Errorf("Expected a current route.") + } + vars := routeMatch.Vars + expectedVars := resultVars[shouldMatch] + if len(vars) != len(expectedVars) { + t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars) + } + for name, value := range vars { + if expectedVars[name] != value { + t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars) + } + } + } + } + + // 1st route -------------------------------------------------------------- + + // Everything match. + reset() + match(true) + + // Scheme doesn't match. + reset() + scheme = "http" + match(false) + + // Host doesn't match. + reset() + host = "www.mygoogle.com" + match(false) + + // Path doesn't match. + reset() + path = "/product/notdigits" + match(false) + + // Query doesn't match. + reset() + query = "?foo=baz" + match(false) + + // Method doesn't match. + reset() + method = "POST" + match(false) + + // Header doesn't match. + reset() + headers = map[string]string{} + match(false) + + // Everything match, again. + reset() + match(true) + + // 2nd route -------------------------------------------------------------- + + // Everything match. + reset2() + match(true) + + // Scheme doesn't match. + reset2() + scheme = "https" + match(false) + + // Host doesn't match. + reset2() + host = "sub.google.com" + match(false) + + // Path doesn't match. + reset2() + path = "/bar/product/42" + match(false) + + // Query doesn't match. + reset2() + query = "?foo=baz" + match(false) + + // Method doesn't match. + reset2() + method = "GET" + match(false) + + // Header doesn't match. + reset2() + headers = map[string]string{} + match(false) + + // Everything match, again. + reset2() + match(true) +} + +type headerMatcherTest struct { + matcher headerMatcher + headers map[string]string + result bool +} + +var headerMatcherTests = []headerMatcherTest{ + { + matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}), + headers: map[string]string{"X-Requested-With": "XMLHttpRequest"}, + result: true, + }, + { + matcher: headerMatcher(map[string]string{"x-requested-with": ""}), + headers: map[string]string{"X-Requested-With": "anything"}, + result: true, + }, + { + matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}), + headers: map[string]string{}, + result: false, + }, +} + +type hostMatcherTest struct { + matcher *Route + url string + vars map[string]string + result bool +} + +var hostMatcherTests = []hostMatcherTest{ + { + matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"), + url: "http://abc.def.ghi/", + vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"}, + result: true, + }, + { + matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"), + url: "http://a.b.c/", + vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"}, + result: false, + }, +} + +type methodMatcherTest struct { + matcher methodMatcher + method string + result bool +} + +var methodMatcherTests = []methodMatcherTest{ + { + matcher: methodMatcher([]string{"GET", "POST", "PUT"}), + method: "GET", + result: true, + }, + { + matcher: methodMatcher([]string{"GET", "POST", "PUT"}), + method: "POST", + result: true, + }, + { + matcher: methodMatcher([]string{"GET", "POST", "PUT"}), + method: "PUT", + result: true, + }, + { + matcher: methodMatcher([]string{"GET", "POST", "PUT"}), + method: "DELETE", + result: false, + }, +} + +type pathMatcherTest struct { + matcher *Route + url string + vars map[string]string + result bool +} + +var pathMatcherTests = []pathMatcherTest{ + { + matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"), + url: "http://localhost:8080/123/456/789", + vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"}, + result: true, + }, + { + matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"), + url: "http://localhost:8080/1/2/3", + vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"}, + result: false, + }, +} + +type schemeMatcherTest struct { + matcher schemeMatcher + url string + result bool +} + +var schemeMatcherTests = []schemeMatcherTest{ + { + matcher: schemeMatcher([]string{"http", "https"}), + url: "http://localhost:8080/", + result: true, + }, + { + matcher: schemeMatcher([]string{"http", "https"}), + url: "https://localhost:8080/", + result: true, + }, + { + matcher: schemeMatcher([]string{"https"}), + url: "http://localhost:8080/", + result: false, + }, + { + matcher: schemeMatcher([]string{"http"}), + url: "https://localhost:8080/", + result: false, + }, +} + +type urlBuildingTest struct { + route *Route + vars []string + url string +} + +var urlBuildingTests = []urlBuildingTest{ + { + route: new(Route).Host("foo.domain.com"), + vars: []string{}, + url: "http://foo.domain.com", + }, + { + route: new(Route).Host("{subdomain}.domain.com"), + vars: []string{"subdomain", "bar"}, + url: "http://bar.domain.com", + }, + { + route: new(Route).Host("foo.domain.com").Path("/articles"), + vars: []string{}, + url: "http://foo.domain.com/articles", + }, + { + route: new(Route).Path("/articles"), + vars: []string{}, + url: "/articles", + }, + { + route: new(Route).Path("/articles/{category}/{id:[0-9]+}"), + vars: []string{"category", "technology", "id", "42"}, + url: "/articles/technology/42", + }, + { + route: new(Route).Host("{subdomain}.domain.com").Path("/articles/{category}/{id:[0-9]+}"), + vars: []string{"subdomain", "foo", "category", "technology", "id", "42"}, + url: "http://foo.domain.com/articles/technology/42", + }, +} + +func TestHeaderMatcher(t *testing.T) { + for _, v := range headerMatcherTests { + request, _ := http.NewRequest("GET", "http://localhost:8080/", nil) + for key, value := range v.headers { + request.Header.Add(key, value) + } + var routeMatch RouteMatch + result := v.matcher.Match(request, &routeMatch) + if result != v.result { + if v.result { + t.Errorf("%#v: should match %v.", v.matcher, request.Header) + } else { + t.Errorf("%#v: should not match %v.", v.matcher, request.Header) + } + } + } +} + +func TestHostMatcher(t *testing.T) { + for _, v := range hostMatcherTests { + request, _ := http.NewRequest("GET", v.url, nil) + var routeMatch RouteMatch + result := v.matcher.Match(request, &routeMatch) + vars := routeMatch.Vars + if result != v.result { + if v.result { + t.Errorf("%#v: should match %v.", v.matcher, v.url) + } else { + t.Errorf("%#v: should not match %v.", v.matcher, v.url) + } + } + if result { + if len(vars) != len(v.vars) { + t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars)) + } + for name, value := range vars { + if v.vars[name] != value { + t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value) + } + } + } else { + if len(vars) != 0 { + t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars)) + } + } + } +} + +func TestMethodMatcher(t *testing.T) { + for _, v := range methodMatcherTests { + request, _ := http.NewRequest(v.method, "http://localhost:8080/", nil) + var routeMatch RouteMatch + result := v.matcher.Match(request, &routeMatch) + if result != v.result { + if v.result { + t.Errorf("%#v: should match %v.", v.matcher, v.method) + } else { + t.Errorf("%#v: should not match %v.", v.matcher, v.method) + } + } + } +} + +func TestPathMatcher(t *testing.T) { + for _, v := range pathMatcherTests { + request, _ := http.NewRequest("GET", v.url, nil) + var routeMatch RouteMatch + result := v.matcher.Match(request, &routeMatch) + vars := routeMatch.Vars + if result != v.result { + if v.result { + t.Errorf("%#v: should match %v.", v.matcher, v.url) + } else { + t.Errorf("%#v: should not match %v.", v.matcher, v.url) + } + } + if result { + if len(vars) != len(v.vars) { + t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars)) + } + for name, value := range vars { + if v.vars[name] != value { + t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value) + } + } + } else { + if len(vars) != 0 { + t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars)) + } + } + } +} + +func TestSchemeMatcher(t *testing.T) { + for _, v := range schemeMatcherTests { + request, _ := http.NewRequest("GET", v.url, nil) + var routeMatch RouteMatch + result := v.matcher.Match(request, &routeMatch) + if result != v.result { + if v.result { + t.Errorf("%#v: should match %v.", v.matcher, v.url) + } else { + t.Errorf("%#v: should not match %v.", v.matcher, v.url) + } + } + } +} + +func TestUrlBuilding(t *testing.T) { + + for _, v := range urlBuildingTests { + u, _ := v.route.URL(v.vars...) + url := u.String() + if url != v.url { + t.Errorf("expected %v, got %v", v.url, url) + /* + reversePath := "" + reverseHost := "" + if v.route.pathTemplate != nil { + reversePath = v.route.pathTemplate.Reverse + } + if v.route.hostTemplate != nil { + reverseHost = v.route.hostTemplate.Reverse + } + + t.Errorf("%#v:\nexpected: %q\ngot: %q\nreverse path: %q\nreverse host: %q", v.route, v.url, url, reversePath, reverseHost) + */ + } + } + + ArticleHandler := func(w http.ResponseWriter, r *http.Request) { + } + + router := NewRouter() + router.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).Name("article") + + url, _ := router.Get("article").URL("category", "technology", "id", "42") + expected := "/articles/technology/42" + if url.String() != expected { + t.Errorf("Expected %v, got %v", expected, url.String()) + } +} + +func TestMatchedRouteName(t *testing.T) { + routeName := "stock" + router := NewRouter() + route := router.NewRoute().Path("/products/").Name(routeName) + + url := "http://www.domain.com/products/" + request, _ := http.NewRequest("GET", url, nil) + var rv RouteMatch + ok := router.Match(request, &rv) + + if !ok || rv.Route != route { + t.Errorf("Expected same route, got %+v.", rv.Route) + } + + retName := rv.Route.GetName() + if retName != routeName { + t.Errorf("Expected %q, got %q.", routeName, retName) + } +} + +func TestSubRouting(t *testing.T) { + // Example from docs. + router := NewRouter() + subrouter := router.NewRoute().Host("www.domain.com").Subrouter() + route := subrouter.NewRoute().Path("/products/").Name("products") + + url := "http://www.domain.com/products/" + request, _ := http.NewRequest("GET", url, nil) + var rv RouteMatch + ok := router.Match(request, &rv) + + if !ok || rv.Route != route { + t.Errorf("Expected same route, got %+v.", rv.Route) + } + + u, _ := router.Get("products").URL() + builtUrl := u.String() + // Yay, subroute aware of the domain when building! + if builtUrl != url { + t.Errorf("Expected %q, got %q.", url, builtUrl) + } +} + +func TestVariableNames(t *testing.T) { + route := new(Route).Host("{arg1}.domain.com").Path("/{arg1}/{arg2:[0-9]+}") + if route.err == nil { + t.Errorf("Expected error for duplicated variable names") + } +} + +func TestRedirectSlash(t *testing.T) { + var route *Route + var routeMatch RouteMatch + r := NewRouter() + + r.StrictSlash(false) + route = r.NewRoute() + if route.strictSlash != false { + t.Errorf("Expected false redirectSlash.") + } + + r.StrictSlash(true) + route = r.NewRoute() + if route.strictSlash != true { + t.Errorf("Expected true redirectSlash.") + } + + route = new(Route) + route.strictSlash = true + route.Path("/{arg1}/{arg2:[0-9]+}/") + request, _ := http.NewRequest("GET", "http://localhost/foo/123", nil) + routeMatch = RouteMatch{} + _ = route.Match(request, &routeMatch) + vars := routeMatch.Vars + if vars["arg1"] != "foo" { + t.Errorf("Expected foo.") + } + if vars["arg2"] != "123" { + t.Errorf("Expected 123.") + } + rsp := NewRecorder() + routeMatch.Handler.ServeHTTP(rsp, request) + if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123/" { + t.Errorf("Expected redirect header.") + } + + route = new(Route) + route.strictSlash = true + route.Path("/{arg1}/{arg2:[0-9]+}") + request, _ = http.NewRequest("GET", "http://localhost/foo/123/", nil) + routeMatch = RouteMatch{} + _ = route.Match(request, &routeMatch) + vars = routeMatch.Vars + if vars["arg1"] != "foo" { + t.Errorf("Expected foo.") + } + if vars["arg2"] != "123" { + t.Errorf("Expected 123.") + } + rsp = NewRecorder() + routeMatch.Handler.ServeHTTP(rsp, request) + if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123" { + t.Errorf("Expected redirect header.") + } +} + +// Test for the new regexp library, still not available in stable Go. +func TestNewRegexp(t *testing.T) { + var p *routeRegexp + var matches []string + + tests := map[string]map[string][]string{ + "/{foo:a{2}}": { + "/a": nil, + "/aa": {"aa"}, + "/aaa": nil, + "/aaaa": nil, + }, + "/{foo:a{2,}}": { + "/a": nil, + "/aa": {"aa"}, + "/aaa": {"aaa"}, + "/aaaa": {"aaaa"}, + }, + "/{foo:a{2,3}}": { + "/a": nil, + "/aa": {"aa"}, + "/aaa": {"aaa"}, + "/aaaa": nil, + }, + "/{foo:[a-z]{3}}/{bar:[a-z]{2}}": { + "/a": nil, + "/ab": nil, + "/abc": nil, + "/abcd": nil, + "/abc/ab": {"abc", "ab"}, + "/abc/abc": nil, + "/abcd/ab": nil, + }, + `/{foo:\w{3,}}/{bar:\d{2,}}`: { + "/a": nil, + "/ab": nil, + "/abc": nil, + "/abc/1": nil, + "/abc/12": {"abc", "12"}, + "/abcd/12": {"abcd", "12"}, + "/abcd/123": {"abcd", "123"}, + }, + } + + for pattern, paths := range tests { + p, _ = newRouteRegexp(pattern, false, false, false, false) + for path, result := range paths { + matches = p.regexp.FindStringSubmatch(path) + if result == nil { + if matches != nil { + t.Errorf("%v should not match %v.", pattern, path) + } + } else { + if len(matches) != len(result)+1 { + t.Errorf("Expected %v matches, got %v.", len(result)+1, len(matches)) + } else { + for k, v := range result { + if matches[k+1] != v { + t.Errorf("Expected %v, got %v.", v, matches[k+1]) + } + } + } + } + } + } +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/regexp.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/regexp.go new file mode 100644 index 000000000..a6305483d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/regexp.go @@ -0,0 +1,276 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "bytes" + "fmt" + "net/http" + "net/url" + "regexp" + "strings" +) + +// newRouteRegexp parses a route template and returns a routeRegexp, +// used to match a host, a path or a query string. +// +// It will extract named variables, assemble a regexp to be matched, create +// a "reverse" template to build URLs and compile regexps to validate variable +// values used in URL building. +// +// Previously we accepted only Python-like identifiers for variable +// names ([a-zA-Z_][a-zA-Z0-9_]*), but currently the only restriction is that +// name and pattern can't be empty, and names can't contain a colon. +func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash bool) (*routeRegexp, error) { + // Check if it is well-formed. + idxs, errBraces := braceIndices(tpl) + if errBraces != nil { + return nil, errBraces + } + // Backup the original. + template := tpl + // Now let's parse it. + defaultPattern := "[^/]+" + if matchQuery { + defaultPattern = "[^?&]+" + matchPrefix = true + } else if matchHost { + defaultPattern = "[^.]+" + matchPrefix = false + } + // Only match strict slash if not matching + if matchPrefix || matchHost || matchQuery { + strictSlash = false + } + // Set a flag for strictSlash. + endSlash := false + if strictSlash && strings.HasSuffix(tpl, "/") { + tpl = tpl[:len(tpl)-1] + endSlash = true + } + varsN := make([]string, len(idxs)/2) + varsR := make([]*regexp.Regexp, len(idxs)/2) + pattern := bytes.NewBufferString("") + if !matchQuery { + pattern.WriteByte('^') + } + reverse := bytes.NewBufferString("") + var end int + var err error + for i := 0; i < len(idxs); i += 2 { + // Set all values we are interested in. + raw := tpl[end:idxs[i]] + end = idxs[i+1] + parts := strings.SplitN(tpl[idxs[i]+1:end-1], ":", 2) + name := parts[0] + patt := defaultPattern + if len(parts) == 2 { + patt = parts[1] + } + // Name or pattern can't be empty. + if name == "" || patt == "" { + return nil, fmt.Errorf("mux: missing name or pattern in %q", + tpl[idxs[i]:end]) + } + // Build the regexp pattern. + fmt.Fprintf(pattern, "%s(%s)", regexp.QuoteMeta(raw), patt) + // Build the reverse template. + fmt.Fprintf(reverse, "%s%%s", raw) + // Append variable name and compiled pattern. + varsN[i/2] = name + varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt)) + if err != nil { + return nil, err + } + } + // Add the remaining. + raw := tpl[end:] + pattern.WriteString(regexp.QuoteMeta(raw)) + if strictSlash { + pattern.WriteString("[/]?") + } + if !matchPrefix { + pattern.WriteByte('$') + } + reverse.WriteString(raw) + if endSlash { + reverse.WriteByte('/') + } + // Compile full regexp. + reg, errCompile := regexp.Compile(pattern.String()) + if errCompile != nil { + return nil, errCompile + } + // Done! + return &routeRegexp{ + template: template, + matchHost: matchHost, + matchQuery: matchQuery, + strictSlash: strictSlash, + regexp: reg, + reverse: reverse.String(), + varsN: varsN, + varsR: varsR, + }, nil +} + +// routeRegexp stores a regexp to match a host or path and information to +// collect and validate route variables. +type routeRegexp struct { + // The unmodified template. + template string + // True for host match, false for path or query string match. + matchHost bool + // True for query string match, false for path and host match. + matchQuery bool + // The strictSlash value defined on the route, but disabled if PathPrefix was used. + strictSlash bool + // Expanded regexp. + regexp *regexp.Regexp + // Reverse template. + reverse string + // Variable names. + varsN []string + // Variable regexps (validators). + varsR []*regexp.Regexp +} + +// Match matches the regexp against the URL host or path. +func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool { + if !r.matchHost { + if r.matchQuery { + return r.regexp.MatchString(req.URL.RawQuery) + } else { + return r.regexp.MatchString(req.URL.Path) + } + } + return r.regexp.MatchString(getHost(req)) +} + +// url builds a URL part using the given values. +func (r *routeRegexp) url(pairs ...string) (string, error) { + values, err := mapFromPairs(pairs...) + if err != nil { + return "", err + } + urlValues := make([]interface{}, len(r.varsN)) + for k, v := range r.varsN { + value, ok := values[v] + if !ok { + return "", fmt.Errorf("mux: missing route variable %q", v) + } + urlValues[k] = value + } + rv := fmt.Sprintf(r.reverse, urlValues...) + if !r.regexp.MatchString(rv) { + // The URL is checked against the full regexp, instead of checking + // individual variables. This is faster but to provide a good error + // message, we check individual regexps if the URL doesn't match. + for k, v := range r.varsN { + if !r.varsR[k].MatchString(values[v]) { + return "", fmt.Errorf( + "mux: variable %q doesn't match, expected %q", values[v], + r.varsR[k].String()) + } + } + } + return rv, nil +} + +// braceIndices returns the first level curly brace indices from a string. +// It returns an error in case of unbalanced braces. +func braceIndices(s string) ([]int, error) { + var level, idx int + idxs := make([]int, 0) + for i := 0; i < len(s); i++ { + switch s[i] { + case '{': + if level++; level == 1 { + idx = i + } + case '}': + if level--; level == 0 { + idxs = append(idxs, idx, i+1) + } else if level < 0 { + return nil, fmt.Errorf("mux: unbalanced braces in %q", s) + } + } + } + if level != 0 { + return nil, fmt.Errorf("mux: unbalanced braces in %q", s) + } + return idxs, nil +} + +// ---------------------------------------------------------------------------- +// routeRegexpGroup +// ---------------------------------------------------------------------------- + +// routeRegexpGroup groups the route matchers that carry variables. +type routeRegexpGroup struct { + host *routeRegexp + path *routeRegexp + queries []*routeRegexp +} + +// setMatch extracts the variables from the URL once a route matches. +func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) { + // Store host variables. + if v.host != nil { + hostVars := v.host.regexp.FindStringSubmatch(getHost(req)) + if hostVars != nil { + for k, v := range v.host.varsN { + m.Vars[v] = hostVars[k+1] + } + } + } + // Store path variables. + if v.path != nil { + pathVars := v.path.regexp.FindStringSubmatch(req.URL.Path) + if pathVars != nil { + for k, v := range v.path.varsN { + m.Vars[v] = pathVars[k+1] + } + // Check if we should redirect. + if v.path.strictSlash { + p1 := strings.HasSuffix(req.URL.Path, "/") + p2 := strings.HasSuffix(v.path.template, "/") + if p1 != p2 { + u, _ := url.Parse(req.URL.String()) + if p1 { + u.Path = u.Path[:len(u.Path)-1] + } else { + u.Path += "/" + } + m.Handler = http.RedirectHandler(u.String(), 301) + } + } + } + } + // Store query string variables. + rawQuery := req.URL.RawQuery + for _, q := range v.queries { + queryVars := q.regexp.FindStringSubmatch(rawQuery) + if queryVars != nil { + for k, v := range q.varsN { + m.Vars[v] = queryVars[k+1] + } + } + } +} + +// getHost tries its best to return the request host. +func getHost(r *http.Request) string { + if r.URL.IsAbs() { + return r.URL.Host + } + host := r.Host + // Slice off any port information. + if i := strings.Index(host, ":"); i != -1 { + host = host[:i] + } + return host + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/route.go b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/route.go new file mode 100644 index 000000000..c310e66bc --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/gorilla/mux/route.go @@ -0,0 +1,524 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strings" +) + +// Route stores information to match a request and build URLs. +type Route struct { + // Parent where the route was registered (a Router). + parent parentRoute + // Request handler for the route. + handler http.Handler + // List of matchers. + matchers []matcher + // Manager for the variables from host and path. + regexp *routeRegexpGroup + // If true, when the path pattern is "/path/", accessing "/path" will + // redirect to the former and vice versa. + strictSlash bool + // If true, this route never matches: it is only used to build URLs. + buildOnly bool + // The name used to build URLs. + name string + // Error resulted from building a route. + err error +} + +// Match matches the route against the request. +func (r *Route) Match(req *http.Request, match *RouteMatch) bool { + if r.buildOnly || r.err != nil { + return false + } + // Match everything. + for _, m := range r.matchers { + if matched := m.Match(req, match); !matched { + return false + } + } + // Yay, we have a match. Let's collect some info about it. + if match.Route == nil { + match.Route = r + } + if match.Handler == nil { + match.Handler = r.handler + } + if match.Vars == nil { + match.Vars = make(map[string]string) + } + // Set variables. + if r.regexp != nil { + r.regexp.setMatch(req, match, r) + } + return true +} + +// ---------------------------------------------------------------------------- +// Route attributes +// ---------------------------------------------------------------------------- + +// GetError returns an error resulted from building the route, if any. +func (r *Route) GetError() error { + return r.err +} + +// BuildOnly sets the route to never match: it is only used to build URLs. +func (r *Route) BuildOnly() *Route { + r.buildOnly = true + return r +} + +// Handler -------------------------------------------------------------------- + +// Handler sets a handler for the route. +func (r *Route) Handler(handler http.Handler) *Route { + if r.err == nil { + r.handler = handler + } + return r +} + +// HandlerFunc sets a handler function for the route. +func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route { + return r.Handler(http.HandlerFunc(f)) +} + +// GetHandler returns the handler for the route, if any. +func (r *Route) GetHandler() http.Handler { + return r.handler +} + +// Name ----------------------------------------------------------------------- + +// Name sets the name for the route, used to build URLs. +// If the name was registered already it will be overwritten. +func (r *Route) Name(name string) *Route { + if r.name != "" { + r.err = fmt.Errorf("mux: route already has name %q, can't set %q", + r.name, name) + } + if r.err == nil { + r.name = name + r.getNamedRoutes()[name] = r + } + return r +} + +// GetName returns the name for the route, if any. +func (r *Route) GetName() string { + return r.name +} + +// ---------------------------------------------------------------------------- +// Matchers +// ---------------------------------------------------------------------------- + +// matcher types try to match a request. +type matcher interface { + Match(*http.Request, *RouteMatch) bool +} + +// addMatcher adds a matcher to the route. +func (r *Route) addMatcher(m matcher) *Route { + if r.err == nil { + r.matchers = append(r.matchers, m) + } + return r +} + +// addRegexpMatcher adds a host or path matcher and builder to a route. +func (r *Route) addRegexpMatcher(tpl string, matchHost, matchPrefix, matchQuery bool) error { + if r.err != nil { + return r.err + } + r.regexp = r.getRegexpGroup() + if !matchHost && !matchQuery { + if len(tpl) == 0 || tpl[0] != '/' { + return fmt.Errorf("mux: path must start with a slash, got %q", tpl) + } + if r.regexp.path != nil { + tpl = strings.TrimRight(r.regexp.path.template, "/") + tpl + } + } + rr, err := newRouteRegexp(tpl, matchHost, matchPrefix, matchQuery, r.strictSlash) + if err != nil { + return err + } + for _, q := range r.regexp.queries { + if err = uniqueVars(rr.varsN, q.varsN); err != nil { + return err + } + } + if matchHost { + if r.regexp.path != nil { + if err = uniqueVars(rr.varsN, r.regexp.path.varsN); err != nil { + return err + } + } + r.regexp.host = rr + } else { + if r.regexp.host != nil { + if err = uniqueVars(rr.varsN, r.regexp.host.varsN); err != nil { + return err + } + } + if matchQuery { + r.regexp.queries = append(r.regexp.queries, rr) + } else { + r.regexp.path = rr + } + } + r.addMatcher(rr) + return nil +} + +// Headers -------------------------------------------------------------------- + +// headerMatcher matches the request against header values. +type headerMatcher map[string]string + +func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool { + return matchMap(m, r.Header, true) +} + +// Headers adds a matcher for request header values. +// It accepts a sequence of key/value pairs to be matched. For example: +// +// r := mux.NewRouter() +// r.Headers("Content-Type", "application/json", +// "X-Requested-With", "XMLHttpRequest") +// +// The above route will only match if both request header values match. +// +// It the value is an empty string, it will match any value if the key is set. +func (r *Route) Headers(pairs ...string) *Route { + if r.err == nil { + var headers map[string]string + headers, r.err = mapFromPairs(pairs...) + return r.addMatcher(headerMatcher(headers)) + } + return r +} + +// Host ----------------------------------------------------------------------- + +// Host adds a matcher for the URL host. +// It accepts a template with zero or more URL variables enclosed by {}. +// Variables can define an optional regexp pattern to me matched: +// +// - {name} matches anything until the next dot. +// +// - {name:pattern} matches the given regexp pattern. +// +// For example: +// +// r := mux.NewRouter() +// r.Host("www.domain.com") +// r.Host("{subdomain}.domain.com") +// r.Host("{subdomain:[a-z]+}.domain.com") +// +// Variable names must be unique in a given route. They can be retrieved +// calling mux.Vars(request). +func (r *Route) Host(tpl string) *Route { + r.err = r.addRegexpMatcher(tpl, true, false, false) + return r +} + +// MatcherFunc ---------------------------------------------------------------- + +// MatcherFunc is the function signature used by custom matchers. +type MatcherFunc func(*http.Request, *RouteMatch) bool + +func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool { + return m(r, match) +} + +// MatcherFunc adds a custom function to be used as request matcher. +func (r *Route) MatcherFunc(f MatcherFunc) *Route { + return r.addMatcher(f) +} + +// Methods -------------------------------------------------------------------- + +// methodMatcher matches the request against HTTP methods. +type methodMatcher []string + +func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool { + return matchInArray(m, r.Method) +} + +// Methods adds a matcher for HTTP methods. +// It accepts a sequence of one or more methods to be matched, e.g.: +// "GET", "POST", "PUT". +func (r *Route) Methods(methods ...string) *Route { + for k, v := range methods { + methods[k] = strings.ToUpper(v) + } + return r.addMatcher(methodMatcher(methods)) +} + +// Path ----------------------------------------------------------------------- + +// Path adds a matcher for the URL path. +// It accepts a template with zero or more URL variables enclosed by {}. The +// template must start with a "/". +// Variables can define an optional regexp pattern to me matched: +// +// - {name} matches anything until the next slash. +// +// - {name:pattern} matches the given regexp pattern. +// +// For example: +// +// r := mux.NewRouter() +// r.Path("/products/").Handler(ProductsHandler) +// r.Path("/products/{key}").Handler(ProductsHandler) +// r.Path("/articles/{category}/{id:[0-9]+}"). +// Handler(ArticleHandler) +// +// Variable names must be unique in a given route. They can be retrieved +// calling mux.Vars(request). +func (r *Route) Path(tpl string) *Route { + r.err = r.addRegexpMatcher(tpl, false, false, false) + return r +} + +// PathPrefix ----------------------------------------------------------------- + +// PathPrefix adds a matcher for the URL path prefix. This matches if the given +// template is a prefix of the full URL path. See Route.Path() for details on +// the tpl argument. +// +// Note that it does not treat slashes specially ("/foobar/" will be matched by +// the prefix "/foo") so you may want to use a trailing slash here. +// +// Also note that the setting of Router.StrictSlash() has no effect on routes +// with a PathPrefix matcher. +func (r *Route) PathPrefix(tpl string) *Route { + r.err = r.addRegexpMatcher(tpl, false, true, false) + return r +} + +// Query ---------------------------------------------------------------------- + +// Queries adds a matcher for URL query values. +// It accepts a sequence of key/value pairs. Values may define variables. +// For example: +// +// r := mux.NewRouter() +// r.Queries("foo", "bar", "id", "{id:[0-9]+}") +// +// The above route will only match if the URL contains the defined queries +// values, e.g.: ?foo=bar&id=42. +// +// It the value is an empty string, it will match any value if the key is set. +// +// Variables can define an optional regexp pattern to me matched: +// +// - {name} matches anything until the next slash. +// +// - {name:pattern} matches the given regexp pattern. +func (r *Route) Queries(pairs ...string) *Route { + length := len(pairs) + if length%2 != 0 { + r.err = fmt.Errorf( + "mux: number of parameters must be multiple of 2, got %v", pairs) + return nil + } + for i := 0; i < length; i += 2 { + if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], false, true, true); r.err != nil { + return r + } + } + + return r +} + +// Schemes -------------------------------------------------------------------- + +// schemeMatcher matches the request against URL schemes. +type schemeMatcher []string + +func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool { + return matchInArray(m, r.URL.Scheme) +} + +// Schemes adds a matcher for URL schemes. +// It accepts a sequence of schemes to be matched, e.g.: "http", "https". +func (r *Route) Schemes(schemes ...string) *Route { + for k, v := range schemes { + schemes[k] = strings.ToLower(v) + } + return r.addMatcher(schemeMatcher(schemes)) +} + +// Subrouter ------------------------------------------------------------------ + +// Subrouter creates a subrouter for the route. +// +// It will test the inner routes only if the parent route matched. For example: +// +// r := mux.NewRouter() +// s := r.Host("www.domain.com").Subrouter() +// s.HandleFunc("/products/", ProductsHandler) +// s.HandleFunc("/products/{key}", ProductHandler) +// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) +// +// Here, the routes registered in the subrouter won't be tested if the host +// doesn't match. +func (r *Route) Subrouter() *Router { + router := &Router{parent: r, strictSlash: r.strictSlash} + r.addMatcher(router) + return router +} + +// ---------------------------------------------------------------------------- +// URL building +// ---------------------------------------------------------------------------- + +// URL builds a URL for the route. +// +// It accepts a sequence of key/value pairs for the route variables. For +// example, given this route: +// +// r := mux.NewRouter() +// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). +// Name("article") +// +// ...a URL for it can be built using: +// +// url, err := r.Get("article").URL("category", "technology", "id", "42") +// +// ...which will return an url.URL with the following path: +// +// "/articles/technology/42" +// +// This also works for host variables: +// +// r := mux.NewRouter() +// r.Host("{subdomain}.domain.com"). +// HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). +// Name("article") +// +// // url.String() will be "http://news.domain.com/articles/technology/42" +// url, err := r.Get("article").URL("subdomain", "news", +// "category", "technology", +// "id", "42") +// +// All variables defined in the route are required, and their values must +// conform to the corresponding patterns. +func (r *Route) URL(pairs ...string) (*url.URL, error) { + if r.err != nil { + return nil, r.err + } + if r.regexp == nil { + return nil, errors.New("mux: route doesn't have a host or path") + } + var scheme, host, path string + var err error + if r.regexp.host != nil { + // Set a default scheme. + scheme = "http" + if host, err = r.regexp.host.url(pairs...); err != nil { + return nil, err + } + } + if r.regexp.path != nil { + if path, err = r.regexp.path.url(pairs...); err != nil { + return nil, err + } + } + return &url.URL{ + Scheme: scheme, + Host: host, + Path: path, + }, nil +} + +// URLHost builds the host part of the URL for a route. See Route.URL(). +// +// The route must have a host defined. +func (r *Route) URLHost(pairs ...string) (*url.URL, error) { + if r.err != nil { + return nil, r.err + } + if r.regexp == nil || r.regexp.host == nil { + return nil, errors.New("mux: route doesn't have a host") + } + host, err := r.regexp.host.url(pairs...) + if err != nil { + return nil, err + } + return &url.URL{ + Scheme: "http", + Host: host, + }, nil +} + +// URLPath builds the path part of the URL for a route. See Route.URL(). +// +// The route must have a path defined. +func (r *Route) URLPath(pairs ...string) (*url.URL, error) { + if r.err != nil { + return nil, r.err + } + if r.regexp == nil || r.regexp.path == nil { + return nil, errors.New("mux: route doesn't have a path") + } + path, err := r.regexp.path.url(pairs...) + if err != nil { + return nil, err + } + return &url.URL{ + Path: path, + }, nil +} + +// ---------------------------------------------------------------------------- +// parentRoute +// ---------------------------------------------------------------------------- + +// parentRoute allows routes to know about parent host and path definitions. +type parentRoute interface { + getNamedRoutes() map[string]*Route + getRegexpGroup() *routeRegexpGroup +} + +// getNamedRoutes returns the map where named routes are registered. +func (r *Route) getNamedRoutes() map[string]*Route { + if r.parent == nil { + // During tests router is not always set. + r.parent = NewRouter() + } + return r.parent.getNamedRoutes() +} + +// getRegexpGroup returns regexp definitions from this route. +func (r *Route) getRegexpGroup() *routeRegexpGroup { + if r.regexp == nil { + if r.parent == nil { + // During tests router is not always set. + r.parent = NewRouter() + } + regexp := r.parent.getRegexpGroup() + if regexp == nil { + r.regexp = new(routeRegexpGroup) + } else { + // Copy. + r.regexp = &routeRegexpGroup{ + host: regexp.host, + path: regexp.path, + queries: regexp.queries, + } + } + } + return r.regexp +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/.gitignore b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/.gitignore new file mode 100644 index 000000000..ea9f6bc3c --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/.gitignore @@ -0,0 +1,6 @@ +*.o +*.a +*.so +*~ +*.dSYM +*.syso \ No newline at end of file diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/BUILDDEPS.md b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/BUILDDEPS.md new file mode 100644 index 000000000..df3770b29 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/BUILDDEPS.md @@ -0,0 +1,80 @@ +## Ubuntu (Kylin) 14.04 +### Build Dependencies +This installation document assumes Ubuntu 14.04 or later on x86-64 platform. + +##### Install YASM + +Erasure depends on Intel ISAL library, ISAL uses Intel AVX2 processor instructions, to compile these files one needs to install ``yasm`` which supports AVX2 instructions. AVX2 support only ended in ``yasm`` from version ``1.2.0``, any version below ``1.2.0`` will throw a build error. + +```sh +$ sudo apt-get install yasm +``` + +##### Install Go 1.4+ +Download Go 1.4+ from [https://golang.org/dl/](https://golang.org/dl/) and extract it into ``${HOME}/local`` and setup ``${HOME}/mygo`` as your project workspace folder. +For example: +```sh +.... Extract and install golang .... + +$ wget https://storage.googleapis.com/golang/go1.4.linux-amd64.tar.gz +$ mkdir -p ${HOME}/local +$ mkdir -p $HOME/mygo +$ tar -C ${HOME}/local -xzf go1.4.linux-amd64.tar.gz + +.... Export necessary environment variables .... + +$ export PATH=$PATH:${HOME}/local/go/bin +$ export GOROOT=${HOME}/local/go +$ export GOPATH=$HOME/mygo +$ export PATH=$PATH:$GOPATH/bin + +.... Add paths to your bashrc .... + +$ echo "export PATH=$PATH:${HOME}/local/go/bin" >> ${HOME}/.bashrc +$ echo "export GOROOT=${HOME}/local/go" >> ${HOME}/.bashrc +$ echo "export GOPATH=$HOME/mygo" >> ${HOME}/.bashrc +$ echo "export PATH=$PATH:$GOPATH/bin" >> ${HOME}/.bashrc +``` + +## Mac OSX (Yosemite) 10.10 +### Build Dependencies +This installation document assumes Mac OSX Yosemite 10.10 or later on x86-64 platform. + +##### Install brew +```sh +$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" +``` + +##### Install Git +```sh +$ brew install git +``` + +##### Install YASM + +Erasure depends on Intel ISAL library, ISAL uses Intel AVX2 processor instructions, to compile these files one needs to install ``yasm`` which supports AVX2 instructions. AVX2 support only ended in ``yasm`` from version ``1.2.0``, any version below ``1.2.0`` will throw a build error. + +```sh +$ brew install yasm +``` + +##### Install Go 1.4+ +On MacOSX ``brew.sh`` is the best way to install golang + +For example: +```sh +.... Install golang using `brew` .... + +$ brew install go +$ mkdir -p $HOME/mygo + +.... Export necessary environment variables .... + +$ export GOPATH=$HOME/mygo +$ export PATH=$PATH:$GOPATH/bin + +.... Add paths to your bashrc .... + +$ echo "export GOPATH=$HOME/mygo" >> ${HOME}/.bashrc +$ echo "export PATH=$PATH:$GOPATH/bin" >> ${HOME}/.bashrc +``` diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/CONTRIBUTING.md b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/CONTRIBUTING.md new file mode 100644 index 000000000..1dfc6a0cb --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/CONTRIBUTING.md @@ -0,0 +1,30 @@ +### Setup your Erasure Github Repository +Fork [Erasure upstream](https://github.com/minio-io/erasure/fork) source repository to your own personal repository. Copy the URL and pass it to ``go get`` command. Go uses git to clone a copy into your project workspace folder. +```sh +$ git clone https://github.com/$USER_ID/erasure +$ cd erasure +$ mkdir -p ${GOPATH}/src/github.com/minio-io +$ ln -s ${PWD} $GOPATH/src/github.com/minio-io/ +``` + +### Compiling Erasure from source +```sh +$ go generate +$ go build +``` +### Developer Guidelines +To make the process as seamless as possible, we ask for the following: +* Go ahead and fork the project and make your changes. We encourage pull requests to discuss code changes. + - Fork it + - Create your feature branch (git checkout -b my-new-feature) + - Commit your changes (git commit -am 'Add some feature') + - Push to the branch (git push origin my-new-feature) + - Create new Pull Request +* When you're ready to create a pull request, be sure to: + - Have test cases for the new code. If you have questions about how to do it, please ask in your pull request. + - Run `go fmt` + - Squash your commits into a single commit. `git rebase -i`. It's okay to force update your pull request. + - Make sure `go test -race ./...` and `go build` completes. +* Read [Effective Go](https://github.com/golang/go/wiki/CodeReviewComments) article from Golang project + - `Erasure` project is strictly conformant with Golang style + - if you happen to observe offending code, please feel free to send a pull request diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/LICENSE.INTEL b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/LICENSE.INTEL new file mode 100644 index 000000000..667056695 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/LICENSE.INTEL @@ -0,0 +1,26 @@ + Copyright(c) 2011-2014 Intel Corporation All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/LICENSE.MINIO b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/LICENSE.MINIO new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/LICENSE.MINIO @@ -0,0 +1,202 @@ + + 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/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/README.md b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/README.md new file mode 100644 index 000000000..cafa80eb3 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/README.md @@ -0,0 +1,25 @@ +## Introduction + +Erasure is an open source Golang library written on top of ISAL (Intel Intelligent Storage Library) released under [Apache license v2](./LICENSE) + +### Developers +* [Get Source](./CONTRIBUTING.md) +* [Build Dependencies](./BUILDDEPS.md) +* [Development Workflow](./CONTRIBUTING.md#developer-guidelines) +* [Developer discussions and bugs](https://github.com/Minio-io/erasure/issues) + +### Supported platforms + +| Name | Supported | +| ------------- | ------------- | +| Linux | Yes | +| Windows | Not yet | +| Mac OSX | Yes | + +### Supported architectures + +| Arch | Supported | +| ------------- | ------------- | +| x86-64 | Yes | +| arm64 | Not yet| +| i386 | Never | diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/RELEASE-NOTES.INTEL b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/RELEASE-NOTES.INTEL new file mode 100644 index 000000000..b4b601824 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/RELEASE-NOTES.INTEL @@ -0,0 +1,49 @@ +================================================================================ +v2.10 Intel Intelligent Storage Acceleration Library Release Notes + Open Source Version +================================================================================ + +================================================================================ +RELEASE NOTE CONTENTS +================================================================================ +1. KNOWN ISSUES +2. FIXED ISSUES +3. CHANGE LOG & FEATURES ADDED + +================================================================================ +1. KNOWN ISSUES +================================================================================ + +* Only erasure code unit included in open source version at this time. + +* Perf tests do not run in Windows environment. + +* Leaving /bin directories from builds in unit directories will cause the + top-level make build to fail. Build only in top-level or ensure unit + directories are clean of objects and /bin. + +* 32-bit lib is not supported in Windows. + +================================================================================ +2. FIXED ISSUES +================================================================================ +v2.10 + +* Fix for windows register save overlap in gf_{3-6}vect_dot_prod_sse.asm. Only + affects windows versions of erasure code. GP register saves/restore were + pushed to same stack area as XMM. + +================================================================================ +3. CHANGE LOG & FEATURES ADDED +================================================================================ +v2.10 + +* Erasure code updates + - New AVX and AVX2 support functions. + - Changes min len requirement on gf_vect_dot_prod() to 32 from 16. + - Tests include both source and parity recovery with ec_encode_data(). + - New encoding examples with Vandermonde or Cauchy matrix. + +v2.8 + +* First open release of erasure code unit that is part of ISA-L. diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/RELEASE-NOTES.MINIO b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/RELEASE-NOTES.MINIO new file mode 100644 index 000000000..bf3ed1ece --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/RELEASE-NOTES.MINIO @@ -0,0 +1,3 @@ +v1.0 - Erasure Golang Package +============================ +- First release, supports only amd64 or x86-64 architecture \ No newline at end of file diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/cauchy_test.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/cauchy_test.go new file mode 100644 index 000000000..37f28c74c --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/cauchy_test.go @@ -0,0 +1,71 @@ +/* + * Minimalist Object Storage, (C) 2014 Minio, Inc. + * + * 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 erasure + +import ( + "bytes" + "testing" + + . "gopkg.in/check.v1" +) + +type MySuite struct{} + +var _ = Suite(&MySuite{}) + +func Test(t *testing.T) { TestingT(t) } + +const ( + k = 10 + m = 5 +) + +func (s *MySuite) TestCauchyEncodeDecodeFailure(c *C) { + ep, _ := ValidateParams(k, m, Cauchy) + + data := []byte("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.") + + e := NewErasure(ep) + chunks, err := e.Encode(data) + c.Assert(err, IsNil) + + errorIndex := []int{0, 3, 5, 9, 11, 13} + chunks = corruptChunks(chunks, errorIndex) + + _, err = e.Decode(chunks, len(data)) + c.Assert(err, Not(IsNil)) +} + +func (s *MySuite) TestCauchyEncodeDecodeSuccess(c *C) { + ep, _ := ValidateParams(k, m, Cauchy) + + data := []byte("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.") + + e := NewErasure(ep) + chunks, err := e.Encode(data) + c.Assert(err, IsNil) + + errorIndex := []int{0, 3, 5, 9, 13} + chunks = corruptChunks(chunks, errorIndex) + + recoveredData, err := e.Decode(chunks, len(data)) + c.Assert(err, IsNil) + + if !bytes.Equal(data, recoveredData) { + c.Fatalf("Recovered data mismatches with original data") + } +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ctypes.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ctypes.go new file mode 100644 index 000000000..da04076fc --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ctypes.go @@ -0,0 +1,59 @@ +/* + * Minimalist Object Storage, (C) 2014 Minio, Inc. + * + * 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 erasure + +// #include +import "C" +import ( + "fmt" + "unsafe" +) + +// intSlice2CIntArray converts Go int slice to C int array +func intSlice2CIntArray(srcErrList []int) *C.int32_t { + var sizeErrInt = int(unsafe.Sizeof(srcErrList[0])) + switch sizeInt { + case sizeErrInt: + return (*C.int32_t)(unsafe.Pointer(&srcErrList[0])) + case sizeInt8: + int8Array := make([]int8, len(srcErrList)) + for i, v := range srcErrList { + int8Array[i] = int8(v) + } + return (*C.int32_t)(unsafe.Pointer(&int8Array[0])) + case sizeInt16: + int16Array := make([]int16, len(srcErrList)) + for i, v := range srcErrList { + int16Array[i] = int16(v) + } + return (*C.int32_t)(unsafe.Pointer(&int16Array[0])) + case sizeInt32: + int32Array := make([]int32, len(srcErrList)) + for i, v := range srcErrList { + int32Array[i] = int32(v) + } + return (*C.int32_t)(unsafe.Pointer(&int32Array[0])) + case sizeInt64: + int64Array := make([]int64, len(srcErrList)) + for i, v := range srcErrList { + int64Array[i] = int64(v) + } + return (*C.int32_t)(unsafe.Pointer(&int64Array[0])) + default: + panic(fmt.Sprintf("Unsupported: %d", sizeInt)) + } +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/doc.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/doc.go new file mode 100644 index 000000000..ce47fb64d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/doc.go @@ -0,0 +1,67 @@ +// Package erasure is a Go wrapper for the Intel Intelligent Storage +// Acceleration Library (Intel ISA-L). Intel ISA-L is a CPU optimized +// implementation of erasure coding algorithms. +// +// For more information on Intel ISA-L, please visit: +// https://01.org/intel%C2%AE-storage-acceleration-library-open-source-version +// +// Usage: +// +// Encode encodes a block of data. The input is the original data. The output +// is a 2 tuple containing (k + m) chunks of erasure encoded data and the +// length of the original object. +// +// Decode decodes 2 tuple data containing (k + m) chunks back into its original form. +// Additionally original block length should also be provided as input. +// +// Decoded data is exactly similar in length and content as the original data. +// +// Encoding data may be performed in 3 steps. +// +// 1. Create a parse set of encoder parameters +// 2. Create a new encoder +// 3. Encode data +// +// Decoding data is also performed in 3 steps. +// +// 1. Create a parse set of encoder parameters for validation +// 2. Create a new encoder +// 3. Decode data +// +// Erasure parameters contain three configurable elements: +// ValidateParams(k, m, technique int) (ErasureParams, error) +// k - Number of rows in matrix +// m - Number of colums in matrix +// technique - Matrix type, can be either Cauchy (recommended) or Vandermonde +// constraints: k + m < Galois Field (2^8) +// +// Choosing right parity and matrix technique is left for application to decide. +// +// But here are the few points to keep in mind +// +// Techniques: +// - Vandermonde is most commonly used method for choosing coefficients in erasure +// encoding but does not guarantee invertable for every sub matrix. +// Users may want to adjust for k > 5. (k is data blocks) +// - Whereas Cauchy is our recommended method for choosing coefficients in erasure coding. +// Since any sub-matrix of a Cauchy matrix is invertable. +// +// Total blocks: +// - Data blocks and Parity blocks should not be greater than 'Galois Field' (2^8) +// +// Example +// +// Creating and using an encoder +// var bytes []byte +// params := erasure.ValidateParams(10, 5, erasure.Cauchy) +// encoder := erasure.NewErasure(params) +// encodedData, length := encoder.Encode(bytes) +// +// Creating and using a decoder +// var encodedData [][]byte +// var length int +// params := erasure.ValidateParams(10, 5, erasure.Cauchy) +// encoder := erasure.NewErasure(params) +// originalData, err := encoder.Decode(encodedData, length) +// +package erasure diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/docs/isa-l_open_src_2.10.pdf b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/docs/isa-l_open_src_2.10.pdf new file mode 100644 index 000000000..b2d6e1447 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/docs/isa-l_open_src_2.10.pdf @@ -0,0 +1,5429 @@ +%PDF-1.4 +%ĐÔÅØ +5 0 obj +<< /S /GoTo /D (chapter.1) >> +endobj +8 0 obj +(\376\377\000S\000t\000o\000r\000a\000g\000e\000\040\000L\000i\000b\000r\000a\000r\000y) +endobj +9 0 obj +<< /S /GoTo /D (section.1.1) >> +endobj +12 0 obj +(\376\377\000A\000b\000o\000u\000t\000\040\000T\000h\000i\000s\000\040\000D\000o\000c\000u\000m\000e\000n\000t) +endobj +13 0 obj +<< /S /GoTo /D (section.1.2) >> +endobj +16 0 obj +(\376\377\000O\000v\000e\000r\000v\000i\000e\000w) +endobj +17 0 obj +<< /S /GoTo /D (section.1.3) >> +endobj +20 0 obj +(\376\377\000E\000r\000a\000s\000u\000r\000e\000\040\000C\000o\000d\000e\000\040\000F\000u\000n\000c\000t\000i\000o\000n\000s) +endobj +21 0 obj +<< /S /GoTo /D (section.1.4) >> +endobj +24 0 obj +(\376\377\000S\000y\000s\000t\000e\000m\000\040\000R\000e\000q\000u\000i\000r\000e\000m\000e\000n\000t\000s) +endobj +25 0 obj +<< /S /GoTo /D (chapter.2) >> +endobj +28 0 obj +(\376\377\000F\000u\000n\000c\000t\000i\000o\000n\000\040\000V\000e\000r\000s\000i\000o\000n\000\040\000N\000u\000m\000b\000e\000r\000s) +endobj +29 0 obj +<< /S /GoTo /D (section.2.1) >> +endobj +32 0 obj +(\376\377\000F\000u\000n\000c\000t\000i\000o\000n\000\040\000V\000e\000r\000s\000i\000o\000n\000\040\000N\000u\000m\000b\000e\000r\000s) +endobj +33 0 obj +<< /S /GoTo /D (section.2.2) >> +endobj +36 0 obj +(\376\377\000F\000u\000n\000c\000t\000i\000o\000n\000\040\000V\000e\000r\000s\000i\000o\000n\000\040\000N\000u\000m\000b\000e\000r\000s\000\040\000T\000a\000b\000l\000e\000s) +endobj +37 0 obj +<< /S /GoTo /D (chapter.3) >> +endobj +40 0 obj +(\376\377\000I\000n\000s\000t\000r\000u\000c\000t\000i\000o\000n\000\040\000S\000e\000t\000\040\000R\000e\000q\000u\000i\000r\000e\000m\000e\000n\000t\000s) +endobj +41 0 obj +<< /S /GoTo /D (chapter.4) >> +endobj +44 0 obj +(\376\377\000F\000i\000l\000e\000\040\000I\000n\000d\000e\000x) +endobj +45 0 obj +<< /S /GoTo /D (section.4.1) >> +endobj +48 0 obj +(\376\377\000F\000i\000l\000e\000\040\000L\000i\000s\000t) +endobj +49 0 obj +<< /S /GoTo /D (chapter.5) >> +endobj +52 0 obj +(\376\377\000F\000i\000l\000e\000\040\000D\000o\000c\000u\000m\000e\000n\000t\000a\000t\000i\000o\000n) +endobj +53 0 obj +<< /S /GoTo /D (section.5.1) >> +endobj +56 0 obj +(\376\377\000e\000r\000a\000s\000u\000r\000e\000\137\000c\000o\000d\000e\000.\000h\000\040\000F\000i\000l\000e\000\040\000R\000e\000f\000e\000r\000e\000n\000c\000e) +endobj +57 0 obj +<< /S /GoTo /D (subsection.5.1.1) >> +endobj +60 0 obj +(\376\377\000D\000e\000t\000a\000i\000l\000e\000d\000\040\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) +endobj +61 0 obj +<< /S /GoTo /D (subsection.5.1.2) >> +endobj +64 0 obj +(\376\377\000F\000u\000n\000c\000t\000i\000o\000n\000\040\000D\000o\000c\000u\000m\000e\000n\000t\000a\000t\000i\000o\000n) +endobj +65 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.1) >> +endobj +68 0 obj +(\376\377\000e\000c\000\137\000e\000n\000c\000o\000d\000e\000\137\000d\000a\000t\000a) +endobj +69 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.2) >> +endobj +72 0 obj +(\376\377\000e\000c\000\137\000e\000n\000c\000o\000d\000e\000\137\000d\000a\000t\000a\000\137\000b\000a\000s\000e) +endobj +73 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.3) >> +endobj +76 0 obj +(\376\377\000e\000c\000\137\000e\000n\000c\000o\000d\000e\000\137\000d\000a\000t\000a\000\137\000s\000s\000e) +endobj +77 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.4) >> +endobj +80 0 obj +(\376\377\000e\000c\000\137\000i\000n\000i\000t\000\137\000t\000a\000b\000l\000e\000s) +endobj +81 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.5) >> +endobj +84 0 obj +(\376\377\000g\000f\000\137\0002\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x) +endobj +85 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.6) >> +endobj +88 0 obj +(\376\377\000g\000f\000\137\0002\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x\0002) +endobj +89 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.7) >> +endobj +92 0 obj +(\376\377\000g\000f\000\137\0002\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000s\000s\000e) +endobj +93 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.8) >> +endobj +96 0 obj +(\376\377\000g\000f\000\137\0003\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x) +endobj +97 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.9) >> +endobj +100 0 obj +(\376\377\000g\000f\000\137\0003\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x\0002) +endobj +101 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.10) >> +endobj +104 0 obj +(\376\377\000g\000f\000\137\0003\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000s\000s\000e) +endobj +105 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.11) >> +endobj +108 0 obj +(\376\377\000g\000f\000\137\0004\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x) +endobj +109 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.12) >> +endobj +112 0 obj +(\376\377\000g\000f\000\137\0004\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x\0002) +endobj +113 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.13) >> +endobj +116 0 obj +(\376\377\000g\000f\000\137\0004\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000s\000s\000e) +endobj +117 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.14) >> +endobj +120 0 obj +(\376\377\000g\000f\000\137\0005\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x) +endobj +121 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.15) >> +endobj +124 0 obj +(\376\377\000g\000f\000\137\0005\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x\0002) +endobj +125 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.16) >> +endobj +128 0 obj +(\376\377\000g\000f\000\137\0005\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000s\000s\000e) +endobj +129 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.17) >> +endobj +132 0 obj +(\376\377\000g\000f\000\137\0006\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x) +endobj +133 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.18) >> +endobj +136 0 obj +(\376\377\000g\000f\000\137\0006\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x\0002) +endobj +137 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.19) >> +endobj +140 0 obj +(\376\377\000g\000f\000\137\0006\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000s\000s\000e) +endobj +141 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.20) >> +endobj +144 0 obj +(\376\377\000g\000f\000\137\000g\000e\000n\000\137\000c\000a\000u\000c\000h\000y\0001\000\137\000m\000a\000t\000r\000i\000x) +endobj +145 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.21) >> +endobj +148 0 obj +(\376\377\000g\000f\000\137\000g\000e\000n\000\137\000r\000s\000\137\000m\000a\000t\000r\000i\000x) +endobj +149 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.22) >> +endobj +152 0 obj +(\376\377\000g\000f\000\137\000i\000n\000v) +endobj +153 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.23) >> +endobj +156 0 obj +(\376\377\000g\000f\000\137\000i\000n\000v\000e\000r\000t\000\137\000m\000a\000t\000r\000i\000x) +endobj +157 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.24) >> +endobj +160 0 obj +(\376\377\000g\000f\000\137\000m\000u\000l) +endobj +161 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.25) >> +endobj +164 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d) +endobj +165 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.26) >> +endobj +168 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x) +endobj +169 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.27) >> +endobj +172 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000a\000v\000x\0002) +endobj +173 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.28) >> +endobj +176 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000b\000a\000s\000e) +endobj +177 0 obj +<< /S /GoTo /D (subsubsection.5.1.2.29) >> +endobj +180 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000d\000o\000t\000\137\000p\000r\000o\000d\000\137\000s\000s\000e) +endobj +181 0 obj +<< /S /GoTo /D (section.5.2) >> +endobj +184 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000m\000u\000l\000.\000h\000\040\000F\000i\000l\000e\000\040\000R\000e\000f\000e\000r\000e\000n\000c\000e) +endobj +185 0 obj +<< /S /GoTo /D (subsection.5.2.1) >> +endobj +188 0 obj +(\376\377\000D\000e\000t\000a\000i\000l\000e\000d\000\040\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) +endobj +189 0 obj +<< /S /GoTo /D (subsection.5.2.2) >> +endobj +192 0 obj +(\376\377\000F\000u\000n\000c\000t\000i\000o\000n\000\040\000D\000o\000c\000u\000m\000e\000n\000t\000a\000t\000i\000o\000n) +endobj +193 0 obj +<< /S /GoTo /D (subsubsection.5.2.2.1) >> +endobj +196 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000m\000u\000l) +endobj +197 0 obj +<< /S /GoTo /D (subsubsection.5.2.2.2) >> +endobj +200 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000m\000u\000l\000\137\000a\000v\000x) +endobj +201 0 obj +<< /S /GoTo /D (subsubsection.5.2.2.3) >> +endobj +204 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000m\000u\000l\000\137\000b\000a\000s\000e) +endobj +205 0 obj +<< /S /GoTo /D (subsubsection.5.2.2.4) >> +endobj +208 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000m\000u\000l\000\137\000i\000n\000i\000t) +endobj +209 0 obj +<< /S /GoTo /D (subsubsection.5.2.2.5) >> +endobj +212 0 obj +(\376\377\000g\000f\000\137\000v\000e\000c\000t\000\137\000m\000u\000l\000\137\000s\000s\000e) +endobj +213 0 obj +<< /S /GoTo /D (section.5.3) >> +endobj +216 0 obj +(\376\377\000t\000y\000p\000e\000s\000.\000h\000\040\000F\000i\000l\000e\000\040\000R\000e\000f\000e\000r\000e\000n\000c\000e) +endobj +217 0 obj +<< /S /GoTo /D (subsection.5.3.1) >> +endobj +220 0 obj +(\376\377\000D\000e\000t\000a\000i\000l\000e\000d\000\040\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) +endobj +221 0 obj +<< /S /GoTo /D [222 0 R /Fit ] >> +endobj +225 0 obj << +/Length 384 +/Filter /FlateDecode +>> +stream +xÚSËNĂ0¼ç+ö˜HØxưö±ˆ‡@@q)=„6E•̉Lâﱓ"Ô^P$¯2̀Œ7k/Àà*a*†•‚”CÜÀj—¼ưlÄơp:Ư!œ7ÉCxe…F…ÑR‡ª•µ>xÙưZ“èMFægyrz)8đ@Ö\A¾ĂA¡¢‘™¯a‘N붬²e~ƯQR!5DÉ©´ •ÎơÔ'®ôs$‰ZT@FÔNµÚ¾dYZÖmF¸±é¼m|‘dÀ{t²Z•Ué‹vÛÔ=r³}ö…ï8_Ñ0‰rg€pA•C¦Øñô +ưïôó ¹ ̣ØÇ¹{-‡`óæĂgœ¥«!úc¦Â1|†*}é÷̣:ÍuT'ZS41y¨|èùä~Ú?+7±¥/ë½ämQG裨úwrØ©9E=“‹|4VáËĐ/-â,– Ö¾să,|v¤HmC­`†®Ÿ5J%$RË̀øƠo‡<ödđf(;ovä>„Lß́;·— +endstream +endobj +222 0 obj << +/Type /Page +/Contents 225 0 R +/Resources 224 0 R +/MediaBox [0 0 612 792] +/Parent 229 0 R +>> endobj +223 0 obj << +/Type /XObject +/Subtype /Form +/FormType 1 +/PTEX.FileName (./intel_4c_100.pdf) +/PTEX.PageNumber 1 +/PTEX.InfoDict 230 0 R +/BBox [0 0 102 77] +/Resources << +/ProcSet [ /PDF ] +/ExtGState << +/R7 231 0 R +>>>> +/Length 232 0 R +/Filter /FlateDecode +>> +stream +xœmWI²5Ü×)t!½AĂ1à +`"h/€ÎO¦¦*÷wxQ?³%½9%ÿR̀!ñßú¾¾_¿üVĂ·/਽÷$ă‡¿.k-z+!÷‹yø~©•¨ÉCn]đC‹)µ Écî k¢4cY«áuåRcª`jÆÜ‚I*D&Mׂ„̃A" \oùÆ´«ÜŒ£Á=Ă-( ơó`¨‡'Îèf F©^!~øEúRral 7G§Ù½•)¸iÿ©µÅÑÂe«Øgb"íÆvte¦9ÛÙ7áT]  e Ük˜ØIÁ|vçàăƒơ¹ I4A!ÔƯĂ1Ù1§Î$±¼c6'X*÷:•µăè->|¤Êh[s°ú£û—Áf,Í„̉qVó`ØÀ$p–ĂΓ1;fPTåW†»J±'#e”ÚpéÀå1\è^˜}#H¸P£í1{›¹m(T—÷ÔWæÆÏx9%•­Â³™açí]QÖ)Û̀Ösê3‹xp÷qYßïT|d|Ÿ°UuÛØ;Po-·îVˆ!'đĂÆf¶ë„ăåG¼:]è¿CṢÊa*e‰wÈ2Ÿ?́n¦1FÆ6O è6¼+n»cGí+kEóÑË焱Mæx±N8^~Ä1cĂ­_f>8ˆ r0†|1ïÁTm‡!æÍK̀ËxÜÀ¥–Ọ¿¬ëе÷`óE&3ïÀbsÄc2æó~¿ẀGÏÆÿaEÂư›+ĐưRÀ¦?9‰Uû÷“ »„B¹ÙB„[º1Ë8å⑲«=öÊó9̣†}<ÿÁMc¾‹5Îë|áÆGBh‘ºNLiă ¢˜ĂËc'†¸̀̀*h ¾NAÏï¨xªsFr9ØzÍΛ̀4ô~0e¨d­{vm¼ÅhbLQ×ơ,®-­§@¯7¸₫Aa˜:zñÆ|Ï̀#6ă}®g¦?Zw¶3éUN0ßă¼G¸>Bàđ)±[uăÙ¼3{EÂïaß;̉Ñç +Ó fùØ@†ù¤’¾Ï›ÙN œ=Ü51ϘÜ+vèó?7U|}Iu;…oׯ×ÿ^§ +endstream +endobj +230 0 obj +<< +/Producer (GPL Ghostscript 8.71) +/CreationDate (D:20100929095736-07'00') +/ModDate (D:20100929095736-07'00') +/Creator (Adobe Illustrator\(R\) 8.0) +/Author (\(L.P Thebault\) \(L.P. Thebault Company\)) +/Title (\(intel_4c_100.eps\)) +>> +endobj +231 0 obj +<< +/Type /ExtGState +/OPM 1 +>> +endobj +232 0 obj +1336 +endobj +226 0 obj << +/D [222 0 R /XYZ 72 668.127 null] +>> endobj +224 0 obj << +/Font << /F32 227 0 R /F35 228 0 R >> +/XObject << /Im1 223 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +236 0 obj << +/Length 1840 +/Filter /FlateDecode +>> +stream +xÚ¥XQs£F ~ϯ`“À€í¾ù0‰¹:¶ ¸éMÛŒ71= >Àͤ¿¾̉JkÇw3>í®¤•¾Ơ'-^›Ú³fj÷W¦aö­₫@3₫Às<=w8´´ÔßPE°ëí₫˜\ỮhdŒ<ÛÓ’'Íí»†i4o82–£%íwƯêư™|:† +’«¯WLMÍ̉6˜ºÆÈjÙîê÷?MṃOl4Ô^¤ƠNs¼!Œ…_ưrtC±ÚÀ L cƒ/×´ 6ʰáün=Œ{–eéI¸˜÷nú̃¤4&Ó0¦ÙdᯂyÂz–.£cê‹k꿆“`̉Ư=̉ưÅ|ø'¯a2UI0{ăb²̣“Ø Ñ|Aă,ôƒy\Ó*øm1^D"|èYú ¦Î{32Ó¹œ…ÁvÚÎ@ÿø™Æ Nź].18JĐC2 ¢ëLÓvàü̉lÆsv#ÁÏà`+Ü5fW|%øđÀÛFáư4‰y÷Ñ +¦ôw2½ ‹W₫”D]®»n¥vÇ€™ÁHúd”ñÇpb*Pü8å*‹Á¯AÄNÆóÉöصƯ7ơIû³qøÓ’X°G§r@©äÆđẠN‹ÇeÆÓưæ#ưQ0S?¿'Ñ‘h˜ÇăY@1Ü­r½Â|ÉXw넱›¥ôg« `é÷xë¦Æ&ø}Ûzƒ8”é´ß¡E;…Ơwa2§¶‡>h½DÖÇT‘¡¿Y½\EËuX=‘?…½0ɸ8]]tpUD!À–ĂRyO›L«H‚ Å'ô\̉פñËϲ9h)³Œă±ạ̊B«¹æ¥V)y“MĂÈ,×°ú m5ŸQ–,ç}·“øØZSû8úcrêañQV³KÈ®I®Ôîç¬$¤ûˆ­æŸ“ ïç*äœ<Í'J|§Ä˜Ø÷i/¡êưînL ߆+̣qb£HEÙæiÎVˆ 5’9PÅàTƯ ë…t₫b5›ÎE/éÆ$C¦́ Ô#d1}1ˆû.ñ*c~Z¥®₫™AEZg¢N‰vüv™´ëÇ÷WÑÅËV`4́ë»ôUM¾Àf]àÊѳmZ>‹†TmEc³Y₫‡iÚYÚæUÉÚ´ÜĐd_W›CÖ’ƒh²:ßwíZe߃á¨m¾ØĐ/y»­lTVm ¸̣À4M₫\íÍÉ&µ(^)nU²ă­àpëF”/ªF8^f—¾•­¨óbc¬«WO8:Đ |i{¨…2©É$/›¶†óó‰A³KkÊé†Ö`¨ÿFObóvÑnĐÊÀÜ–bc| ™¢ ̀:;Ù9°ŒGAx: .²·ñ„ˆ³f›ɶin5rL’²¢"îñ$–¯ó"o_/ÔßË6m›Jôl—] ·Ï€\[ϪPôó¬mH£y™U»=”‘ô V§ü¼|&›§ºÚ±?u.ty¬L—+„Œ₫`‚OA"‰]^ŒàO9 ÛZiÚÙÖ Y´wƒd§²ű,1̉¤: +/’̀~ZäÿêÆ”†¬e£kµ[Âc2j ùbëÊăơ‡–ê¶W6·Û+ •yIḅ‹’M•v¢lI.»Å@P›*k…MÚ‹'qô¬¡PÔuU³́  +đ₫Âö)‹Á$mS’½lól{0=4B{{–V +€,«> endobj +233 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [135.019 309.334 337.859 318.456] +/Subtype/Link/A<> +>> endobj +234 0 obj << +/Font << /F46 237 0 R /F47 238 0 R /F48 239 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +275 0 obj << +/Length 824 +/Filter /FlateDecode +>> +stream +xÚíKo›@…÷ù³„t̃3,Û¼”*j¥Äê&ª†I‚C +8M₫}ÇfŒM° ÔQ"Vƶ†çœ{/Q ¸œAóúmrôåŒr€©+¤@`r ̀ƒ.L"pc§I¡’"·O¾ëu -/.®ÎËåëq̀«!p8r÷ÊÅÈv„Đº.̉,¸S¶ƒ´.ăid/æ†åAåÄ…ÈÓòÂÛ‰íJ¥ B®Ç˜Ý.÷Ơ[}¦ó¢ÜurçåƠIÎgú'Ơp£¿ă–k;LŸ÷°^¨ç½û=‘Àb§J ÔÁFŸO6b–Êbecfư}­đÄajđI2ưŸZĨuù<3±=N#su6OÂ"N“üµz„̉¼»Ôˆqư’jV*p¥₫̀ăLÍ6 +s%ecLúi»ơ6Q×£8Xëƒd©6n•‰RŸ_¶₫P—¹¼úäÇ|6Ơï[›Ù§éáªé5‚ĐÛG¹q¸ £EvY„tŒ+®:]WÊáÄ–Đ +¦ª¡$b°,ÉÓ=ÂIL8/’¼Èær\«b³ÚHZÛ‹)ÁDR‹µ¨¿¹]ƒøÁ´Ê‹$RÏ­¡û„®C_myçÑ–I9رꃦ+±‡OYĂ7«g”`éÙ6ÿÈ}üĂ*ÿ¨rÔóC=å¹÷fΫs¥nU¦’P5Êâ£3Ö&Ø%ÀX«Mđ—ø±¾Á‰*M;2ê«<̀âǦöºK{#đ:w¼˜¦á[ư™¯™cĂ¼̃¡[§ë'–#çVιR¢¦Á˱”,*Lèë +¢Ë‹EĐxđçô {Ä;X¸Fo¥êOƒ¼Q£ÅŸJơ¢H¶S̀›Ńsd?–tÍ2NâÂ/¶?ÏP6„‘đm¸¸\fà̃Ưú¸üjXøQZøYù¡ơôܘAÖ[¿Ë»€Ä ×JtÈI//V„[j§$d>́Q®!’1Đ5´H¯ È¡ºB=z:r'ÂÁơj,zZZA¤c k y?7â ‡èIÂÁZôƒH+ˆl ô> YC ´́‡·!l ½~ZTùè­ ëÿx:9ú^Vư× +endstream +endobj +274 0 obj << +/Type /Page +/Contents 275 0 R +/Resources 273 0 R +/MediaBox [0 0 612 792] +/Parent 229 0 R +/Annots [ 240 0 R 241 0 R 242 0 R 243 0 R 244 0 R 245 0 R 246 0 R 247 0 R 248 0 R 249 0 R 250 0 R 251 0 R 252 0 R 253 0 R 254 0 R 255 0 R 256 0 R 257 0 R 258 0 R 259 0 R 260 0 R 261 0 R 262 0 R 263 0 R 264 0 R 265 0 R 266 0 R 267 0 R 268 0 R 269 0 R 270 0 R 271 0 R ] +>> endobj +240 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 525.49 156.841 536.369] +/Subtype /Link +/A << /S /GoTo /D (chapter.1) >> +>> endobj +241 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 515.457 199.959 524.304] +/Subtype /Link +/A << /S /GoTo /D (section.1.1) >> +>> endobj +242 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 503.502 149.738 512.349] +/Subtype /Link +/A << /S /GoTo /D (section.1.2) >> +>> endobj +243 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 491.547 206.594 500.394] +/Subtype /Link +/A << /S /GoTo /D (section.1.3) >> +>> endobj +244 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 477.535 198.026 488.439] +/Subtype /Link +/A << /S /GoTo /D (section.1.4) >> +>> endobj +245 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 457.654 202.619 466.63] +/Subtype /Link +/A << /S /GoTo /D (chapter.2) >> +>> endobj +246 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 445.719 218.221 454.566] +/Subtype /Link +/A << /S /GoTo /D (section.2.1) >> +>> endobj +247 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 433.764 246.474 442.61] +/Subtype /Link +/A << /S /GoTo /D (section.2.2) >> +>> endobj +248 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 409.923 213.388 420.802] +/Subtype /Link +/A << /S /GoTo /D (chapter.3) >> +>> endobj +249 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 389.908 130.839 398.884] +/Subtype /Link +/A << /S /GoTo /D (chapter.4) >> +>> endobj +250 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 377.973 144.348 386.82] +/Subtype /Link +/A << /S /GoTo /D (section.4.1) >> +>> endobj +251 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 356.035 171.785 365.011] +/Subtype /Link +/A << /S /GoTo /D (chapter.5) >> +>> endobj +252 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 343.019 231.74 352.947] +/Subtype /Link +/A << /S /GoTo /D (section.5.1) >> +>> endobj +253 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.862 330.087 225.463 340.991] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.1.1) >> +>> endobj +254 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.862 320.19 242.081 329.036] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.1.2) >> +>> endobj +255 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 307.153 247.203 317.081] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.1) >> +>> endobj +256 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 295.198 269.887 305.126] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.2) >> +>> endobj +257 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 283.243 264.358 293.171] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.3) >> +>> endobj +258 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 271.288 238.923 281.216] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.4) >> +>> endobj +259 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 258.356 278.416 269.26] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.5) >> +>> endobj +260 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 246.401 283.397 257.305] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.6) >> +>> endobj +261 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 234.446 276.403 245.35] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.7) >> +>> endobj +262 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 222.491 278.416 233.395] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.8) >> +>> endobj +263 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 210.536 283.397 221.44] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.9) >> +>> endobj +264 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 198.581 276.403 209.485] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.10) >> +>> endobj +265 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 186.625 278.416 197.529] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.11) >> +>> endobj +266 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 174.67 283.397 185.574] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.12) >> +>> endobj +267 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 162.715 276.403 173.619] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.13) >> +>> endobj +268 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 150.76 278.416 161.664] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.14) >> +>> endobj +269 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 138.805 283.397 149.709] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.15) >> +>> endobj +270 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 126.85 276.403 137.754] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.16) >> +>> endobj +271 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 114.894 278.416 125.798] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.17) >> +>> endobj +273 0 obj << +/Font << /F46 237 0 R /F47 238 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +299 0 obj << +/Length 690 +/Filter /FlateDecode +>> +stream +xÚíÙMs¢0đ;Ÿ"G8˜Í“÷\wû2ÓCw¶åÖé8.̉–™.b·ưö°µ+•¾¨<…ŒÉÇøt‹:ơ& ˜B3%¹´­ZẾå†K§̃÷ĐûvbOl$•(¼A"© VÀQ8DW₫Ÿçáñyx\‡gy×›!.)æle×I²Ôéqèưñ‹Á|ªQ4̣®® ÚógE·F£¿å]#Û¡¶í=ºô~½­|}1’̣`1Iơß$V̀ ;4 ̣y¦¦tĐÓ‚ø·7}ù€đă(ïÇy’‡ưA@‰ÿđH—®zv†>z‚Ïj¸1Ÿüµ Pª|Jç[•µm!–Í*Âé4vôÛÎl¾¢½ưñ6NûÑ`Ư‚₫hgÉcƠ3ÑChgK†Ù´ÁN²‹)íḤ= t¤·K¡óQ¦»œÓ₫j/¡Óvè̀A/ÖÔ,oZ ¨î,ó†¾rÉ—/|G³ûª¦8ô´X€;ñÀYOˆèj³v¨²ơ%¶Vq™†.¨¾‰S­çtv’A y;H½̣÷ÀƯ (¥ˆƠ¯(³±fC%4ëÎ[4QöÇʈjUÚ ¤‚i¿øñ]Đ£öôIrÏ.â›8‹ÓÈáed_3ÁÙA)6À瀡x¥íá(ÎV}8g?§Q–Ḷdœ: ¬‘x^n¼"Ó²ú ó“Y•Äsóq4Åi>¨S;ƯṔÅb´Æ™.~ăt±Ëgîbă6öo®è²¦k›b¯a²«®jăØQ¸²׺ضíȱGDµ*Ṽ€¤I^E¥Jv|!hg+lk"2Ó]ÿ•L·̀Í́97çO“xÚ"-M¾|hÛV’Óí"4;D膯ÿ+Á̉¼–Eÿƒc1¡ +endstream +endobj +298 0 obj << +/Type /Page +/Contents 299 0 R +/Resources 297 0 R +/MediaBox [0 0 612 792] +/Parent 229 0 R +/Annots [ 272 0 R 276 0 R 277 0 R 278 0 R 279 0 R 280 0 R 281 0 R 282 0 R 283 0 R 284 0 R 285 0 R 286 0 R 287 0 R 288 0 R 289 0 R 290 0 R 291 0 R 292 0 R 293 0 R 294 0 R 295 0 R 296 0 R ] +>> endobj +272 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 655.011 283.397 665.915] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.18) >> +>> endobj +276 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 643.056 276.403 653.96] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.19) >> +>> endobj +277 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 631.101 280.368 642.005] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.20) >> +>> endobj +278 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 619.146 254.415 630.05] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.21) >> +>> endobj +279 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 607.191 209.196 618.095] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.22) >> +>> endobj +280 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 595.235 250.55 606.139] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.23) >> +>> endobj +281 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 583.28 212.364 594.184] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.24) >> +>> endobj +282 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 571.325 254.266 582.229] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.25) >> +>> endobj +283 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 559.37 273.435 570.274] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.26) >> +>> endobj +284 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 547.415 278.416 558.319] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.27) >> +>> endobj +285 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 535.46 276.951 546.364] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.28) >> +>> endobj +286 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 523.504 271.422 534.408] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.1.2.29) >> +>> endobj +287 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 511.549 229.399 522.453] +/Subtype /Link +/A << /S /GoTo /D (section.5.2) >> +>> endobj +288 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.862 499.594 225.463 510.498] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.2.1) >> +>> endobj +289 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.862 489.696 242.081 498.543] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.2.2) >> +>> endobj +290 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 475.684 233.793 486.588] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.2.2.1) >> +>> endobj +291 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 463.729 252.961 474.633] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.2.2.2) >> +>> endobj +292 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 451.773 256.478 462.677] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.2.2.3) >> +>> endobj +293 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 439.818 252.064 450.722] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.2.2.4) >> +>> endobj +294 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [140.742 427.863 250.949 438.767] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.5.2.2.5) >> +>> endobj +295 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.948 415.908 200.218 426.812] +/Subtype /Link +/A << /S /GoTo /D (section.5.3) >> +>> endobj +296 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.862 403.953 225.463 414.857] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.3.1) >> +>> endobj +297 0 obj << +/Font << /F46 237 0 R /F47 238 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +304 0 obj << +/Length 2318 +/Filter /FlateDecode +>> +stream +xÚ­XƯsܶ×_ÁG̃ÔGüÉṿ $’êŒǵHN;vÁ‘8cy%y–Ơ¿>»Ø<1‰œö‰Äb́绽/ôn.Bû ÂXÄ™q& _™æ¹đz˜₫©Û›‹oï/^_§¹'² iâƯo½$‰ƒ8Ï=™¦A"Sï¾̣>øßưựưưƠíje¹/V?Ưÿà­eiê­a­Œâ»»_%¡ÿîör‡₫Íñ¿}óííåí* ưáÊ‹«û‹ÿ\:ô„—EŒQ²Ü+÷~ +½ +è? °Eî=®½—Ⱦwwñ££q”â/~¬&…'’ Nd„ÀÖi‘€p '±Z‹0 ưËMwA¸(÷ïwơ@ßwåq¯ÛÑÈhy}d^2’¸eèFAKÚ‘ÇQáWv1ôPöơFóä¸Óô3tÛñq%B_ơL9ôƯC¯öûº} BƯz%ü~kØJfSmE?ƯA÷j¬»–‡[únm‰ÔÁnrvpSozƠ?­dê«ud₫>[€>ơ„0^5êd›L:êEYF̉#ù¡ï]Ñ`óD³æP$8B™awl+bAùT·U½Rÿs]UCs;­*ƯÓüÇ0ŒÍëÇâó+­¶ô³óˆ ,;văÓA qœ₫Ưq³^̉r˜,AˆÖmÙ+MgGxJº^Ü|8q7áL‡a‚¤nÄDÑ̀¤`^oa_;¢‘b@§·ô×ëF«AÓüç•H}XEÇ#ßöláÜíqù—Ä1hTfÔ¨H,üƯBX5V”é é—ªiŒƒ#khàx1Ú|ŒRIt3lêÎsû̃]¯Ø¢—e ÛÛFÊ[–Ñ >†ièî¤7w—ë·@́ö“j†ÿVQ¶¹TƯ¨M£Ï|Qví¨jë_ÅÇj4̃—Q·•f¾Aôc̀èxfxs6 t\Q[¬‰k̃}ÆhÎ!ÆáHá?¾^¦`1‘=7x67¸™?™fÏL Ó'›œ›·wL ï(ÜpßîØ—,Ă?@zq +7̀̃f ËB¥*éÍY₫áˆ]¤®^ÙÛ*’0?êb`0=œmÿ+…%±©Ÿ½•ö%aĂüÜÊ"£­æ˜8UĂNƯTi—ă7.¯Å*.~çïJ¬ô¥yÈËư¶3Øuz̀í#`î«M‡´å›ûlù +{;‡u(wPĐ5ørĂ¾;u«§·Îé,úÑ-h<=UPø•|b É’ỨM27ï2ü +Ç–Đh¸N“ÔĂ›jñƠŒfŸzi£¤€}”…ùiK±0¿Ñ“ÉÙk0¹á‹̀iû±P†‹v×kUÙG?¿ukhXé¼RØ-~K²Ư21–ỄIÜÂZÓØkÅ΢et̃+́c‘p à_U›tÛ>™×g $/ ÔDä¥à†Tﱋ±ŒÑĂˆ¯µƠX™܆ăÿ†×Nư¢®æç(ú4úÔ)4DÚƠ;PF̀–kĐK/C6æ„}’ ̉‚œÔ›IC=§ Lt耧ÉáʾöÑ èépÅóÀ™eôTK˜ƒ®'÷öÖ«h¼`V–ÚïƠưůC½„ +endstream +endobj +303 0 obj << +/Type /Page +/Contents 304 0 R +/Resources 302 0 R +/MediaBox [0 0 612 792] +/Parent 229 0 R +/Annots [ 300 0 R ] +>> endobj +300 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [176.401 286.23 248.649 297.188] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a590b5c35075aeea1243a9e4ef73a49d4) >> +>> endobj +305 0 obj << +/D [303 0 R /XYZ 72 686.127 null] +>> endobj +6 0 obj << +/D [303 0 R /XYZ 72 668.127 null] +>> endobj +307 0 obj << +/D [303 0 R /XYZ 74.491 618.224 null] +>> endobj +308 0 obj << +/D [303 0 R /XYZ 74.491 618.224 null] +>> endobj +10 0 obj << +/D [303 0 R /XYZ 72 618.224 null] +>> endobj +310 0 obj << +/D [303 0 R /XYZ 485.963 513.196 null] +>> endobj +14 0 obj << +/D [303 0 R /XYZ 72 495.348 null] +>> endobj +311 0 obj << +/D [303 0 R /XYZ 84.453 398.147 null] +>> endobj +18 0 obj << +/D [303 0 R /XYZ 72 382.356 null] +>> endobj +319 0 obj << +/D [303 0 R /XYZ 482.188 135.988 null] +>> endobj +302 0 obj << +/Font << /F58 306 0 R /F59 309 0 R /F47 238 0 R /F13 312 0 R /F11 313 0 R /F7 314 0 R /F8 315 0 R /F10 316 0 R /F1 317 0 R /F14 318 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +324 0 obj << +/Length 1196 +/Filter /FlateDecode +>> +stream +xÚ¥VÛnÜ6}ß¯Đ£ˆh’’(ÉElÀq6MêƯ¢.â ĐJ\¯]6$åËßwx³¥íÚEÑAĂË gΜw.á˜ÄY€Qœ±„ÁŸ¥yN˯,]_.Î׋“÷0U ‚Q¬·AF–(#I°®ƒ/!AÉ2¢)WORñÎÊ×üû؈%ÉC̃ñ^Éå×ơ‡₫_ ‹&˜0ç̉™Í‹ơâû‚€ˆb]LQAó ê_¾â †ùÚj‘fWörø·ÁjñÛÄ5jQÿ\điÅ £>ú4CI‘M¢'O§¹ ÿHè€e6ÁÍP3ḱª¯›%MĂû¦ËvÅ1 ·c_©fè¥̉°+Ÿ́ü®\R̃/Ir»t¯UKÑ £´[ÄØGªéܲ˜údÖåXí¬T:ëjÇíD×ôM7ṽ°>DHđ®[»°Z]LơIXsY‰fĂk»̃ô.x]#è\Bà„ "M}àR‰ÑÄé¸ÄƠ”HG-§^̣ —̃?RÏ”‚[¡m Aµ•7¼4\K–‚0|Àrí`†u^ójèÀhí üTZẶPZ–Ÿ¾•fÂPç륅+›[JÓƒ€¢hÄ;–¨SÙ™=KN +kSJï‚ÇÊ$M W½âí-M™̃đ¡íÅPq)a‡ÚƠb‰‡­Ú5WjÍƠØ@p›×"¹:‹)B ₫±ăÚY +L±¬ƠLm–$lËMËíÊÖ¸BL£M£Ü¤gÿ0‚ÙégD@öˆ€8¸C," LcƒáMÑÊî/Çœ³(6½&ÈQ +G\W±S”₫‘ —̉ă$‹h‚ +œÍ‰±¶Ê³êx3=u¦²#|uF>Ü'ö=„’4‘Úf#Jñd£äË,±ÉĐ2ï ²MèQÙ;á÷¾y´’T0© ìƠBU¶mÓß¹$)ñ«7o¹c›÷·ÀK?ë*Ê'!ÆYŒË|ÿß)µ?=9|+÷¼’(29ü®Yàøñq;Œà> âî„·Û“Çœư–›&°íë-z«)ƒ[Ç̃KkƄֆÓï u˜>sYï™´QywUóªEºVđá%`‚̣çÎæ$³³>÷ ¥¸oƒox®—(@@'äÉ7Å₫ÛZḉK_(…r¿oAĂàf¼9 ÚùØ´µI¯̃ư‹§“¼÷λă¼₫Kù¼'¤ëgR [.\‹œƯMÆ]wq´¼”N¼'ˆ"lơâye·o¹‡µwȬ—À$]ù¢0Qb±Sbp¡răLÉa·³Û¡ơ×]k´®]Ó÷ŒSuv¸•>Z]ƯؾÊÏ’»alâÆYÛB¹ ³† FE£öd·tĐ* Ü)Ñsx“º‰À/àAÙ;L?­ĐÁ›núp2¯¦IŸƒâ*˜Á¼ ¹µøë øÜÂ+wg2¬»nOCju?ëä:B÷Ú»}îŸoÄvÊÆRʱói%Ï­đ£¿ƒ7œ₫\¹<)¿³éưËBƒùÜÛ¹€₫™ªÜQ·Ó;¸$zó] +dF ´ÿñ]ú7´ ++ +endstream +endobj +323 0 obj << +/Type /Page +/Contents 324 0 R +/Resources 322 0 R +/MediaBox [0 0 612 792] +/Parent 229 0 R +/Annots [ 301 0 R 321 0 R 326 0 R ] +>> endobj +301 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 614.453 189.219 625.357] +/Subtype /Link +/A << /S /GoTo /D (requires) >> +>> endobj +321 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [444.171 496.134 540.996 507.038] +/Subtype/Link/A<> +>> endobj +326 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [71.004 484.802 336.01 495.083] +/Subtype/Link/A<> +>> endobj +325 0 obj << +/D [323 0 R /XYZ 72 686.127 null] +>> endobj +22 0 obj << +/D [323 0 R /XYZ 72 668.127 null] +>> endobj +322 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F47 238 0 R /F48 239 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +359 0 obj << +/Length 570 +/Filter /FlateDecode +>> +stream +xÚ…TK“@¾ó+æÆ™af€Ăâ–îjƠDÙä°µÔ©âa1æ×§qĐ8Ö®á̉úë₫úmAO9KL<êùˆ`Ï—\‚”"(ªàơ'¯æOÖ0²c êcFGÑqîa/s)P” 7ûñùË·h4w\æ6s̃£)r©„!Añ±d\_gÑäëLG₫Ícöú2»[£ÈúeQ NE>C̉ëÈh•[oï%àŸv|ĂNQ9â2™¡…ơưªi&:µçfBD9ö¸d]3Z„è1Ma긔b÷ŪQeÜu8±ÓʡԮ/ÎÙ>_ö¾ésƠÁ˜û(Ä¡d²«A´‡COê“"Qv«’}œA&Áu_¬Öf\¥ZÙèH‡ +;-´KUÏʼnE<¨f«µfÛçX—U7ZÏs·mƯ|ÚP£‡¢ß¢{̣̉A‹È ±C‰]jd¿µ‘¨júê +Z[Å*67vU¹J뺬ú₫̀®{ê]…¸ÏTî•«?iréÁÂÆÆ˜¯Æ\»opV{iLÂN Ṇ̃A‹Yº³4Lăz{<ùÆe•ÖÍàeŸ5j©¸:ƒ’f>jäû È<…Ư}<Ú‚ˆE\$Çe¥’Í]g€&íQ+Ăÿ¹|ëCe÷¤§²6­̣²h:̀ÍY»Æ Í j[ă‚̀ErÁw²;Ø; ë´Rç/é_®›ÿă_üg₫ °BS +endstream +endobj +358 0 obj << +/Type /Page +/Contents 359 0 R +/Resources 357 0 R +/MediaBox [0 0 612 792] +/Parent 364 0 R +>> endobj +360 0 obj << +/D [358 0 R /XYZ 72 686.127 null] +>> endobj +26 0 obj << +/D [358 0 R /XYZ 72 668.127 null] +>> endobj +361 0 obj << +/D [358 0 R /XYZ 74.491 618.224 null] +>> endobj +362 0 obj << +/D [358 0 R /XYZ 76.981 618.224 null] +>> endobj +30 0 obj << +/D [358 0 R /XYZ 72 618.224 null] +>> endobj +363 0 obj << +/D [358 0 R /XYZ 196.601 431.811 null] +>> endobj +34 0 obj << +/D [358 0 R /XYZ 72 416.02 null] +>> endobj +357 0 obj << +/Font << /F58 306 0 R /F59 309 0 R /F47 238 0 R /F48 239 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +367 0 obj << +/Length 1462 +/Filter /FlateDecode +>> +stream +xÚµ™MoÛF†ïú W~ưz÷‘Ï'ÛM¦ơƠÇÛƯÓæĂöƯB‘Ưû ‹.Úµ«öËvơ÷ÊđÓ̀A¶‡L©»¾[½ÿ€Ư _×?.§îŸư]w ‰·Ư«ßVX•q_Ÿ;ăÀº@/•đB6T‚ߺ*%.…ë+±1fư4\âđẠ̈+H=†.X1¿„á­{ñ•h‹áÉj ¿AŒuZ₫̉¸Ç/íUjo3$43̉×5§9¥ù57ÈZEúCxÿáï ^y…Ạ̊´(¥ù†±1‚¡ÜˆKBˆ&ŒoÍŒ¬_êE +€JMÇơK“…½3}̣Ï’̣ü­<Ënå› #mÍLZ¾Ô‹ø”{g& {gúä5/å¸À@̃™ṾßÑKÛ3Ó©E +€JM aÿLŸ¼Äá vh¬3@¡•œƒä¥̀ixÔ<…¤0¹Ñç®ép8†ăÊ`±•},AÊ^ZĂœÆG-RàSj }̣‡9\d"°"„́&ô?cµHP¡i3}À@è÷7·áƒ r̉ÿŒR«•¢BÂÄGŸ¼&Äá}¥ç¢lÁ¹F¢í„h^äy@¥¦°­Ï]ñéĂÉÍw%.5r%Ư„.h Z¥¨5º©“ׄ8œ̉d½Ô z†AÛk=ơŒÿ́ Ä8 +endstream +endobj +366 0 obj << +/Type /Page +/Contents 367 0 R +/Resources 365 0 R +/MediaBox [0 0 612 792] +/Parent 364 0 R +/Annots [ 328 0 R 329 0 R 330 0 R 331 0 R 332 0 R 333 0 R 334 0 R 335 0 R 336 0 R 337 0 R 338 0 R 339 0 R 340 0 R 341 0 R 342 0 R 343 0 R 344 0 R 345 0 R 346 0 R 347 0 R 348 0 R 349 0 R 350 0 R 351 0 R 352 0 R 353 0 R 354 0 R 355 0 R 356 0 R ] +>> endobj +328 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 615.236 146.739 629.184] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a15d42d058c64dec106d9e3e9fc2e1136) >> +>> endobj +329 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 603.281 147.855 617.229] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a84eb9ca31c934f05a8e3fa7a02fa71dc) >> +>> endobj +330 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 591.326 148.752 605.274] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a7a1f65b032f03494dbc68411f5614bb1) >> +>> endobj +331 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 579.371 167.212 593.318] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a1ff835062a19d6516f2d59d9c37ddb48) >> +>> endobj +332 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 567.416 169.225 581.363] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a4f880c4b9fe6700e040b9f4ef4e45918) >> +>> endobj +333 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 555.46 172.194 569.408] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a17c6ccf6470796b756841e160dc8697c) >> +>> endobj +334 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 543.505 172.194 557.453] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_abb7a991b4c0fb9ced373680ef36bae08) >> +>> endobj +335 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 531.55 179.188 545.498] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a26c2200ad3bf04b1c858eb239b7ff940) >> +>> endobj +336 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 519.595 174.206 533.543] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ae1e4c9eb9a26a3a7852166d54d2a27f8) >> +>> endobj +337 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 507.64 172.194 521.587] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_af88a7da05f46e1a0fe17d032a2cf78bf) >> +>> endobj +338 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 495.685 172.194 509.632] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a06a563b718c6269c8df0fe7647e5bb49) >> +>> endobj +339 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 483.729 172.194 497.677] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a12f59be6d348fea6ad2464a20af22fd3) >> +>> endobj +340 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 471.774 134.714 485.722] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a22b53cd4103da9ed88c351e7045ff313) >> +>> endobj +341 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 459.819 160.149 473.767] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a21d5e25b4ac64062996149fea71aede8) >> +>> endobj +342 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 447.864 142.993 461.812] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a590b5c35075aeea1243a9e4ef73a49d4) >> +>> endobj +343 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 435.909 129.584 449.856] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_aa7a737b69a0a77dc29aa28d0f17421a1) >> +>> endobj +344 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 423.954 165.678 437.901] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_aa486278c409735df8001096ac2b487dd) >> +>> endobj +345 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 411.998 152.268 425.946] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a8f3e57729c3382514325612c54e20eaa) >> +>> endobj +346 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 400.043 172.742 413.991] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a17799d49d9b83861322ebf314a55f77f) >> +>> endobj +347 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 388.088 150.057 402.036] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a6ce05684e168d73773847a3c2c13c175) >> +>> endobj +348 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 376.133 174.206 390.081] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a1fb1d6d463ac00ae196501c75d2036d2) >> +>> endobj +349 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 364.178 174.206 378.125] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_aacd489f45babdbfe6a41f1bac2885ab6) >> +>> endobj +350 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 352.223 174.206 366.17] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ad0eca329291d751df6ffb3aa3eb83610) >> +>> endobj +351 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 340.267 174.206 354.215] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_afeefb3612c92a0bc87182f6e11030b11) >> +>> endobj +352 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 328.312 174.206 342.26] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ac64153e1aef3cdc4b69d375ec762fa33) >> +>> endobj +353 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 316.357 179.188 330.305] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a2688b38c18e93c95c525c0d5bf9e221a) >> +>> endobj +354 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 304.402 179.188 318.35] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a2fb7662ba4e1df4bb72659c57efeaad6) >> +>> endobj +355 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 292.447 179.188 306.394] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_af88c501e0c5138ec9c88f58c182945e8) >> +>> endobj +356 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [77.38 280.492 179.188 294.439] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ac6468d7eb3c28116439abb4a7c5eca05) >> +>> endobj +368 0 obj << +/D [366 0 R /XYZ 72 686.127 null] +>> endobj +365 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F47 238 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +433 0 obj << +/Length 621 +/Filter /FlateDecode +>> +stream +xÚí–[o›0€ßù~iq}9¾=víRiÙØ4)­Ph-%[`í~₫ Œ´IÛ)tQ”&<Çs|üÁG#‚ÎRGL8å +̀•i£ZS4·—Ÿ¹Ô?s̃†ÎÑ©Đˆ*̀¨^#¹ÖH +A +Æhà¼;₫ú}¯Ă”v¹w£#BQÇ.– ªÄn/û÷ÓIØưĐ«~X ú₫…Gíµnßï÷ ¸‘ă‡ÎO‡Ú&¢H1$y±QF7Îà ØÎŸ{7Ư•Y7¤¶qçâ₫±¸OÑv9¨›… 6’É¢G E’¬l,wŒ¢$Íâ$‡ù0ʲ¤Ü]}[4è0AÜK"È$ͽ̣Ç4IßT£ÅÔ÷Ơ‰ù̀c½Ë₫ÎÿJ³É8Mâê×èÛp^T9:¥đ`{Œ6Ü‚ªvvI¯²–°9Ơ9ăëüë´Q-°Rêagê#^çgÓ¤2¸dƠ¨ˆ¥0IÇö¨é2‚P†5hûÈ1Líú2;|ÀË™Ÿr n£Á‚B}j»ơ¨°đó(åÑù,†#îíï—࿽Ÿ[4L„^ƒ4ưỎëBX> endobj +398 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 597.638 156.263 608.542] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a21d5e25b4ac64062996149fea71aede8) >> +>> endobj +400 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 565.977 170.321 576.881] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_aacd489f45babdbfe6a41f1bac2885ab6) >> +>> endobj +402 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 534.316 175.302 545.22] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a2688b38c18e93c95c525c0d5bf9e221a) >> +>> endobj +404 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 502.655 168.308 513.559] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a17c6ccf6470796b756841e160dc8697c) >> +>> endobj +406 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 470.994 170.321 481.898] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ad0eca329291d751df6ffb3aa3eb83610) >> +>> endobj +408 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 439.332 175.302 450.236] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a2fb7662ba4e1df4bb72659c57efeaad6) >> +>> endobj +410 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 407.671 168.308 418.575] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_abb7a991b4c0fb9ced373680ef36bae08) >> +>> endobj +412 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 376.01 170.321 386.914] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ae1e4c9eb9a26a3a7852166d54d2a27f8) >> +>> endobj +414 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 344.349 175.302 355.253] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a26c2200ad3bf04b1c858eb239b7ff940) >> +>> endobj +416 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 312.688 168.308 323.592] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_af88a7da05f46e1a0fe17d032a2cf78bf) >> +>> endobj +418 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 281.027 170.321 291.931] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_afeefb3612c92a0bc87182f6e11030b11) >> +>> endobj +420 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 249.366 175.302 260.27] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_af88c501e0c5138ec9c88f58c182945e8) >> +>> endobj +422 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 217.705 168.308 228.608] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a06a563b718c6269c8df0fe7647e5bb49) >> +>> endobj +424 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 186.043 170.321 196.947] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ac64153e1aef3cdc4b69d375ec762fa33) >> +>> endobj +426 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 154.382 175.302 165.286] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ac6468d7eb3c28116439abb4a7c5eca05) >> +>> endobj +428 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 122.721 168.308 133.625] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a12f59be6d348fea6ad2464a20af22fd3) >> +>> endobj +434 0 obj << +/D [432 0 R /XYZ 72 686.127 null] +>> endobj +38 0 obj << +/D [432 0 R /XYZ 72 668.127 null] +>> endobj +327 0 obj << +/D [432 0 R /XYZ 74.491 618.224 null] +>> endobj +435 0 obj << +/D [432 0 R /XYZ 72 607.546 null] +>> endobj +436 0 obj << +/D [432 0 R /XYZ 72 575.885 null] +>> endobj +437 0 obj << +/D [432 0 R /XYZ 72 544.224 null] +>> endobj +438 0 obj << +/D [432 0 R /XYZ 72 512.562 null] +>> endobj +439 0 obj << +/D [432 0 R /XYZ 72 480.901 null] +>> endobj +440 0 obj << +/D [432 0 R /XYZ 72 449.24 null] +>> endobj +441 0 obj << +/D [432 0 R /XYZ 72 417.579 null] +>> endobj +442 0 obj << +/D [432 0 R /XYZ 72 385.918 null] +>> endobj +443 0 obj << +/D [432 0 R /XYZ 72 354.257 null] +>> endobj +444 0 obj << +/D [432 0 R /XYZ 72 322.596 null] +>> endobj +445 0 obj << +/D [432 0 R /XYZ 72 290.934 null] +>> endobj +446 0 obj << +/D [432 0 R /XYZ 72 259.273 null] +>> endobj +447 0 obj << +/D [432 0 R /XYZ 72 227.612 null] +>> endobj +448 0 obj << +/D [432 0 R /XYZ 72 195.951 null] +>> endobj +449 0 obj << +/D [432 0 R /XYZ 72 164.29 null] +>> endobj +450 0 obj << +/D [432 0 R /XYZ 72 132.629 null] +>> endobj +431 0 obj << +/Font << /F58 306 0 R /F47 238 0 R /F14 318 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +461 0 obj << +/Length 489 +/Filter /FlateDecode +>> +stream +xÚí–MoÚ@†ï₫s)Lf¿w©”DʭŪ*‘¥ØP$>́Đ₫üí‚ë&RN9ízưîÎëyvÖK0‚눔P•³Úrk÷VüzÇ«/<ë¨ÙŸâèü‡+-Äc0Ê ‰ÖtBCœÀ c»wñÍ6Ôe=F‚»œd©Á =ŒæÑà áñ›"Xđđ³TÍA[Ïí úÑçÚñ¶-Ö)|–­+÷—+§Q́•±•©Éx¸î +ÓIGù0YæĂ‡Ơ2̃w%uÖ¿~aĐ“†:·dhºÈ»åĂ,]œU½íĐº{ZdÓÉ"Mª§ÑûU±àùç£ö$E@rœÖÊÎ-‘ªT çƒÍdœŸem‚pj]3Æ8EOmtÙjÔ&g׆pÀ‡È&I³œó)yî)ïX̃Ï.µ_¿5dÏy—zm·¼é”ÚÏW°ÔHÆŸ°?°|;àVût̃ ‘È=Ă+ÛñƠ¯đͲô4µËƠê´uåǾj¢í÷/5£‹w₫4{Ă¹|Đ× «8¶mÍñOŒuáj9M^XY+ôdÚœ‰5¸W–U-Éw&µå_¡>̣¨Ơ/ÓjW…’¨µú_¤Zm÷%%÷’̉¨´Ü[Zÿ^«ñEM·¼Vưyś +endstream +endobj +460 0 obj << +/Type /Page +/Contents 461 0 R +/Resources 459 0 R +/MediaBox [0 0 612 792] +/Parent 364 0 R +/Annots [ 430 0 R 452 0 R 454 0 R 456 0 R 458 0 R ] +>> endobj +430 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 655.203 165.34 666.107] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a4f880c4b9fe6700e040b9f4ef4e45918) >> +>> endobj +452 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 623.323 170.321 634.227] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a1fb1d6d463ac00ae196501c75d2036d2) >> +>> endobj +454 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 591.442 163.327 602.346] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a1ff835062a19d6516f2d59d9c37ddb48) >> +>> endobj +456 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 559.562 144.866 570.466] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a7a1f65b032f03494dbc68411f5614bb1) >> +>> endobj +458 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.494 527.681 142.854 538.585] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a15d42d058c64dec106d9e3e9fc2e1136) >> +>> endobj +462 0 obj << +/D [460 0 R /XYZ 72 686.127 null] +>> endobj +463 0 obj << +/D [460 0 R /XYZ 72 665.111 null] +>> endobj +464 0 obj << +/D [460 0 R /XYZ 72 633.23 null] +>> endobj +465 0 obj << +/D [460 0 R /XYZ 72 601.35 null] +>> endobj +466 0 obj << +/D [460 0 R /XYZ 72 569.469 null] +>> endobj +467 0 obj << +/D [460 0 R /XYZ 72 537.589 null] +>> endobj +459 0 obj << +/Font << /F46 237 0 R /F47 238 0 R /F14 318 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +476 0 obj << +/Length 583 +/Filter /FlateDecode +>> +stream +xÚÅU]oÓ0}ϯ¸ÉC]Çæ XÓuŒ> u£ê§‹H“’¤Lû÷Øu¢RA+*1ñt®íûq|®o‚a ¦aFX ±XriQ +¥4öøÄÑƯ4x7ƉP@bD‰à0Ïs†˜R …@\ +˜g°ß_¿ư8ŸÜE#«Gó HÙÀ‘””{¯dv;ñ.³W“/Î-˜̀ƒï±1ˆ)Hæh(H7ÁâCf÷o3­àyïµ.•Å>Ÿ~¹Ît0ĐÖ@8b\RGÛ¦[.ÔsáˆD#‚1“¢4–UámÑv{RCÖqÂcĐHK*] –<̉Lúצq‡Eëqå¡työV÷eé¬NwSu&óë{Œiiúđç¢{̣ÖcS˜>43mÚÛ®¨«öÍ»:í\#÷†m›»8‰Ù±ú¦Yµ»Æ,Ó:3èé(°¸ïAZô=Y–MË>íïÙƠó]•î ùe»Ûnë¦+ªµ_÷•ü•뷫ƒ½ª²áz~Sk¢h$lC₫5p­Oy~“o1" +óPû¤́£?é¸Î—?""B“vËÍ®<+½¼Tú¼n¼1”Ö÷XàDzN¿Yƒø-[¼+¶e‘®\‚₫åö8M\uÔÆ a ‘™rrÜ×€!Izz_½ÛÑl¤¤´¼”¯,_¯±gàtcf!w–j{5,[Û½lMû7³teÜ WĂ ·}ÿ«&Æ>æ~ŸĐjFÔĐ́5á̀ ^Ü?̉ó“iÿ)?c˜Œµ +endstream +endobj +475 0 obj << +/Type /Page +/Contents 476 0 R +/Resources 474 0 R +/MediaBox [0 0 612 792] +/Parent 364 0 R +/Annots [ 468 0 R 469 0 R 470 0 R 471 0 R 472 0 R 473 0 R ] +>> endobj +468 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.177 546.885 147.194 556.813] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h) >> +>> endobj +469 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [534.022 536.011 540.996 544.858] +/Subtype /Link +/A << /S /GoTo /D (section.5.1) >> +>> endobj +470 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.177 521.998 144.853 532.902] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h) >> +>> endobj +471 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [529.041 512.101 540.996 520.947] +/Subtype /Link +/A << /S /GoTo /D (section.5.2) >> +>> endobj +472 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [85.177 498.088 115.672 508.992] +/Subtype /Link +/A << /S /GoTo /D (types_8h) >> +>> endobj +473 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [529.041 488.19 540.996 497.037] +/Subtype /Link +/A << /S /GoTo /D (section.5.3) >> +>> endobj +477 0 obj << +/D [475 0 R /XYZ 72 686.127 null] +>> endobj +42 0 obj << +/D [475 0 R /XYZ 72 668.127 null] +>> endobj +46 0 obj << +/D [475 0 R /XYZ 72 618.224 null] +>> endobj +474 0 obj << +/Font << /F58 306 0 R /F59 309 0 R /F47 238 0 R /F13 312 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +495 0 obj << +/Length 1402 +/Filter /FlateDecode +>> +stream +xÚí™KsÛ6ÇïúœôBÎT̃cÚi2M̉ºê)I5´DÙ+¤JRr§Ÿ¾ ”(ÉtH¹Í«¹„ÔⱋÅ.\8x6ÂÍaF˜ +0bJr O)´&AÍMÏF?LFÏ…ˆB”Lç 1­)âR“yđ&|úÓ“_&gј*èƯäE06Úy0†±’r×ïüùÏg®Ó¯Ÿ₫₫̣́Ơ$"‡Oê'Ï_¿²CGg“ÑŸ#a〒ÙĐt0{?zós°¿°ÑÜÖ½̃\jx.ƒßF¿¶–L…}µf)& 1.©] +L- ‡è¨‹N  Æ8L¸\Éq4„K„Á—§)¹7$Ä0ßu‡{"́²b˜åó‚!º†DQ§ËĽ]$‹HAhI6s‘5 }|ÎU`‘TÚyÇJ×óB‘ảÍû<«’bÆ3;ŸÀa•»çbͪ4ÏJ÷³\¯VyQ¥Ù•ûƯä¢₫á«ÍÙî=ÎæîeX#²ÑAPº̃á»4›-×v¼„t?ºZL7ɬ¾_/Ñơ#·¸½Ưs¹#ÈAưtŒ#¢•çj»„v^:̣C$âLCz(’ Ào){cƒ7c‘m"3Oç¾Í"`OLưrQ÷ªs1›¦YZM«ør™”‡óØo±ÀiV¹,Ư|ï[C‘GT„·¥·¯³2½ÊŸÓÙu\¸„̃ZÅ +ilÀ‰[Æ̀§½½VŒ&MŸxÈüR!Ơé¯Ơ岄•’]P,Đ0TÖ:2¦̣xáHÎLÓ*—éß £.£Ó¼đ/qéwVDD„–ψÁÑpƧ}µăĐ½§ÈâÁá +Ôчb +k1qMçqOË29œ‹îP‰Hhá°¿—Iûƨq¼Ø‰n -€¬}·Áv‚.€†$†ïđNX— Â[ËG‡Ÿú­égÓ3ĢI8¬é$b˜7Ø»¾Ürø’}hŸ%Yâ@¬[OÏójº*̣ù]µ¥-ơ¶Ú”±pkÚ́l­¢º(†Ë¡9©¢èíBĂ-Mñ¡2í îíDq„̣½î˜cŒ¸`́ÛƯ ̃ 2J¹ ‹A÷뾸^{³Âu\8~»^ºÈó8«¶G!÷Ơ³WăùzVƯ)‡»À¿'½”¨»!íĐÍ_G Âmx* öP̉T0mv¶ÖCC'¨aÊNCµ¯Í‘æê4½ííD1uưŸ¢j(ù2Q}x ̀îG••Ä0`W³†U®y¸5mv¶VaʺY•úôê·¯(?4“§Éjo'PH$Íqiđ¡³7Yƒˆ¡ÿWi¥ỘJ{´]­®ê¦ ;]U{NÚ­«Àªæ'±ÚÛ èª1äÄ ¯ĐUCèàëà0m5HØ2€J¤ù Xu†Û´ºö~»ơ#Î×Ơj]•Ÿ@{iï:á›ö¤½ăZö•0ư`}æ˜ÜÏôqA["m‡{€¹ÿïkj fí+ºxÏ_~§AƯ׉Áh¿,í_ûööL+Ä¿1ưIuÚ×́[Íñ9Ög“Ñ? ËÔm +endstream +endobj +494 0 obj << +/Type /Page +/Contents 495 0 R +/Resources 493 0 R +/MediaBox [0 0 612 792] +/Parent 364 0 R +/Annots [ 481 0 R 482 0 R 483 0 R 484 0 R 485 0 R 486 0 R 487 0 R 488 0 R 489 0 R 490 0 R 491 0 R ] +>> endobj +481 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.915 489.057 173.249 499.961] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a22b53cd4103da9ed88c351e7045ff313) >> +>> endobj +482 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [116.545 461.161 199.314 472.065] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a21d5e25b4ac64062996149fea71aede8) >> +>> endobj +483 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.601 421.311 183.215 432.215] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a590b5c35075aeea1243a9e4ef73a49d4) >> +>> endobj +484 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [116.945 381.46 205.243 392.364] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_aa486278c409735df8001096ac2b487dd) >> +>> endobj +485 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.7 341.609 205.532 352.513] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a1ff835062a19d6516f2d59d9c37ddb48) >> +>> endobj +486 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.583 313.714 207.428 324.618] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a4f880c4b9fe6700e040b9f4ef4e45918) >> +>> endobj +487 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.78 285.819 214.606 296.723] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a1fb1d6d463ac00ae196501c75d2036d2) >> +>> endobj +488 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.634 245.968 210.448 256.872] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a17c6ccf6470796b756841e160dc8697c) >> +>> endobj +489 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.78 206.118 214.606 217.022] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_aacd489f45babdbfe6a41f1bac2885ab6) >> +>> endobj +490 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.424 166.267 219.232 177.171] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a2688b38c18e93c95c525c0d5bf9e221a) >> +>> endobj +491 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.634 126.416 210.448 137.32] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_abb7a991b4c0fb9ced373680ef36bae08) >> +>> endobj +496 0 obj << +/D [494 0 R /XYZ 72 686.127 null] +>> endobj +50 0 obj << +/D [494 0 R /XYZ 72 668.127 null] +>> endobj +478 0 obj << +/D [494 0 R /XYZ 74.491 618.224 null] +>> endobj +54 0 obj << +/D [494 0 R /XYZ 72 618.224 null] +>> endobj +497 0 obj << +/D [494 0 R /XYZ 72 508.03 null] +>> endobj +493 0 obj << +/Font << /F58 306 0 R /F59 309 0 R /F47 238 0 R /F48 239 0 R /F14 318 0 R /F73 498 0 R /F43 499 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +517 0 obj << +/Length 994 +/Filter /FlateDecode +>> +stream +xÚíKoÛ8Çï₫> endobj +492 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.78 642.06 214.606 652.964] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ad0eca329291d751df6ffb3aa3eb83610) >> +>> endobj +500 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.424 602.209 219.232 613.113] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a2fb7662ba4e1df4bb72659c57efeaad6) >> +>> endobj +501 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.634 562.359 210.448 573.263] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_af88a7da05f46e1a0fe17d032a2cf78bf) >> +>> endobj +502 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.78 522.508 214.606 533.412] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ae1e4c9eb9a26a3a7852166d54d2a27f8) >> +>> endobj +503 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.424 482.658 219.232 493.562] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a26c2200ad3bf04b1c858eb239b7ff940) >> +>> endobj +504 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.634 442.807 210.448 453.711] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a06a563b718c6269c8df0fe7647e5bb49) >> +>> endobj +505 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.78 402.957 214.606 413.86] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_afeefb3612c92a0bc87182f6e11030b11) >> +>> endobj +506 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.424 363.106 219.232 374.01] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_af88c501e0c5138ec9c88f58c182945e8) >> +>> endobj +507 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.634 323.255 210.448 334.159] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a12f59be6d348fea6ad2464a20af22fd3) >> +>> endobj +508 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.78 283.405 214.606 294.309] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ac64153e1aef3cdc4b69d375ec762fa33) >> +>> endobj +509 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [117.424 243.554 219.232 254.458] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ac6468d7eb3c28116439abb4a7c5eca05) >> +>> endobj +510 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.378 203.704 210.74 214.608] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a17799d49d9b83861322ebf314a55f77f) >> +>> endobj +511 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.915 175.808 188.592 186.712] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a6ce05684e168d73773847a3c2c13c175) >> +>> endobj +512 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [154.012 147.913 184.786 158.817] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ac73ea8358bc3155c7f3a6c078a7d6d35) >> +>> endobj +513 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [154.012 120.018 181.618 130.921] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a484460566a8c888fda3d769324461345) >> +>> endobj +518 0 obj << +/D [516 0 R /XYZ 72 686.127 null] +>> endobj +515 0 obj << +/Font << /F46 237 0 R /F73 498 0 R /F43 499 0 R /F47 238 0 R /F14 318 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +527 0 obj << +/Length 2526 +/Filter /FlateDecode +>> +stream +xÚÍZK“Û6¾Ï¯à‘ª<<ÚY{jSNUÖƯ=8ÉEA3,S¤ÂG&“_¿ƯHJĨÚ=~£ûkH4xhp{C L$%"‰£±T |>̣éăíÍÛ»›ïßĂTJ̉˜ÇÁƯ&Hx«”$, +îÖÁçP¶XrICƯdmß,˜ +ơ}^¯5y´óï‹RÛÑG½ÑvA•ëůw?̃Đ«„ >/‹¥ ơ¨½»»ùư†Á̀Ê+IÊUoo>ÿJƒ5̀ÿˆôR<™UÛ <ËàÓÍ?öB<-(°E¡-c„ª",vöøTTƒÂºÔ[]uöåöư/TR’‚IE2%‰5iD8• ¦–Èov•ÇL’(Iƒåd•‚ÎøEµˆhø—†­^0Ï&À2™xqÉ('ÆKÆI*™%ø ç̉Û–è.8 ëbí¾¡YÑ3f`ư€2uFq(`êTa Ên‹¿ôúP^Pơ´Æ´zÚ,"e‹ÏQ~|AñZ/¦2|ç4Ày£¬vŒÉcB¡̉Mư€a"ˆ!`„BÓs™¡8„L̀¤2‡$x=ÁW9x`$̃fƒ8«gË8Ïʼ/3ë!ü`lh„¯;;Ø5ơºÏ;_ \†[̣X¥¾áÚçíª.MZä&¡¬;í^íá'TN!đƠ… +˜ˆƒç›ºu<3ûhug6“óp…E±ß,¸ ›ÅÂà‰]&ÿĂ–}₫‡ (₫k0̀Ê~ĐƠå}î"sv¯ăep_kƯm¹ÑØ7° [óÆVSt§ÉïqØ=ï´22Ầä %áxdøÏÖÅĨ,…Yi·§ắètœƯềhd™¹Y…µäÙ®hơï½ơ³ÊÂ÷mæX9ù]¥„™¢ÊË̃TÈ™ó¸?}’ÙÓ‡Cpcf*̀Ö•j² Ñ‘0µ6̀¸-fQøS_vÅ®tt]‰lmÎïøǺOÄà9œÅ\WVṇáê˜[Ä–±#Úw»¾›Ó̉ +wµ È8¶'u¥í`—µ&ä¤ +ß‚êṿö½}n­6ÏöÍ3 Öê₫G±v˧‰^ó̀1Y¹ïíN»ưÎ}q$]̉µqdßxóñöƯưƯ›·̃}r|;ụ̂Ä¡'QÇ?wºjµ­¶z[7{µ¦É+}Yí¸«vï–®ÚƠyYö¢̃Í08Zư ư±® ®^r!Àm†¬×‚2Í$8}¨J¢S}(`=•¨é8=I˜P€e¹!'ƒ-méyÉ7NHâ_Ë Xœ2Ÿï:ë2«5&̣Å2“‰™^€ÔI*Vj@f‘ÏÉ Rœ#`XĐxXóe– #‘RçiLg„ùÔÎQä s<ÂĐ rÍóE΃W¼ˆâ—àƠ$9ä°æaÓ­²”óR¤„îîåR‘LÂƠ¸];+„€bÄÏb) KäAû0{àï:¦—̉Fç{åÀưaG•àÙ‰ü³lúÀ±º´·íïµôĐU¬µköjơWeiư$fÍg†M_¹ÙÊÆ®)Fn“BCÆ™˜=ªÍØf•I`”lx”…ém`d8³­ûÆT_·s ³V6”„§®Îwn‘­%H¡±ÏíX÷;}6ϬíËIÖZP0̣+ðÄÔ‹½ĐcŸ4!yFR˜æïBØk SĐ9¡̀¯<³( JYøïG´²÷à^0Óëá£í‹.[¤ë 0ÄiØÂÛ ˜èL÷‚K )sƒ°$‡‘-M8ÿT”¥%¶ƒÎ¥n¶vÚ¢q˜µÍLë:_»Ñ‰8o×ByœỪ•̃Z¯—Ÿê²̃!́Đăl°û‘éH¸f /6öơƠœ‡]Ư×' McÜvM?Y +¶ÎÅÀOWhZw%à@8., 7,úë‡É­èÆ Ÿ&¯/÷KJ̉4†<];SVăŸ±ÊgM¶E èûÙ{„yú‡_/¨±Å£ư§.¨ñ‹‹±DËư„¥iÀ£˜(0Ă Ôa®)JH„‡N$¡HKREr¬ö3ĐDWy)S/0™ +Cé]=t~RÖY₫8IÙ/3öb¼₫Ú#đưû°r̀´^½îy©¯Œ”ªè…}GĂöøôöÓrƯ~(µ%€–«%â` ¥ ^ܽơ—ăQrÇù(™²¼²IƠoWºñư¼©ß[ßñMé₫©ơoÿÆ,å̉ô°zzS8̃Û„}*fÎVß÷9lG°{q̀\·ßÆ GG²ëb†+€m`HË#Xèɰ~jÇÎeœçcgÊùd́¸̃₫ ~%Èë*ï›PBù<ùq@?Ü{ˆ³•̣=Ê™ùIá∸n¿‰–&DEü´ +ĐmÀQ=Đˆó$à ¬¢¢}U‡ËØÎGĂ”íϵ¹qÆ+6a Ϭì=Wêđ.<‹ÊÆ®B°ÓÚñÍ×öuÓà•4gÇ3—i†æ‰ß~R¼’¸/ª¢»· ±¼½è”@Á" ê['ßjö̃f¬‚Å_.₫Ÿéø°ạ́œ_n¾̀Pñœ 2¶€c:>ztÎ/̣qw]Ô®ÜoO’$RW5hĂñwYêƯæ=7—1=8×7îŒL’çÎ¥ƒl9…]Ă)B(ç_àŸHç«à»¶su9ôºr¿u}"`́+]OÁ¡àÑ$& ç‡7,ó̃¿Œï¼÷§|_íưáâá ¶áư³Uđ½HÅå ê‚ưó­äË«YØF)(Q¢ÔØâw}SµG~êöư™Úü9p±pn©đrèÔ?ª¥$V́ÜTươ¾<́ +endstream +endobj +526 0 obj << +/Type /Page +/Contents 527 0 R +/Resources 525 0 R +/MediaBox [0 0 612 792] +/Parent 519 0 R +/Annots [ 514 0 R 522 0 R 523 0 R 524 0 R ] +>> endobj +514 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.915 642.06 188.741 652.964] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a81be18ea979e8a32f384e1a7856badcf) >> +>> endobj +522 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.915 614.164 214.694 625.068] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_afd549f435ee28276b5a9408a3a6256b1) >> +>> endobj +523 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.921 586.269 177.882 597.173] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_ad808efb2e8af3803571c0a6c7c9faf39) >> +>> endobj +524 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [435.802 210.231 499.771 222.749] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a22b53cd4103da9ed88c351e7045ff313) >> +>> endobj +528 0 obj << +/D [526 0 R /XYZ 72 686.127 null] +>> endobj +58 0 obj << +/D [526 0 R /XYZ 72 558.334 null] +>> endobj +62 0 obj << +/D [526 0 R /XYZ 72 427.484 null] +>> endobj +320 0 obj << +/D [526 0 R /XYZ 72 403.078 null] +>> endobj +66 0 obj << +/D [526 0 R /XYZ 72 403.078 null] +>> endobj +530 0 obj << +/D [526 0 R /XYZ 72 271.167 null] +>> endobj +384 0 obj << +/D [526 0 R /XYZ 72 113.727 null] +>> endobj +525 0 obj << +/Font << /F46 237 0 R /F73 498 0 R /F43 499 0 R /F47 238 0 R /F14 318 0 R /F59 309 0 R /F13 312 0 R /F76 529 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +539 0 obj << +/Length 2066 +/Filter /FlateDecode +>> +stream +xÚíZ[Û6~Ÿ_¡G¨̃/-Đ ṔƯd€}H»Ç–g„Ø̉T’3›ươ{(R¶hÓÊHf7@Ÿ$ÓçF‡‡Ÿ“‡'·7aF˜J0bJr O)´&I__ùêƯíÍOw7õÂAFR™ÜmE© R„'w›äC*Y,©ÀiV­êCµ :Í>®ËM†ƯøÛ|—¹·wÙ6sÅ:[ü~÷Ë \̣aɈ"%$°öóƯÍ7^qB\¼ª“ơ₫æĂï8ÙÀø/ÖÑÉs+µO¸ÔđÜ%ïo₫Ñ +ûj~%„9[ ¡‘§•@ÑÅ’`ŒÓÏ ÊÓ2ßÀỒxƯFDF˜@B¨Ö#áQd´9x +a Xœ XeHCįTHyá¹~F‰ĐïfƠ¬"^5ˆPó*^ A„èĐëưªÎÜZÿ†^,¹i^467oUÁb6 ́·z»¬øÁ …>4̉’tBqC„"˜»©«Å麣 IÉFÛdu·‹gb‡¢Î̀cl½PéăªrZ°=OZ°N”ñNë7ŒY$…7̀ç…Æit]0̉˜̀àJv9[Óh `.âÁdÉ´„"‘, AF'q=6°Äa¾(¶̃$lb "¨?QV&¨¥ª'¼Ô +e’%åíâ·J·Y¥´ñ5³¬Üs“µ›¹Wiư;\{ÙÂ=ïwåúS7¶ơú°)p¯¬–„=³Ë oéó‚°]çeڅİ„ +IêwØm¾ ÂKYO”¥+÷Øå°í[ëuy¨ÖÖ.¥®´£.05éĂi T¶QX •{î»&Úe}ÍЇ«o÷áädU;‹ơS¶Î!•´¹ÿ½_5U₫ïĐäí[[<¨G K$¤‡é¶h†4dv2ñú— 2* j(@àIJw H–\À¹ ›'f™míºÚH×yV45‚âeHúÏG»ÊŒô!\xF°ƒ}Ô‡¼YƯÛE²ruÖ¸a;;piÖÁ@ó˜×Nt{(ÖM^zOÏùnçÆŸ²j[V{7Ükl+Ú;öÏ¿=ï.‡RDƠ`w¡”´×ÔGĘD°©C6@Ú¡®wª‚F¿‡[[p> +a§cä(àULú"Âđ8ư[V<4aưÊVëÇ^u»,nîÍn_·QÖMYµ[/<Ö¥ ´¶ƠËÛA—óœ!Upü„ĂDƒºVÊ<}8i$œ›ó€N ÄÍẠ̊xT3íÏu´LóGKßóƯ£ÏgqØßgU˜ïúù¯CT¥-’Ï~4ïêQg×—¹NúxnÀû¶to;£§æÔ9Yê9¶ư®jr¨m25Ø‚sRĐ^¯{6ÓÜÆaÓw;›̣Đ<sy€4e—ób}¨*8Vw_|‘j;’7®WĂèI…Ùu,åt4̀ÓoáÀmë*Ôđà̃cÈu4p +éHfˆƯƯ;®aĂ8ú-á>Öæß0—Zx®ªjơ޶€g^8DX)ÛrƠî½ëb7îă¶*÷î­kÜûyÖÙô}ˆ§å:ÚÇlØï³ơǼțΡ=Û.n0Û/2“₫ưPûøî³ ặæñ̀ÿă‘Ïhä:Ät{£¿¸++Éá†~¼¥}X ŒĐNæXƒ¯nÑ0oµ•˜̃¥ÍÔw{F $ñü.Í’U\AרMpø^ß;ÓG7OàøG¿Oz¥óÉí§³ZÙﻺd{9{¿?´{c :%süÂô:Ç|zúçé»ôK†(Ÿß{Q»RÂuT†TD<÷Ó¼Æsß÷úâÜw·ô³suDîGO!̀¨c1=ơ£Ơ_L „Sœº  ¿7‡ªˆßOϳ•(̣aÆœzay”VwđL ˜–,¹…ˆêÓ×,B_‹ëô5# “>“³ék +–42L½€½†Fú5ÜZöëĐï{ åç5¼H»9›míÈkq$¯ñ]ùụZ₫u¾™e>Eͬ}™#µỰµ¥m˜Ÿăôµh!aÅ0{LbƯÄ9}}ăaÛÜ[ªjÂî71?Ÿxâ–x₫& ´¼F`¸®Ñ?™ÁöêehpÆ0J_LbèË$ùV$vHM‹¿¨é€–/¢¦åw@MK6Ă¾€ó ỎoJR‹W ©/.ug?¤ƒ/ªĐǃÿCî~ÑéÏí9£»Mú₫ưÏ‘,9´VFs€ƒh ₫óirÀ=âzz6S¿íÀ)…×aÉ)±7Mơu–|Ïhûøü%ÉGÏ7̀2hĂg:Jæé·(!ö@SjL·E1ø’¬Ç“D12Ñc$}—ß7>~úAέºRÓ©™ú3úr:³´Ø?wpXè₫(éj.̣̉ù:?>Ñq:}ÇÿKz|üœÂ|‚:§Ó¹™úzhÂgÑăpY²´QJ‰<]lvh˜ä6†¾Û¿Ḥï„$ €ù̉₫±nz6Sßí®ạ3 ©#°Ư‚Ó:~ÛḶß6}§ß=ƒ0o ­äô®k¦¾Ë;“Hâ™]…îOØ|ÂÓ°s#ûi~ăÉïûưvüøø)„Ùuơố×ï +shc$5û7íÿwÁp +endstream +endobj +538 0 obj << +/Type /Page +/Contents 539 0 R +/Resources 537 0 R +/MediaBox [0 0 612 792] +/Parent 519 0 R +/Annots [ 534 0 R 535 0 R 536 0 R ] +>> endobj +534 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [435.802 500.345 499.771 512.863] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a22b53cd4103da9ed88c351e7045ff313) >> +>> endobj +535 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 260.492 111.003 271.372] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000001) >> +>> endobj +536 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [435.802 173.703 499.771 186.221] +/Subtype /Link +/A << /S /GoTo /D (erasure__code_8h_a22b53cd4103da9ed88c351e7045ff313) >> +>> endobj +540 0 obj << +/D [538 0 R /XYZ 72 686.127 null] +>> endobj +70 0 obj << +/D [538 0 R /XYZ 72 668.127 null] +>> endobj +541 0 obj << +/D [538 0 R /XYZ 72 561.282 null] +>> endobj +382 0 obj << +/D [538 0 R /XYZ 72 401.032 null] +>> endobj +74 0 obj << +/D [538 0 R /XYZ 72 386.462 null] +>> endobj +542 0 obj << +/D [538 0 R /XYZ 72 234.639 null] +>> endobj +537 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F76 529 0 R /F14 318 0 R /F47 238 0 R /F13 312 0 R /F73 498 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +546 0 obj << +/Length 2219 +/Filter /FlateDecode +>> +stream +xÚÅÛnăÆơƯ_ÁG +¨fç>ÇHÓØhĐéÆl̉‚¦(›X™tHỄí×÷̀"µ#Ú7퇣9—9÷s(œÜ'8¹¹Â3ÂT‚S’KxJ¡5IZøùÄOïo®₫|{ơî¶2”I*“Ûm¢h"u†áÉí&ù +DVk*pZ¶y·oWD§å¿‹fS¢·]íJ·z_nKw .ÊƠ¯·ß_áÈ%ÖŒH!RB'ؾ»½úíÀ'Äñ+PFuR<^}ø'Øÿ̃àËṭbO=&\jxî’¯₫y`j` +³4/‘%BÆ<‘£,óRy_öû¶î¦—ôO¨Î’5<1£¼nj/  í#Âk¢@,YsˆĐƒ>E|µ&ăôyEyÚTP¹éD>„ Ä%I$6×`sB¢(ÓÙ ¦/A˜F\&Œ4ö‚¨êª1üuˆ +h6%Úçw+•îÊÎ]û,đjÍ…n,3ï®Ơؤ¹@ŒøăÜ‘)àW¨p$†PĐ gÚÅi³""}éb©@‚ñpz_wƠ}]z=ÀưC̃:(p´”#á$@ư²‹0¢Æ|ä¯_ç÷#~¿íïV§».&‰¤Ê虸ˑ›¬™Q“VÉrÄxæ ₫ +æUå»ê?>Ä€æÚa½mZ¿0,ä]ï̃¾³qÊŸÿ•_u1¬óză›̉F2ĂđdüMRoc7e ¯7ʦiÿPKK£̣OO€ÂÔ₫äy2¿Öe9́[₫̀æ?³1ëpÂñqV†‹˜]ó»§ÑÔnën×ẴÖíṃ>G«µÂ*eôîs`ªn¸#A™^}₫›#–yáƒ{U?í½\‹¦Ü®¨0vA‹ª¬{tâç"™ T xƠ₫`BW̃æeo²IăÑ4ÿø×ă” ˆăS³)⺠l=_‘,KföÀ œxuŒ¢ŸbcG†Đ¯ Rˆ`/¸±xk2Ä¥§éJ(„a9!yûà=§̃?̃•̃JŒÍ™ç³ñˆ²èƒơt;-‚“†Í¶1¶ó̉³̣îđzK §ó¾­>Y%¸@Uߣ/o/8ƒÏ/¸₫TçØ¡¹Øf–Á[›áADfËl†j pq¤„ é‹´yéNÚÎ…”£¶3¡VlƯ•S›î†¢–ÑX10û²ŸH‰Cï4Ôë#H̀z’¦çüâ\íNÍ ^Sχ?³ÏçĐéÿ_Ÿ¯Æ}¾ˆôù +ü/Öçs„¡bẻHƒ/ëóÁù¤´¨HæÍ—>Cj¹¼FLük• 7¨[&d7MŒ¨âHû“K‰*…4cS¢O­)EM„r&÷Ç—RÎ2Ä)RÎM#ôüÉ©9̀5ø‰ˆªÁ½we@Ạ́ơÉá̀ó LàÓ„g±¡‚ze¨@ùëCο*D¹Đ(cj9'81¢ ƒ(:;å)NÈUKñ»ñ±€!¬3ŸC|-½)»>&‚ó EHDµÎYn®±…<Ä …+Ó7f$a¶±gÿI"„¡’ơè”¶|DDăÓvñÔ6›}á_^ª̃ú£₫fÜ!¸„> endobj +543 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 239.795 111.003 250.674] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000006) >> +>> endobj +547 0 obj << +/D [545 0 R /XYZ 72 686.127 null] +>> endobj +381 0 obj << +/D [545 0 R /XYZ 72 632.899 null] +>> endobj +78 0 obj << +/D [545 0 R /XYZ 72 618.329 null] +>> endobj +548 0 obj << +/D [545 0 R /XYZ 72 527.832 null] +>> endobj +389 0 obj << +/D [545 0 R /XYZ 72 392.29 null] +>> endobj +82 0 obj << +/D [545 0 R /XYZ 72 377.719 null] +>> endobj +549 0 obj << +/D [545 0 R /XYZ 72 213.941 null] +>> endobj +544 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F47 238 0 R /F76 529 0 R /F14 318 0 R /F73 498 0 R /F13 312 0 R /F11 313 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +554 0 obj << +/Length 1723 +/Filter /FlateDecode +>> +stream +xÚíZIoÛF¾ëWđHådöåĐiÚ"uŒ @’45²ؤCRvÓ_ß7 iR¦K2‹Oæ-|ë7ÏÆÉe‚“ÓF˜¦Œ˜’\ÂS +­IRĂÏ[~:;ư|>{u[Ier¾LM¤6Hœ/’©@dQS[çͺÚjaÑUØ?Y]Û°:³K”…>;ĂG)—|̀‘B¤„¸½9Ÿ}™Xâ„}2T'ÅÍ́ăgœ,`ÿ­ăgtrïOƯ$\jx^'ïg>(Ơ+G…[ºG´ˆ0C‹„1O¤ÄȘh•3Û®ë²d|‚AƠ€œh¤°I2xbFyY•Ñ@#Ù‚3¢À,É8EDè̃ˆ"9ÏÆ8½›SV«8€ñôré™́CG„‹Db÷l—‘(2ÚôfzlpvÀ +#£%è-Ú ±B#IÙ³ˆ•IBÇbƠ”PÅ‘!äY„*…̀Xä-ĶH«Å„\#ÑóXØÄơ†Ü|NHz÷/ >₫„gÏéªô&xu¢†ùË!¡´öÚ–?„Cc9“Ru‡¦ 1»3w[8Q†6Ư©uÙ¬.Kñ˜«ô*¯Ô“*"zªO`µ ȧƯ™Ëe{1'8½n&µ0}¼[4SPÓ›¢©ç§Å¤]AXí©GÆ\‰‘ #Ä“ô<Œb¶i§lBĐĂˆ2*VE*“ +PT&¸`£QcÈedÓ‘7Tí„A^Fmÿ§FL̉dÙà”özøfqç’ JGU‡w—Đ~q[W‹u_îWml3í½s^ªu{»nä„‚Îiđ¾+—’ƤùICz₫Đ“X<đ‡—ê¶]Ư¬₫ó>‚×¶ +Ï"¿.Ö×ykăv/Û‘¬è°Î#›<[ƯX4Ïæ_+ÛLo7)#.åÍá6øÆNË¢®¸¶yqV_»Ï«–QÓ+ +]Iˆ¸²«đƯpPă4¯ëük\–ÎtÊ >v‹ªlÚ¼ŒÇë5•—‡‹Ê.çT¸§ÅÊ–Ưïm¤úÛđU²¨rÇÈ\u]Dd̀˜ô—¼ Û6P®ïbØYú€Đ±Â‹Uyé¿Ó° €` )́?–1)çĐ<’¥'ë²hWUÎÔöËzU;ç»·ÛÚf]0Å#Â+ïÙ…W:Q(Wˆbơ¸B‚º&Ư6ÅÇ­Ø>\\Úc;¼éµÎ÷GroVÿM‘Ê;ÄmôñàvC¸Uµ́rÖa‰’×…˜À‚6À–k¼?úÅÙé&7R…„V`snñàôI¨»VƯw”×₫¢€vnă ˆ9ä‘@ÇôyçZ^ç7¶u ™¤ÓjL ØüusP—µC”ơàă9éà–„3P–Ó]<àtđöÿ(6B˜¹ăŦ¦Ç0Sø̉aâC…ºP¾k„₫fËË®ơøb#úB4ѼVexºœñ5Bÿ÷ucùÂÆ̀$¨–â¨ư4‘˜€₫y‚?^Œ¢ÇÆp :ß₫ÖGc΢ăèCA×ZEØ·/0…+1(l[Ăè0©Óa4”úÇúæÂÖă0Ú ¦Z×…mvùuoơÆ~qÀnûơ8zïWfăƯ_w C¶{•ÂƠ—*¸àx’‡kÁu³Ơ¯IöêPê» +®LέpAñ˜.J“mœ»₫nM”»˜g$ưÚÎ +-»î ¿y[CŒâÛ9üÖµü&é½£*ĂVhô°Ñsd‘#íúx`ôĐdzĐú¡óK)ÆØâ'S`_OØ3}püGÂ_CµOÛƯ‹i4ܺË(Sp·Ü‡ ̀‘à×ñ0(l·!-xa«†å­ë“ưµm‹›÷Vẃ) Çôpt$}p5\¥µ:93€9€'f|ÏŸöóaR§ư<”úd?;ơVe¼æø¼Í#r“µ¯K Ûåÿ½?ć? —êpsưSd¸¡|ï!²zCX›1æz–¹±ˆÂÍäenü27~™¿̀_æÆ£¹ñû÷o8";ÿy’`Ç=ÿyá¬&åt +endstream +endobj +553 0 obj << +/Type /Page +/Contents 554 0 R +/Resources 552 0 R +/MediaBox [0 0 612 792] +/Parent 519 0 R +/Annots [ 550 0 R 551 0 R ] +>> endobj +550 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 480.404 111.003 491.284] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000007) >> +>> endobj +551 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 154.16 111.003 165.04] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000005) >> +>> endobj +555 0 obj << +/D [553 0 R /XYZ 72 686.127 null] +>> endobj +393 0 obj << +/D [553 0 R /XYZ 72 632.899 null] +>> endobj +86 0 obj << +/D [553 0 R /XYZ 72 618.329 null] +>> endobj +556 0 obj << +/D [553 0 R /XYZ 72 454.551 null] +>> endobj +374 0 obj << +/D [553 0 R /XYZ 72 306.655 null] +>> endobj +90 0 obj << +/D [553 0 R /XYZ 72 292.085 null] +>> endobj +552 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F47 238 0 R /F76 529 0 R /F14 318 0 R /F13 312 0 R /F73 498 0 R /F11 313 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +560 0 obj << +/Length 1933 +/Filter /FlateDecode +>> +stream +xÚíZYoÛF~ׯà#T›½‡HÚ"u @’4EÛl̉¡¨¤é¯ḯA‰”)Z$å úÄƠîαśÎ|6n"Ï0ÂŒ0aÄ”ä¾RhM¢–,]œÏ¾¿œ½8ƒ)ƒŒ¤2º¼¤6H].£·±@d¾ ÇY™¬7åœè8û+-–ºơóg«»̀.²ë̀oÈÓl₫₫̣Ơ OR.z»`D +̃âöÓǻĂŒÀGÄë+¡:Jïgoßăh ó¯,?££On×}Ä¥†ï]ôû́·R[娰Cû ¦i‚0æ‘”¬̣zNyœ”É}VÙ#“xƯ>o¯ˆưƠGçÂÙ¿ï< ” l{¦S̉#bL$9C̀ĐĂvd„,œák0°ă¥×:ËƯe¹3UëĐD€T1V(WM¡B! Ă–ĐŸ³ü¦ +ñZ\‡xN̉0óqNDœ¥UQú߫ܯ>WÙÍ!qüËf]…YÚ/ÎiJ•Q,@='ï;¿¥¥˜BëzĂ·‘è±1XQ>Âí(°läø DîcˆY£È‰1‚w2”¡̃z{ƒhœÔî jJưus••í Úu±)S4‡½:X½¶[˜½&¸u½÷+–HƠÊ!‡ƯJá]¡*’”"ÎŒ7đÍuuu·>́ØQb»ưÚûºXåö‡<§qUØ/‹iHr̃ æ6…ë ~‡1ëÈrŒ&ơÖÅÅØ..ÚrWó‰?Wsg^ˤ,“Ï~ÍF¤z(³EÜ¥›»¤Ê–~--̣u•äƠÚo¹JÖơJ‘û©ê6ó[,p¤p>lªQv=§ÂªMVïh!’RD ²áºMWëK‚¡®lÇ0PK£ÇçÀ4z—Âp§™ü>ÚÂDó¦[—s¦âô`Œ”Û™M¹/½ß›wۃϋµÿecwĂƠ%DFŸŸ‡kÛr”%g||!4‘̃;ZĂWO-„àηæ€BU©$Ë *ƒn'µÛÍM©GûÙª·Ê“jU„jh™TI¨€æÇw@ÁßëÿÁÇhûOĂ’ï₫Áä[Á5ÂRyË^dƠ¦̀»û€}Ïh¤°;ÈY¨.̣"=SKöà7rvÁm˜èm‹†(̉đ8`lKhM\đ”*xS;b ª¬TĵvßQxˆ̀Ö< X@+…´ +–`¡"ê +m ơ¬8‰X(·$vḰ²èª8̉nçt¡ +„1ÖúPÚ +°XvH6j vÉÆ Ni[rbÛÎ{7¿ĂÏ\p¸“+_P¨fW/ …ŒÀÛ́¿©-F#xëMƯŒE”‹fỉÅ nÂM½k“¯W7y"2«ø6);*#ˆL; +¬– +äo÷ØqƯÙƯºS ŒE¦jq@k +º5<Üp+¦́ª¥x6=à.`kj0Ñ~^ömBàEÜ1¤u_íƯS !Ơ:ZPû†rùǜ[]Ù²H"£˜¼1#C’%₫́¨mCE‹Æ.íôè́§lNûGª,–›4üø´ª›ùê¶̀B1Rlªm5ÛS»ûR̉Ú¼Œ![îFî0Øq‡ÅCµº_ưă<?ƯƒßmQ¦ƒdK°±‚ư8qLDœ„]«û AbrÿXdëG¤‡É fP\cMÙiÍóƠ:¦e±。ÀÈ¢̃v .uIh;\µ ¸ï¨u[`çBÓ`g“|Yï󇄹ºưđ ë̀éó5ËfWá[¿î,ë^ûÀ,( ÓNa7̣ŒD­ßÅ‚iÿä"đظ₫ÇÎ\»P°lºé €÷º™b¹Êo€fÙ,–™»£ÚÁ2sx(¸Yøl“§¾h²Keöa³*­ăí¯fo¶ƯâÚ,ËÎXÇU6¯/̃z‚Z̃Øv´ó¦Ó:ô‹x×VÚ3*ßVºŸ™P”Ñ®¢´.>´WdÙçÖBÉnpq¾iƒ?©BBo 5ë‡SU­qû> endobj +557 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 367.478 111.003 378.357] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000009) >> +>> endobj +561 0 obj << +/D [559 0 R /XYZ 72 686.127 null] +>> endobj +562 0 obj << +/D [559 0 R /XYZ 72 667.868 null] +>> endobj +390 0 obj << +/D [559 0 R /XYZ 72 519.972 null] +>> endobj +94 0 obj << +/D [559 0 R /XYZ 72 505.402 null] +>> endobj +563 0 obj << +/D [559 0 R /XYZ 72 341.624 null] +>> endobj +394 0 obj << +/D [559 0 R /XYZ 72 193.729 null] +>> endobj +98 0 obj << +/D [559 0 R /XYZ 72 179.158 null] +>> endobj +558 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F73 498 0 R /F47 238 0 R /F11 313 0 R /F14 318 0 R /F76 529 0 R /F13 312 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +568 0 obj << +/Length 1836 +/Filter /FlateDecode +>> +stream +xÚíZ[oÛ6~÷¯Đ£ ̀,ï¤6 ÛÅ6tmP h»A‘•Ä@"¥’œ¢ûơûHJ®ä(n,{Ụ̀$ä¹đÜÏIhtÑèåŒ*˜0%Âh©ñƠÊZU8¾çèÍËÙ§³g'ØJH¢¹NÏ#Ă#mb˜ŒN—ÑûX6_pEă¼Jëu5g6ÎÿÊÊeN.Ă₫Éê*«7ùy.Y>ÿxújFb.z¿L+35Àöâtöiư¤ ü*’pe׳÷i´Ä₫+‡/±Ñgë:’Úâ{½ư¾Ãn¶̃®,aº}û»9c,㦬đÂDÇ˲ ‹›ª\®³öGyÓ¬®WçËđ³)Ă7K¯²ơUÚäíöe•·Ër}³nê°N=§í­ƠuNæ )müs™×w@_| r'g'LD$FXǼŒPÍtàÿÏpmđFE¬ÖÑ¢wË#_ÇcV•u»ÎÓ́2¬Î¾4^Ë@& ĐñhÁI” +hËs\3̀;ÖW^ö̉ªJ¿„Ư´Xv÷Â#±—•EƯ¤E{¹Î=ØïPfe~>ç*₫@)ÏVyÑ{ÉăYY³*‹pTåŸÖ«Ê)̃ưº©̣EgF›+y.|Dk ²§dpJ8W`̀39‰S$±¬»#ø·û`¹½Ê[.ƒ°Ưê«6=×Aơ₫JêÅêßÔBy…„…³o]<‘„©¡ˆ[›@ĐñªÄ·³.,ïF#8\́ñ D­}rC”5دØê-Dá»-‘ØN$ÏßưÁ·‚!4ă>V%=Ø…–đ)onx=çÎg̉ë¼q–ÅălŒØ>ƯJ!Xµ3zF›zLxÂ’$RÛ…·ƒ₫ +¼èIAbÔăBÊb6HΙ£ƠàÑLqgP‰TÍ”!ËÑ_̣⢹g…°º3µÉ)̃pĂ×9Œ@ŒÆ¿®ëÖ–Ị̈Ö-YŸªf„Ó{ÿ0â•Ö³1Áï.ÁÉ]a(œàr‚4†Vp!øt+: >XO3æ@+Bb PËtuÀíN3FuÜŒúT[_ŸåƠĐŒ¶§.×U–×»ôº7{C½p‹ +ĂN×ëađA¯T¢h±»ŸÀ7ÙưjåđOnÀ%’ù^œ7gWơưzDu\­=ª¯ËUá¢8üœû‚Ơïh—Î…ÿ³ æÎæ i樀—]êÆ™¯Aذ@ñ¹g]¾¯Ă•.Ë;¨"l…, ƶªÁV›Ç¢¯y|jBSoƠư?îûjrhÁ€Ö:™î‡Á{ '©ƒó£kƒd¢ £­5ÖƠ\˜8»× &ơ‚áçmĐ‹m7Á3ÚºÎ×̣›׫ñvizvªràè8'«ú@ø jKÑ€Z +¡>pâ°Â—^âË5ŽzFu\Ï}ªÖ³coU´mßH›´­æœÆk +ηKÿ{?c¨?ă_3]ÿûĂ×́^¸ƒ¾`”âR*’®/iÖUñ –„Ybh‚¸i.xQí”fgC‡˜@câ Ål†B?)2¥®*AR®\‹,$̣ꈙ ‹&ÁD‚¹3»æ)ÙÈç®$*EW¡ «ˆ•­(Ä-¢²ZÀÔQÈjD/%‡dƯ¼ä.QXTâ(D-'Ṛ!Ñ›Êạ̊.eNa%₫úÁ”9²E;0 \×yP±›A¹é…AHnBEaú 4R₫Ú~ ¢ø.\ÚzjƯM3ˆ¹€ÊûµÉ&änAMwk]Ô«‹"o­1››ø2­FJ#7éSönm4`À€~wÅŒstgWơ( ÚO=‰ ÓgâF l$¼˜˜|p¹/ ûÖ>DôJ«ođ#6dºä²-4u½V±A¬ÚQ #uÅ—€jMî₫y'p{%©ƯăNÆj8îé¦ÂøÓ¥¨Íx?>¯ºf¾QºdÖ ĂˆJ çr±RsơˆĂcçM·<ÊüX=d~læÇOóă§ùñằß¾}₫§Nơ#L9+%›\6ïÛ&ÎáÖe‚̀Q™X#¿=AHt´kư¿N™̃Ñ|í/¡œÚ铯áƒQ¸ú£cL9Ơ ö€̣D¢ăVÔ#zœùñ₫Ü µpƒp²Vƒ÷ZeÆú²́ócær‰Ö O#;ªÖÙ§ ̣£O÷VåÀ†´äÓÿÂz |đ´wܰ£L™NˆíFAß O$<î}ÂÿÎyv‡ª85Ó'ˆÂU+gˆæ(d'yEå&È©ë¹Oơq'Èû?c¨?€6½ˆ™ßUåC<Eˆeû₫KÜ?MË?ƒ +endstream +endobj +567 0 obj << +/Type /Page +/Contents 568 0 R +/Resources 566 0 R +/MediaBox [0 0 612 792] +/Parent 572 0 R +/Annots [ 564 0 R 565 0 R ] +>> endobj +564 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 591.693 111.003 602.572] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000010) >> +>> endobj +565 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 265.449 111.003 276.328] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000008) >> +>> endobj +569 0 obj << +/D [567 0 R /XYZ 72 686.127 null] +>> endobj +570 0 obj << +/D [567 0 R /XYZ 72 565.84 null] +>> endobj +375 0 obj << +/D [567 0 R /XYZ 72 417.944 null] +>> endobj +102 0 obj << +/D [567 0 R /XYZ 72 403.374 null] +>> endobj +571 0 obj << +/D [567 0 R /XYZ 72 239.596 null] +>> endobj +566 0 obj << +/Font << /F46 237 0 R /F47 238 0 R /F13 312 0 R /F14 318 0 R /F59 309 0 R /F73 498 0 R /F11 313 0 R /F76 529 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +577 0 obj << +/Length 1709 +/Filter /FlateDecode +>> +stream +xÚíZYoÜ6~ß_¡G-P1¼‡HÚ"u @’²–k °%G‡Óô×w(R²´Ö®÷0Đ>øI\i.Î g>GW̃,0ÂŒ0aÄ”äRhM¢ +>oùt₫fñưÅâƠ¼2ÈH*£‹u¤h$µAđèb}ˆ"Ë„ +Û*­ÛjItlÿÊÊ•E×₫ưY~cưêÜ®­'(2»ütñvO2.ú0"…ˆ‰œHûébñyA`‰#âíÈPe·‹Ÿp´‚÷o<££/ƠmÄ¥†çMôûâ·£ă¨pK÷f́‚0æ‘”¼rn›¶*êé&ĂªF́D#…M”À3êÙ‹²è̃Pœq`QÂ)"Bñ@đ‚B0Æñư’̣¸̀WÆă«u'uâ Â4’ZG»}°]^¢Èh3øé±''H*¢0̉8¸‚ßÛ¬™Q+"R>‹Z)aÿ|ªvUÎ)Uṇ̃t¥"ÎÙT餷ˆËƠcÍÔíÈOÖL1ï2e¢9]ßÿíĂü ¼L §ă¼è¼đêLÏ0Hp +*:Ö[|ă‰66ˆ”T=Ѽ BÎæ~‹$Êæ§j‹:¿*lÈÈl©âë´̣\PS¸„† \Ái3(Đ?läjƯ\. oêY+ ÂFŸnÅKÀÔ ®¨«%Åq6ëW°VÚ‘0HrA\ ȱ—=Œ÷jV¶næ|BĐ d ™¬B•(†°QB9pÏôæ̀% C~#£˜²¡rG I¬ưÓSM„ +¤!É’•î́èƽ;MP=ÊÊÿvgº[ÜUåªÍÂ/yZͺleÙ6wmS#§ –HCè]½”4˜÷p`H/œQă…»Å œ1t×ä·ù?.@î[Súg–̃díMÚXÿÓ+îè[§×¿MƒÀ4đæ·-ÁuüciëMÎ턯ku´+çvW{¥iV•u0Ŧٵ_]~m¬÷ƒRa `ú¬“^l¹'kØĐµơ‹¼€MûeZUé×°,V~«¬,ê&-mmnå%jøn×K*\^Ó,·EÿƯ¹Ư=½ñA«·×­:{G‚F¦ ‰MRÅ?¤EàŸÛÚF=ñûÇÓă°&/®€ŒR‡aä¸5 ;…—+Û!đ"&ñY[dM^¦²ŸÛ¼raw„w•Mú +$ÔïÄùŸ|¦ P¨X̉ÇUq’ :È@Ă茜nuˆWÛ½YÁÙ`ç(đ¾¼#I½[¦ß›,B2Àª ¿?Ÿ i=uvç 8Ê}rẠ́qz  „åZ­ƯâüÍ&x…xR…œ¥€̉\L:DºTă´33¸äơû?6@́.¬ÆđÂA‚¥x8Hï8K«ôÖ6“x̃y›_7Q/k™Q;Q/@WAÙ€5“c"•‹̉Ø!¨}ĐGpG±q#áNC³̀ ;ápđ±J§ \¨®KO”₫l‹«¾ƠôÙĐL³Ê ÿtçÅƠÈä—¶©|iĂ©$ Ø‹>Á¾›9”€øùßzYD¢ÇÎp Ưá̃˜fë=œŸE§ñû,‚¾­µ>1‹àâ‰,áJŒÚÖ4:Në|µ₫Ú̃^ÚjF›ÉSC•̀l½+®›7‹ĂBpÍ8:®§ñwqe†A-̃½¸;²=ª®»TEx’‡kÀM½5®GiêXë»®H.¬p!ñ0‘°ÙÎỮ£ơ’'8;DoàθËeBâ¯ÍĐ¯·2tn÷Íå£{5Æ'ö…o}»¯=IḥWá_uM̃½$² ‘ömÜ zhă‰G²É]-&hkÔágÀ¡‘œ$°cfúèü?Ư§¿†j‘:µ9ºÙÓi¸4ô—O¦à.¹ơ§xö L¿pTØîü±¨ư¯Çåm„ïv†ù`s§‘vLÇA'̣ûPK´:97€;@&fz¯ŸóqZçă<ÖºwœyyÑ_qÜ‹´Ir’¶«kàÛÿƒ·1°Ku<‚9‚ÿÀÉ1cơàà?Ó™Á1̃>84¢ +̀—'Ï9é$ơC†]ccö:ƯĐ˜˜‰Îí3ă@x¢J72Æz¢̣‰‰1VÏ —bh‚FNô†y1ơáíÆdÛÀ–œ==0–J?90¦Jí10¦”̀HñîQ­›’=50¦Jî?0[?i…̃s`,Ô>c S‡Ú‘0‡_é—ñËÀøe`ü20~ÿÆtçx! Wöÿ¨đ/0äá +endstream +endobj +576 0 obj << +/Type /Page +/Contents 577 0 R +/Resources 575 0 R +/MediaBox [0 0 612 792] +/Parent 572 0 R +/Annots [ 573 0 R 574 0 R ] +>> endobj +573 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 480.404 111.003 491.284] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000012) >> +>> endobj +574 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 154.16 111.003 165.04] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000013) >> +>> endobj +578 0 obj << +/D [576 0 R /XYZ 72 686.127 null] +>> endobj +377 0 obj << +/D [576 0 R /XYZ 72 632.899 null] +>> endobj +106 0 obj << +/D [576 0 R /XYZ 72 618.329 null] +>> endobj +579 0 obj << +/D [576 0 R /XYZ 72 454.551 null] +>> endobj +376 0 obj << +/D [576 0 R /XYZ 72 306.655 null] +>> endobj +110 0 obj << +/D [576 0 R /XYZ 72 292.085 null] +>> endobj +575 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F47 238 0 R /F76 529 0 R /F14 318 0 R /F13 312 0 R /F73 498 0 R /F11 313 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +583 0 obj << +/Length 1906 +/Filter /FlateDecode +>> +stream +xÚíZKoÛF¾ûWđHƠfßC ôÚ"uŒ^’´ )Ú`“I¹M}gTH™bDR rȉ+rw¾Ù™ÙÙ™ÏÆÑm„£‹3Œ0#LE1%¹„§Z“¨‚Ï>]^œưtuö́^d$•ÑƠM¤h$µAđèj½"É +çUZo«„è8ÿ;+×9zçߟoîr?º̀or?¡Ẹ̀äíƠ‹3¼H¹èơ)DLTOÚó«³÷g†8"^_ ƠQvöú-Öđ₫…•gtô›uq©áy½:ûă£R;娰Cû¦k‚0æ‘”¬̣2¡ó–I\÷÷; +±ÿơÉ~„pöÛ(%(Ûíé”ë1&’œ!f‘³ 2BÎpu G˜@ØÉRˆ€kåị̂™ª·i"Ùåª *Â0́₫·Mˆ×̣&Äs…7 q5eåo +ÿ¼₫Đä5J qüÛ¶nÂ[ÚÏÎ é¢J‚( ĂûÁOé)¦âºđ½—Å(zj V`”ϰF? +¬9?ˆ-÷1ĬQä‚„ ÀŒ#e¨·̃ăhÍC¢.êïÛûë¼êÑ~èÔå¶ÊlĐöêdơúna6-pë²ỡ¯X"mÔø(C†v+…{…ªHR83̃À·7Íơ]}ر³`‡ưÚ…}Yn +›ÅáœÓ¸)í“Å<r̃YÍínOđŒÙÀ)çÈh̉Îat@±)R\´;宓‰?4 ‰s¯eZUéÿÍF¤}ơPå«,½Ë¶wi“¯ư·¬,ê&-ÚO¹NëöKYøWͻܿØIdA"…tø°mZAùMB…U›®¬̃ÑJ*$¥ˆV.dCºÍ69€‚©®́Ç0¬–FÏ?ËÖ»3 G°›Å÷£-L„ш0oººJ˜³ƒ‡`&îà)èâ₫èữÍm₫\Ô₫—=3\{QBdŒùyº¶=GÙåŒÏ/„®÷ÖđÔK !ÈùÖP¨*É:‡â ›ç¡»¹‹z´Ÿ­z›"m6e¨†Öi“† +(¡8̃ºDÿ¨ÿ'o£ï? Ÿ̀|÷O^>±%\#,•·́ẽl«b¸Ø÷ŒF +È™°œ…ê¢(‹Đ3ơ°÷€Wî 8³+nĂDïZ4?ÜÛz“r2—ê@1¤V× €MĂn"³³ÏSKN\}ƵBZSđG(‰`%CĐÏVJØ?ïĂ®Ë!Pé$ ÍœÓ>èCeKÀrư™bˆ7}12ÅܶÉ}äºÎ½‹ß`“— +ră« Ơméá‘[¨&¾ó“ö6‡”Ü50Ă‚EPtë’!Ipo3¬ÚYÛ¢̃ÜyˆÆ,Qñ»´(‹„vư¤.ê) ¿b«Å:³»zP ­§œ¥„ê*q@°5;KÀ¥ 14+èAùT=V â[ºá“ă1ú°L{µ́Û„ Ö©_é媽µR rvỖ¡¡T¾8·±ÖVµ,’È(¦ƒl  I´ưk ®HCº\ufi§Ç`/e³¿ ªr½ÍÂ6m#•H¸É¶Í®…mm©]ª”4đ5&„V8£Æ ·ƒpÆ@ĐC³¹ßüçªcøæxîêiÿÓ»ù[‹ëߦA`Önîs”¬àˆ)ózåaKÂW„!9Ï5åĐîjfUYU<ưaG–æđ–c) dƠ^Ô¹2Aß"ØAè́0t nX¬ư ¸FmÛáƠ¹UĂ¼DƯë&|ËJÿôÊÔ@×è oGPGµ] Àư¨âŸÓ"¬Ÿ·®ïñJ=«é÷÷º˜r½)na¥–Ñ,×V +%a§đr;¬ˆI|¾-²P,Áœ*¿ƯTÖívb·' S|ĂæÄùŸC '…,€%=¢Y¤Ÿl9'Iñ-§U+ốx“îúD7Å·“vN»7ï„`€‘s¿?Ÿ–®Ơz ÊږŸ†Ú+®́-k)d7¸¼Ø§²ÁŸT!¡wơ‰ă§ª̉8uj“¼zơœ#²ÇjUjP g ΔjyÈÏJĂYF\Í®–—-w½#ö‚'!ÅÈ`úỉx&è`«ÔưZIc"G:®éÖè,'d>½¸p½"(vm¾:m̀°FpAÏD£.êihăéêơưËƠø̣q¿.[ïüJµưÛ;mL ´FEσôkömüÅiăÉ®́Ű]ÍÅ|6qáz¤†ÆÑœ„6¦¦µ<7 <| ºÀŸ‡8®nßU°œ̀wô’ỠÍJ\.NBSahYÂQ̉x&ê°»¨_–4¾¾÷„/¸g{úú‰´1tJHSö•ĐÆ|"m¬]Ưª[N+'J²` +1FË“ÀÚ¸;Bó“€:Ú˜ơA?E³S {Ú˜ö‘SÛw>₫Û§ơaêXpz u¬ ÙQÔ±™ÅÚ#¨c:;Ö˵ăٱܱœÅ ̣;ăm%j¯"¿î)‹|dT 9Lư_Ăÿ´Kj- +endstream +endobj +582 0 obj << +/Type /Page +/Contents 583 0 R +/Resources 581 0 R +/MediaBox [0 0 612 792] +/Parent 572 0 R +/Annots [ 580 0 R ] +>> endobj +580 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 367.478 111.003 378.357] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000011) >> +>> endobj +584 0 obj << +/D [582 0 R /XYZ 72 686.127 null] +>> endobj +585 0 obj << +/D [582 0 R /XYZ 72 667.868 null] +>> endobj +378 0 obj << +/D [582 0 R /XYZ 72 519.972 null] +>> endobj +114 0 obj << +/D [582 0 R /XYZ 72 505.402 null] +>> endobj +586 0 obj << +/D [582 0 R /XYZ 72 341.624 null] +>> endobj +391 0 obj << +/D [582 0 R /XYZ 72 193.729 null] +>> endobj +118 0 obj << +/D [582 0 R /XYZ 72 179.158 null] +>> endobj +581 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F73 498 0 R /F47 238 0 R /F11 313 0 R /F14 318 0 R /F76 529 0 R /F13 312 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +591 0 obj << +/Length 1839 +/Filter /FlateDecode +>> +stream +xÚíZYoÛF~ׯà# T›½wùĐéáA[¤©H̉‚¦h›€M:$å$ươ=Èr%J¶(5 +?qIí;ß́\6®"½X`„a*ˆ)É%<¥ĐD ü¼ă§×/ߟ/Á§¥’Êèü2R4’:Eđè|½"É’ +MÖ®›„è¸ø+¯WºvßÏʛ­^—…ÛPåẸ₫üå¥\ôvɈ"&:àöÓùâĂ‚ÀGÄé+PJu”ß.̃¾ÇÑ +¾¿4üR}´»n#.5!"ößêơƯºkƯ:óÜ2Ï¥¼-P²d˜Ä?ÖE»›Ç‹³wXÀg°Đ³3Â"‰RÅ´9#‰”E I"Ư‰₫tÛ‚S ¤¥–£]8’é÷ÊæMƯúu‘å×îÄŸûĂÖ—₫×Ö"$t—„ T'¦¬àô°O¿¦É>ûeµr‹­Ăj°i]µ]b6uîC[X•´ ϼ.. ™!Ïˢ귰è₫ …{ñºĂÊë>0¢Vw÷aƯ˜ YüCVy +ÿóº-¼Æ—ÖO€ÔƯ•¢WhUVWÖ 84ܸH2“îØf±*́íJ–Bêøl]å]YWø°.ă æí®)–½I†]FËÑ=„÷ >‚œr…x9vz€©Ø„cp”jÚïat‚]Âå₫¦đZ:{›•ÅÔjµv`·dÖ²öLÊb˜;ư7ç ̃Öë¨Tˆ¦Ó^kÛUP¶l„1AÊ. $mKÀ“*$´r¬_[|ll7¹ç¦i(ØF÷¶y₫æ I…Y‡!éˆtÉĐr¸X)îå¿J(f·Eg1‰§µ˜°ùëf”"„{£¬"HP6DÚS̉#’¦‘à°‘}<`·Û±°A^±‘åX [^Úˆv–3niL*æ + &B! Ë@èÏEuƠù,jƒÉ². ÁÊ…=Ÿ{ཬÜÓ\‹ ºÇ¿¬!ºkIÆ̉xN{ÇúnâV*đaĂ·3„èm#p4Fù +„è9ct¾÷G'¦ˆ(u¤÷@¢HF‘êë„û½î3Oê´ûŒ¥₫º¾½(Đ}6¦­×M^´ûp=X½ª¡̃Đóq=̃á9”0zÿ(ÄK²V +÷’*P#Nœ}¯.»‹›v7®³¤NĂ:’úª.+½á~S[³@u<™Ă¹¹ÂȽäÁ Îáâ38(w‘,IüÙ”…Ó²OƯđ›­AàÓ¸F±¹œĐ!ß·nKŸå Uå>¹,̀s¤}úvŒ₫MßK—đ!ßK)„?Î́ÓWàP$Cj)Óù7à8z{xJ‘ âè¼hÚ$JD°÷ƶI˜ó—`¦àÉ[~î‚Ql»s7£uo¶œ"\Ÿ"]¾éĂƠ  2äĐÈ̀†úHzµÆĐ [D94ƒâ«‘Uáj‰iœçIÆy,ơÑ8ơÊ*sÍưu™¯ˆăµ —@·ÿƒâ§\Ă3ÿĂé§kukÜ 2Œá€\"̀̉¾éÖMơ¨N„h¤°i”43G^Ơ•ŸấmDä! !1¢†¡2¯!06U ô%uiºd†!¯N¸ÓH +1 ú󽡨ôLé`ŸmK¨%dS¦̉Ü›BÜCQ4!V2ºŸBª„àẺPªlË'àvçñB5EëPè]cjÀzµ-™bă$ê’)†t˜ÊPrfZÎûOÔÁl¦RÉ’KaÙ7)jÜ;3X̣¡ô€ªâ·iă„Pṃ4#B…vTŸLq‚üMéPŬ«¶¼ª +ï‘y¢â묙(Ü­¶ë£@̣e¿ÇT ´f7í¤) Î̉BµØ¡‰1…Ô…ä 1ßa×”©CơX2Ađê«ôaC‘Úg˜M›@g7*d ÖF Z*†°©đ(*ïx»G ÀCÓjf›âQPN@'Z*75yj˜ĂËDzïä·Æ–&µơD?•B:Ơ6rJ*FÍ_ï¨z›îiÔü4j₫éÜY³ü³f +Gåœ̀.´¤·%Q­N2k¦oµâÏg +́³¡_Û¬™Ñ=mÚáVÑrS/Íöăè÷`¸pĐIbÖL±a5Ï:í=#¡§™4®]ˆ ++(g£z½E•(mK¶LIÊ45Ï; k öiÖüÅgÍCø°¡æt₫ß`¤ww@JèÉIfÍD¦H÷C£‡fÍ3O_ƒ±àÿfÖ|¸º!T@ƠüYă‘ôjaQdÖl,/0Ĭy¦ÔiœÇR¿́¬ùđc„ø¹"ó‹˜ô}5̣ÁP„hrè?×ưèzF8 +endstream +endobj +590 0 obj << +/Type /Page +/Contents 591 0 R +/Resources 589 0 R +/MediaBox [0 0 612 792] +/Parent 572 0 R +/Annots [ 587 0 R 588 0 R ] +>> endobj +587 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 591.693 111.003 602.572] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000015) >> +>> endobj +588 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 265.449 111.003 276.328] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000016) >> +>> endobj +592 0 obj << +/D [590 0 R /XYZ 72 686.127 null] +>> endobj +593 0 obj << +/D [590 0 R /XYZ 72 565.84 null] +>> endobj +395 0 obj << +/D [590 0 R /XYZ 72 417.944 null] +>> endobj +122 0 obj << +/D [590 0 R /XYZ 72 403.374 null] +>> endobj +594 0 obj << +/D [590 0 R /XYZ 72 239.596 null] +>> endobj +589 0 obj << +/Font << /F46 237 0 R /F47 238 0 R /F13 312 0 R /F14 318 0 R /F59 309 0 R /F73 498 0 R /F11 313 0 R /F76 529 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +599 0 obj << +/Length 1921 +/Filter /FlateDecode +>> +stream +xÚíZKoÛF¾ëWđHåfßC ¤ml h‹Ô1‚IZĐ̉Ê`“.)9I}g¤H‰R$Ê@zè‰ËåÎcgfgf? '· N.'aF˜J0bJr O)´&IŸ÷|ººœüx=yqSIer½HM¤6H\Ï“÷©@dQS[åơºÚ¿fåÜ¢»0±¼·ate6,(fvúñúơŸ¥\̣>cD +‘Óăöêẓ÷„À'$è+¡:™=L̃ÄÉæ_;~F'Ÿüª‡„K Ïûäíä÷R­rT¸¡{D‹ÓµAóDJŒŒ‰V¹²«uUÔưMÆ'TuȉF +›$ƒ'f4e Ô“½%8# +üÀ’ŒSD„nưàUN3‚1NŸ¦”§år`<½]x®=¦‘Ô*‘Øíƒ²EF›ÖN»– œ ©$°ÂHă&@́l5 V2ĐR<‹X)aÿ¼/v^ UqÁE¨¦ˆsÚúá-̉r¾+™:‰~ùÙ’)æîLô%×µ .₫€f\ªtYx ¼¸PƯóË’Ü»'»·ÅwaÑÖæßÄEĂŒEŒĐfÍÓN”!†U³j]ÔËÛÂÆhœMUz—W +̣ɆJhĐ‘êl@̣›%·‹ƠÍ”àô¾T lä(%TW‰=€%¨i-QWSÓÙ YAÊOƠ#cß̉§‚ŒGéĂZ1s[¯†lBĐf  é媭•)†0DF9P™@tyábFáP!£˜¼]€2$IÔöϰªÇT -́n³J{=|­xr GY…wwœưà±*çëY|ù´\Å*¦ S*"]˜+׫ÇơªFN6¨.‘†Sæ’¦¤ñÔ¼›BZ1”D10؈—̣qµ|X₫ă]¯«̉=i:Ëïgëû|eĂô +rí4ă[Ú¢ùîƯ¢›Øđu‡QÔ½eD½îa¢ ”Œc–₫”‘"~^×6j¼đq¤¡Ù±BóeqëÍ€û‡è„ÀÉL†m»ÁÜúöh ©Ó‹u1[-Ë"|ª́ßëeå‚Á½=V6‹1æL̉®rú{á!rå%ßÍ ½ÀàPiÚ¼Åè?:…‹«A­`o7r> ơZ‡HđKroY¿§Hå}Â˜Ø ÷1ÄB4A<Ô +roßèMÔAØ ´Ơ’¹Ú́ºL?¸ºÜîvÁŸT!íQlëœ| {ToÇ]-oëØÛ·¯8"[ï¡₫3 çp¶R<©7®¡Ë«üÁ®\3M̉aE†lƯ¡VD́”¡Ư”µưÉs̉#bLÂ( ̉°:ø»Ó")Ö­€`1́y1¤©i{P¸̃y¬Đ~#/”wÙú‹-n›åó»)…œ4På–Exº³ẳ$øô×uS¿ éơÚ:+ÓÄÖn¼]đ}à Yz×AM<Ư +}ï9æl|ôœG¢Ê»Öú̀èÁ₫Ă¡áJtÛ̃đ'u8|ºR[?ÜØª>ÛAS—ëjfëC~=Y½¾_\ËW’Ñ~=̃û•iøđà®aÈ~¯R¸S•plàI6÷†ûz¯_GIöjWê›®Tέp̣m #l°Œsw„(¿ä«EœÂ%qPîf‘ôË +Ú´lª7|ómLuÚ”•/ç„¶%¿KBï¨0 +=L´YäH› +m*xj>”|éî"Ưß-îƒGàTOöØ3=:₫Ï#ᯠ¢à©s‹¢Ă¹˜æHĂ=¢¹­2—Ͻ'`œàÁ3Đü2^:‰í1‹:¼ùv¾MoM}l/t{Ü|²º}O9¦ăûŸ3郫¥FZÛÿ83€9€'¦ ûyœÔa?w¥íg§̃²ÈĂ5ÇOä«<¶CQYû<°ºC₫?y}ÿ¹Tă;˜ô'¢̀ŒqÔ4ßdV'‚̀:¡ +Ô—çc̀Êsjpyb–Ï!4"̀]¡f₫"=¾̀z"¿/³gĐeÚ“›»{æÓç>À¬÷̀‚ÓcfuÀ̀˜Í(l×0Óf}¾‡fv,Â,G!̀‚ü0B˜ëåçq°²h@VA»¼û°²ˆø%<»°2D¹,YD,Y,Ö4X2ôĐKî±FÜœcÇƯ½56²hAXÑ‚°‚Æf  ƒç…F od#"‚ sa‹0³ưtÀŒãK™Àæ½ÍaƯ3†É¨.LGua.03v̀˜7˜±£ˆŸ#f 33vl[̀Ø+ü5̀˜R7 +ƒ3f˜u0c÷iƒ»·îe¬]Àz~yĐ©Œ™Bô[ÁÅN©æ§Ươ¥Ó9ºƯ- ·H¿£H܃ n|OM»ëCá°B‡J¨Üº;₫§@â—ï₫8øgh¸ “"§₫™á_ḯç+ +endstream +endobj +598 0 obj << +/Type /Page +/Contents 599 0 R +/Resources 597 0 R +/MediaBox [0 0 612 792] +/Parent 572 0 R +/Annots [ 595 0 R 596 0 R ] +>> endobj +595 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 480.404 111.003 491.284] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000014) >> +>> endobj +596 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 154.16 111.003 165.04] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000018) >> +>> endobj +600 0 obj << +/D [598 0 R /XYZ 72 686.127 null] +>> endobj +379 0 obj << +/D [598 0 R /XYZ 72 632.899 null] +>> endobj +126 0 obj << +/D [598 0 R /XYZ 72 618.329 null] +>> endobj +601 0 obj << +/D [598 0 R /XYZ 72 454.551 null] +>> endobj +392 0 obj << +/D [598 0 R /XYZ 72 306.655 null] +>> endobj +130 0 obj << +/D [598 0 R /XYZ 72 292.085 null] +>> endobj +597 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F47 238 0 R /F76 529 0 R /F14 318 0 R /F13 312 0 R /F73 498 0 R /F11 313 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +605 0 obj << +/Length 1934 +/Filter /FlateDecode +>> +stream +xÚíZYoÛF~ׯà#”›½‡HÚ"u @’´D;l̉%©ươ=H“2%‹¤ä!O¤–»óÍÎ̀ÎÎ|6n"/0ÂŒ0aÄ”äRhM¢>ïùtq¾øñrñ́ † 2’Êẹ̀:R4’Ú Ext¹^Ç‘eB³2­¶å’è8ûgU¬3ôΟmn3ÿv‘]g~B¾Ê–o/_,đ,å¢× #Rˆ˜â´_.ÿ.¼âˆx}2TG«»Åë·8ZĂø +Ïè胛uq©áyư¹øăA©V9*́«}‹ÓµAóHJŒŒ Vy¹¤ƠY…–„8₫m[ƠaÔ…ö³3Bº¨’ ¨çđ~đSz)¤¸n&|ïe‰C€å¬Ñ+FN¢YË} 1k93† !(p'ăHê­÷₫`MC¢.êïÛ»«¬́ÑnèTŶ\Ù ÙïƠÑêơƯÂl6áÖyë½_±DÚ¨Ă[  ²ß­îª"I)ầxß\×W·Ơ~ÇN‚ököe±Ém‡sNăº°OËpÈyg5·G¸9Áo0f§œ#£I3‡Ñ)ö‘â¢Ư)wµLHü©^’8óZ¦e™~̣ßlDÚ¡û2KVéíj{›ÖÙÚ[yU§y]ù)WiƠ|)r?T¿Ëü@+‘‰̉áư¶ne×K*¬Ú4±zG‰THJ%.dCº]m2;tƺ²ðZ=ư ̀[ï΀0Ánfß¶0F#¼éªrÉT¼Ú{&â‚.îsï÷nn»÷ç¢̣¿́ÁxÈpÍE ‘qÈÏăµí9Ê.g|z!4s½w´†§[Aηæ€BU©pHÖT{Ư< uØÍ]Ô£ưlƠÛäi½)B5´Në4T@Kă­KPđôÿèmôư§á“™î₫ÑËG¶‚k„¥̣–½Èêm™÷»ÑHa9–³P]äEz¦öpBà‚3›p&ºmѵ3ÜÛz“b2 —ê@1 ]¸ÔÁ4Lá&2­}[‚p‚$' J!­‚)ä{(‰`%³ùæ¨R"BLu] a*ƒ¸›9‚™cƯ½/mX¬#SlƒD™b¸ +́#§¶í|ÿ‘z7¿Á/. $åÚWªÛÖ3xåmÙÅw~̉ΡÖn{”aA„" +*tj“!IpwSÚV0Û¼ÚÜäYˆÈƠRÅï̉r 4`)­×F=àËf-—ĐƯVƒZđ€™¤…îj±Gk +Ѫ 77¤ÅƠ»¦Æê‘0Iü‘„ yŒ>¬-P›ûe×&±N+H/aí$ªD1HpPƯQ{‘†zùǜ[SÚ²H"£˜²1#C’mÿ(n̉3“Î,íôl΅¡ö·TY¬·«đăĂ¦éæ«ÍÇp›më¶}m}©]º”4p6¯àÀÙ¤‘M»²I\Ü×›»ÍÎ?đÓ߇$nkj¿$àÂô­…ơïi‘ú9 'C¾–₫¹Èª…ûÍȰFǛ±ăă½5®Ê¢ +ï BÑágû€¸~À’đ¼Ø‰ÁĐPĂ›~§ùÚù-ÂHÓw„á̀iăFºí„ïü¸³9̀óºg~0¨ ĂA]ó‚„o_Ü@ ç,₫)ÍĂđyë;rí‚Àu´fÖ(¼̃ä7nç¸ß̉d¹åÛæ«P-Á§2ûw»)ÓáW·)k§8å­8ÿê8)ƒlwD¯HŸ́8GIñ§U*˜̃:¾´:·Û)¾›t; +«¼;àÅG‚}ñ¾§¦Ưµ!X¡P% F/ÆÇÚ)­́%k d÷rq¾Kdƒ©BB·å™uˆc§ªÑ¸½”Û[àù«¿è£}¨Jƒ̣×h§*ü¬”1ƒ««É•̣¼å®Obj$¢SÆŒbd0}0:Ø&ơ@¿V˜ÑƯÖxkôƒ–2Zœ¹̃Gæ.Y‚2¶×(thGPÆQ‡Ă¨‹zÊx¼z}¿Àruxùa¿Î[ïüJµư»;eL ô~FEOƒôköeüÅ)ăÑ®́Ű]ÍÅt&qæz¤FÔ˜“PÆÀ´–ÇqƇAøóÆăƠí» +–“é³Ú»Yd¸8 aL…A¢aÆQ‡}ÜEư²„ñømô½'|Á=ÙûăפŒ)…óCÙWB›ʘ琉¡—²u«fl6e ơ™%{2†»â°–3†̃ƒƯÏĂUs +PËsÚ}‚3Óg"S¨Ú,×C®ª̀»¸¡‹Ơ>ºX ùĐ|́§‹•ỎÅPA3> endobj +602 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 367.478 111.003 378.357] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000019) >> +>> endobj +606 0 obj << +/D [604 0 R /XYZ 72 686.127 null] +>> endobj +607 0 obj << +/D [604 0 R /XYZ 72 667.868 null] +>> endobj +396 0 obj << +/D [604 0 R /XYZ 72 519.972 null] +>> endobj +134 0 obj << +/D [604 0 R /XYZ 72 505.402 null] +>> endobj +608 0 obj << +/D [604 0 R /XYZ 72 341.624 null] +>> endobj +380 0 obj << +/D [604 0 R /XYZ 72 193.729 null] +>> endobj +138 0 obj << +/D [604 0 R /XYZ 72 179.158 null] +>> endobj +603 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F73 498 0 R /F47 238 0 R /F11 313 0 R /F14 318 0 R /F76 529 0 R /F13 312 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +612 0 obj << +/Length 2168 +/Filter /FlateDecode +>> +stream +xÚ½Z[Û6~Ÿ_¡}“јáTh³ Åî¢Mû’f ,ÛÊØ̉T—$³Aÿ{/²%‡vÆ̣ O¢( Ï磣U„£—WaF˜0bJr O)´&Q Ÿ|zợêÇ›«ç×0• DRƯ,#E#©¤nÑ›X 2›Să¼N›®çdƠ"Gk7]lr7z•/s· ̣̀ÙÛ›_®đEÊEoæŒH!bJFÜ~º¹úóÀGÄé+PBu”m¯̃¼ÅÑæ1ü}°«¶—›èơƠo;6nïê`ïB#"ữÿ;#„ÄyÖVµÙ!‰Uk4¾¯«E—µn¶ºo‹mñÿ|á^ÛÊ=³t“u›´ÍIS|ôË»û®mÜ8ơ,R·øäh»fñ?«¼9 |yư;˜[<¿&,’(QLÅÖˆ'$bHétÿŸ[6ÚŸ@Zªh>X¥# ï­×0««Æó4[»ÑíC¿­jéw½¶.î„#&t4'%B89E {†… ÓºǸPÄi¹psn‹0“UeÓ¦¥_ÚäV ˜·R`&«̣åŒøwŒiVä¥ûÎÍaÓ=w“^]˜öêœc$¬ºn¢k;ÀꜳøEZz +ÿ¹k¬[afiƒÀ°µ‰÷ +/rewÇ[†$€,UTûÂ`‘ÛÔc_weÖUé>ƠùŸ]Q[§ĂÛ}ÏûÚ-±Êvî!}$đ‹)Sˆ‚*V° „G‰̃­a4ÀÅÎạ́~“{½©a4đ¥ÑÙ»Ư,IQÍ<•s \$˜ó=Mv»v1dcŒ +…¨12øç±ÆEÈÖ Sŕ +̀AéR…„Vß+ë[ÏFîyh +ѽE^¿₫‰#rP©0Có0Ô"PÏ9rù#â^…_gÔ$LºÍ[SYIV$,àđëaÙ +'˦"HP¶+OIH’D‚ĂFNñ€ƠÎÉ…­Ú ,GÀbØ̣‚³hg9ÆT£MRÅT¡#gˆ@ Ă‘ĐååªơÇ¢«‹xW3qü~FÄ₫0ÁÏîi2¦±UÇÿîÖÏæ>/ÉPª$ˆbÑÇØ÷´T=» üÎñ"}n Ç(Ÿ`q9ctz]F&ˆ(uaAç¡À¡Œ"Ơ7ïO†Ñ4©á0JưO·½ÍëqOSuu–7§üz¶zc¿P í…î×Ëè_1‡EŸ̃…ºI»•B~Rê`ĉ³ïjÙ̃nă~$5́ÖÔ_«¢4ỤœÚ~Åty¡#œ›~ÄáK¾x„³s¸¸#Ü(w;›“ø¡AĂç´ôg·ùfâÑL ûs˜›oư߸%₫˜·T¥›²Ç¼™Øqd#í[DÇh’ÏƯ‰/’RøƒC>œçzrÁ@-e2=.£·ÀŸÿđD"‚}46ơŒ©8;³`$øßj۽ˌƽ9øÔW¸₫¨t=úQOŸ¯îÈU† ædW_Hï\­1 ÏK[!èŒ94³m€µø"oÚă~&5́ç¡ÔGûÙ¨W”=Ê1i›úhFqÜÙR°ºS₫?{cÿ)‡x&ûÿ|úpÏn;Â@†1lK„Ỷ#“¶«ËG¢‘ ÔM ä̀‘—Ué¯gNçaLL ¨Ưm¢Đ‚ ±éJŸT…s«e ̀˜F’&Ó ??Y |JvöùÜ:E ­6ÓiîM±ÍÍ}S(¾%|úrE‚4NÆr³´Ëf*^›¶́ÄCEĐB~r!ÍG̣·i[÷PÙÜ +Íæ\ȸ+›bUöàÚ*˜Ö¡æ€b +tjta±[“>s+ÆAë‘û;6À…Đ!›m GX=†Í®+º pIÖr¿%1Æ̃i1§úŸSXoÔ—y™×₫ÂǾ½O¯gàe÷º3ü °o¥%îÖsô—I0Zö}¼½%*ÊÚ]!A£C=æ|/3è̀ đ>¦Û{{ùÊưÅ–ùàºÙ f0ÿaÛ, X«µ›¼¯j_…9óü†By\4î[±NEPëg7åî»`°©ŒôÍÀçËmxm&û[h"ë.k{S¥̃˜ä¹‰ó½|ăïz?ß”î‚î]đ*”LöLÿáạ́»g¾ëøö~v7'ùéo?Ư=Û«Çê?”6ù}·̉ƯÎC¡ñå jÖU·YŒ¥(g¼Ç|u›̃nrtÆMR¢‡|S ßéW¸Ib*/¤·íƠQÆ/kŸà¨£ hB̀Ùá +ßÑÖi¢Ä`ë4”øfûñî­}Ơ×’uƠK ·öGçë:r!ÇlúUá…ôÎÁ +?}¡1À)@ä;íqÿNvïPb¸̃©]lÆ7ƒĂ2‘Uu7÷Ué‹û)ƠY3*‹÷imª³ñ‰–ù́í= +ÔR“éq½‹É`º8å¡M£R!BØ »‡Ä4‰á˜ ÅDVmºm9=$Nù₫́}Œ' 5ƯùçÓŸ —(…„Ăü2¸DŸ +.‘³á‘ ?áO— +JÄăà̉SÈơpi$wĐrŒÅJ0´ẈR¹Öơj,÷+Á$ú40‰%˜$“ X1•8˜$N ¤¯ ‹Üß2cäơŸ¹Ræ{ ̀x„s¿!Û;td̃B +ỳĐ¡#Ăb‡]̀tÏo(´đÔ{tdȆ+~v‹̀`ÿØËS·Âctd&Rÿ!ô¯‚ó§û¯ñ¨…øUŸ@2($=ç“oïæwßeù}́!•yB* ï/ª-xtóྺ¸`Œ˜·ëÊïØÆˆµÅºªçKuÄ—Êœ§₫;uù‹}Hà¿CSÈ¤Ô +endstream +endobj +611 0 obj << +/Type /Page +/Contents 612 0 R +/Resources 610 0 R +/MediaBox [0 0 612 792] +/Parent 616 0 R +/Annots [ 609 0 R ] +>> endobj +609 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 591.693 111.003 602.572] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000017) >> +>> endobj +613 0 obj << +/D [611 0 R /XYZ 72 686.127 null] +>> endobj +614 0 obj << +/D [611 0 R /XYZ 72 565.84 null] +>> endobj +532 0 obj << +/D [611 0 R /XYZ 72 417.944 null] +>> endobj +142 0 obj << +/D [611 0 R /XYZ 72 403.374 null] +>> endobj +615 0 obj << +/D [611 0 R /XYZ 72 312.543 null] +>> endobj +531 0 obj << +/D [611 0 R /XYZ 72 201.31 null] +>> endobj +146 0 obj << +/D [611 0 R /XYZ 72 186.739 null] +>> endobj +610 0 obj << +/Font << /F46 237 0 R /F47 238 0 R /F13 312 0 R /F14 318 0 R /F59 309 0 R /F73 498 0 R /F11 313 0 R /F76 529 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +619 0 obj << +/Length 1605 +/Filter /FlateDecode +>> +stream +xÚÅYIsÛ6¾ûWđ(M#;C{èLíINmê·CKÅZ"].µÓNÿ{!J•HOzDâíË÷áè!ÂÑÍF˜G±Xr «J‘¨€×G^}¸¹ú₫öêí5<̉HK*£ÛMÓH*b£Ûu´œ Dæ *đ̀IYs¢fæ·U¾6hë_§;ăv̀ƸÙỀïnß_áIÊEË#Rˆ¥·n¯₫¸"°Åqú +¤©Vû«åÖđü½å§UôÜœÚG\*XwÑÏW?ulœíñíB!"½íÎdkÖ¨|föŸƯÏ)Ơ•{µÎMévY^¹÷uR$YeKZOI‘VŸÜĂÎg©'î¹HÚMÿØ/×ĐÙ/¥)ÊV/ÏüyN0ˆ­BÛ“ơïuéÙu!x´V¿½&¤—\bD…͵Æß¹#Ả,Ú3·:(*́Ö.7vB÷9`¤µŒ”!%‰£ÿqN­íÉ̃T¶¦È¬ ù®ÿĂ·_ †ª&́dÁÄ ʺ¢yMzD´„¦à-}œvu,zYÏq„SD5^ î=Ÿ4 +L&d±"ƒh# Û@ärỵ̈xçz`RMêÁ¶I6X·ùnív«ÜllÛ̉[¥&«Ê/uœ!FùeƒỴø4ùÉO¤w!VĐ̀±˜b¬8°¤ÎƯûă'q8Â}‘Y½¿7…‹b¾qk‘ÛX>—îWÓ¼`í:bï¢0åSyÜè%EY¬<á7nñ:‘ÛÈ9–ă“b½K +©n9µîDd)¦\„'Å8‰ĂIÑ9”«|Wï³ñ9q*øÛȱ ăƒ9ư0:5̃ È0TƠιLUÙ0êG¡kÀ_Pµ›g~=‰¼$†I—†ÛLQƯÄ‹Wè|A0†!/+Ó‡̀ØNƠl5gÛ¤p?6IÇHq¾cØÉ + ^éÎY_º…@¹)œ̉̀»RQ~ù±Àọ́ˆ’ͰÓ½FXvăLâNBဒí@‚Î>`PÇ1̀.1îuü2»ư&0;³7Íø?n®­ÆÔÏY,²´¶˜6‘b1$‰ÇÔ_F-óÈêR†m±} KsÉüß;ö“Ø MÔWÀ8¤*Óăkq"}Óˆ¡‘# +^¯1€q ¤ü¿°‘";q ̣]öTWaÂm£—+ºÈ1SăCw9ư…m”Ù·2±^§¦^ƒJ¾÷ˆU¯ü-@µMü«Ä-/ÁÁoỰ7ùgZSf¾)§"ÇZ0£€Tà ¨˜Ô‚™@˜S` AEĐƒ-ô9«†̉, ñ«(—1‘¡Ư@ÎF>Ik"ß»àj"¨‡₫ ØÎ…ÇñbÄ¡X¤“gá¡́ăáùȧ5¢J6È'8ÿ +ÈG…„ïÊñÈ7‘¾A>Ê9z"̣1H +úp…ˆâ]c8}#eBß̀ú|E¾Ëu]äö́èĐM£w¡ƒª£œM ¸Z…̃ăuÛc‡nœ̀áĐ…2CwT—ivàê¨ïl]¾ó¿¾É¬­Ư%ë9¹q±‘al-äBÓè]n"¨×¹P¤”!ËV gÆ(‰Ă‰Ñ—X¦™đZ¡ŸË́’áx$/U* PKMÆ̣rú Ç[¢9̀LÇ[_‚¸«¸•)ËM½{ăƯ^mÛ‹MóBºó/> endobj +620 0 obj << +/D [618 0 R /XYZ 72 686.127 null] +>> endobj +621 0 obj << +/D [618 0 R /XYZ 72 617.267 null] +>> endobj +521 0 obj << +/D [618 0 R /XYZ 72 506.034 null] +>> endobj +150 0 obj << +/D [618 0 R /XYZ 72 491.464 null] +>> endobj +622 0 obj << +/D [618 0 R /XYZ 72 430.546 null] +>> endobj +533 0 obj << +/D [618 0 R /XYZ 72 342.337 null] +>> endobj +154 0 obj << +/D [618 0 R /XYZ 72 327.767 null] +>> endobj +623 0 obj << +/D [618 0 R /XYZ 72 268.906 null] +>> endobj +520 0 obj << +/D [618 0 R /XYZ 72 169.442 null] +>> endobj +158 0 obj << +/D [618 0 R /XYZ 72 155.701 null] +>> endobj +617 0 obj << +/Font << /F46 237 0 R /F47 238 0 R /F11 313 0 R /F59 309 0 R /F73 498 0 R /F76 529 0 R /F13 312 0 R /F14 318 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +627 0 obj << +/Length 1839 +/Filter /FlateDecode +>> +stream +xÚíZYoÜ6~÷¯Đ£È2¼‡HÚ"u¢@’̣Z¶¬%G̉:Í¿ïđVZK²Wró”'rErføÍp.,n"`„a*ˆ)É%ŒRhM¢–G–ÎÏN~¸8y} +Ÿ 2’Êèâ:R4’Ú Extq½"«58Nˤڕ+¢ăôŸMq•¢[ÿư4Û¦~v^§~C¾IW/̃àEÂEï׌H!bÊzÔ~¾8ùtB`#âåÈPmîÑÄÑ|ké}v»î".5ŒÛè“ß÷BµÂQa§vˆÓE„ Œy$%FÆT̃­(“2¹Kk{eWưûN²8\}t!₫S÷¡eí^̣<"ÆD’3$† °› #D á€S¬áQ̣p…¨Ö!—8 zW&x¹,¹ê² +a˜öX₫ºÛÖÙư6Û$ù•·Ô!pg”Ï¢½%#ç«nÑq¯9FẠ̊e4Ç8R0:/Ç57å°æº,kîrBsGKчÙw¾@uÇŸ?̉ iæ¡9Oë]™»Ch5RØDk1 Ⱦ+‹«Ư¦ö ×ͳđĂl7d¹ÏN?`©eùú”°H"£˜v°DX0$Áƒ¿ư¶ i©¢ug—Äß¡‡ÁkÂI wàÖàTØ©X­ Æ8~°>¹È¬́ØÄ7׿Ê4â€# ›̉E¸á®µö"œ N ‚‹7Aá!@̃ˆ†Đ&^„«$àxŸëU1ÄTq$åË\U)ɬÏô‚ˆ‹€µ5‹ƠCäỊ̈Úë]us +fÀđ8đpg·i₫Êoêó˜ˆj6 "a)=#”(;#Í®]^e7yDƯ¬T|›”Á†y×8á’5§>`̀4e{‘›ëúrEp¼­¥ĐHr³\I,¼…¢*WÇ›\…Rÿ?WiUÁ€ítO¨yîĂ®jÍ¥@Ê­)G,øˆq·C‰MבỊ̈:²ëuœO{°v ï¶(ưoûÜä̃;ÈW₫W ¸çx+÷e–Ôi—BYeE,wƯ>¸ ix0?©%À©s²œMÜJ`¤ÀÅÍô¥‡¿p¹oƯ¼å¼)‹*H‘&›[¿ạ̊‹» |sa¾Ô·áC–ßï³e™|ñË><47¡ñ¦È«:ÉÇ*­ûÔ6Ez½¢ÂÚƯdi^ êÂ^ÄÔonÄ¢^,§ÆuƯiDƠq±«AV´‚Ç?&¹_¾ «»ÊY<|¹v†‰/gÂ:Ô3Y~r[Ưøy¸ªăv%'ºË75¨Û/•é§]Vzí¸Mº̃$ÛÍn›4[LV{ÀL̀èÀƒă`5tàÁơ”ÎÁWÓ®û ×l±â6"´VGAÖ€ƒ&m|O<.61̃ꂾ×=LkĐ:&Ø\Üfá\ï²OÊÖHwY†ƠÏ·IƯđ¨êr×Ù +ÆÓ<³2È‘æÉå¶‘²ÍLªt ¶:yêm†uûë́.EUêT +b«? jM¢¿BÈ!Œ­fç£ Ï»Z‚[³eµ‚XZÖW™6­&f2¬&zLIó›ú¶Ỵ̈‡3 ¬×>®*¼ü_wU0 Ë4¼arŸQÜåï^°BëfĂw£h¼ª9¾`ƒôôñi+ZṽYƒºEª…½($$ÄRv<à˜Íä:lF]®¿íî.Ó²oF‡ÆS»r“Vz=^¼^́q®g«uÙq¯U-à"b™VÁ› +¹ÖàUé>­̃VăzÇwP¯=¾ï +(:œb)óÙ Œƒ±24ĂéŒXMÛt fM †©3#ˆ%ỨÁÅ<ÊÚè]…ó!fÛS¤]ô˜6%µy–J!­x¶=ÉÇŒ ˜†zÎÆ@@P}Ή­ư₫ơ:ÍPÉÆ¡Q„zºj-ë©f(5äÉf(Û•í?u¢ư§!âÉö_‡ÿÍPƒ0çË¥o†REŸ× 5ûGÉ!Ÿ@c îÍyØ^ïe¬+JĐ¾!₫dS|§fÄ7E¹9¢+:«øŒ®èP£S,itÎjß~kt~kt~Fg'ƒ°ÑÄ₫iÅMÎÏÿ<ƒáM($´j²‹˜ûG̀³Rn£OÛzóç_“{üIMưÛË +Oơ +endstream +endobj +626 0 obj << +/Type /Page +/Contents 627 0 R +/Resources 625 0 R +/MediaBox [0 0 612 792] +/Parent 616 0 R +/Annots [ 624 0 R ] +>> endobj +624 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 157.861 111.003 168.74] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000003) >> +>> endobj +628 0 obj << +/D [626 0 R /XYZ 72 686.127 null] +>> endobj +629 0 obj << +/D [626 0 R /XYZ 72 667.868 null] +>> endobj +387 0 obj << +/D [626 0 R /XYZ 72 567.305 null] +>> endobj +162 0 obj << +/D [626 0 R /XYZ 72 552.735 null] +>> endobj +630 0 obj << +/D [626 0 R /XYZ 72 434.341 null] +>> endobj +373 0 obj << +/D [626 0 R /XYZ 72 298.401 null] +>> endobj +166 0 obj << +/D [626 0 R /XYZ 72 283.831 null] +>> endobj +625 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F73 498 0 R /F47 238 0 R /F13 312 0 R /F76 529 0 R /F14 318 0 R /F11 313 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +634 0 obj << +/Length 1835 +/Filter /FlateDecode +>> +stream +xÚíZYoÛF~ׯà#D›½‡HÚ"u¢€“4E;d̉!©´ù÷=$seê"•´y"ÅƯ983œùö³qrŸàär‚f„©#¦$—p•Bk’Ô°¼céêṛƯơäå<2ÈH*“ë»DÑDjƒáÉơ<¹I"Ó8-ê¬YƠS¢Ó⯼è½~±X₫+ü†2/¦ï®_Ođ(ç’›#Rˆ”̣HÛד·8!̃_ ƠI₫0¹y‡“9<mơüív=$\j¸.“ß&¿>9µq +{k/!"Ât#BÆ<‘#cBT̃L)O³:{(ZûÊ$mâ÷Ưkb{ơÙûáâ¿ï}À)AÙæÎ)ˆ1‰ä ð› #DPá§X'p„ „.…¤ÖEnY”.TÑKVÅP£\u +…0ÜFF*Êû6Ôkuê9ËĂ“S"̉"o«Úÿ^”₫zû©-4…"ÄéÏ«¦ O]i¿¼ ¤kUD±÷œ½oư–È1…×ë ßx]D¢çÁFù€hÄU`ƠÈáE4JÜ׳A‘#k‚‚t2”¡>z÷Ñ0«ưEÔµúËêᶨă"Ú.¦ZƠ¹-ƯY=Ù½8-̀v£i'ïóJ4̉‚Ë+…ÁBU")Eœáû»övÙ́Î́0»ư™íÚ}S-ÊÖ¥–²´­ü•Ñđó¸€Àéú+~‹1ëù̉92z³ÇƠªShÛ‰¿Ëê:ûäo]!Á,y¬‹Y-óƠ2k‹¹_Ë«²i³²m‚|Ö¬Wª ²}¿­‘ ºØăª]+*î¦TXi¾(@ă¾=9Êq¸lx“÷%âF^5HE Ÿ̀¦2•æ»+t˜á₫ +í~̣Ûi=¾hÿËUí¦­çTÀ̃TŸ́nœ*§Æ Oơ8y—ja8Œy12ƠĐ’!ÂÀŒfÄG|^ÀÀß•çV{óY}êDœZWeÖ.ªLæY›ù;ÿƯK‘îẸ́éÎFY†Aσ³<@₫Dd.™c¦ôUÑ®ê²og@#…M2ƒ+fA¼¬Êpt‰loÈaÉŒÛrP›“¢ˆªéŒ`l¡mÆ ×±5Œ¶bbĐê ócçÀQ)fŸç‘ œ In ̉Œ…ɸ¤¯‚5RÅ(€^EYW}F‡™"ÎbT)¤9‹>Ö‡UóËZl?‡e°ÈÙV3{øûøơY~‹θPĐ{[ T÷pÍ@Rl€ ^øM±¨ +º9Jô+"PhBt1FŸ&Ê‘s«²YÜ—E(È|ª̉÷YƯ‡qàsàâ9ƉP]û·Má´lz½ĐĐZäx/vxbCÁ6êaBSœæ;âª5ÿ,Ñ€>½Ö6×Ge,”–Âó÷áU5Ô«ăơ¼ú‹U™ÄKuñaµ¨}vMtX [LđVû€™₫ă‡ªqs₫Ôă“}ÍM¬¸Åk„ÆÁê$hƒ‹<_M:üäºFÈ₫v×é CØqb Kwsu¹Mœbø&Z­qˆ˜cC#ÜŸM¯~ơût‹AƯGéhm38³(®¾EÉô;=wÀŸq ÚåYJÆz˜ h´÷GFÿ¯%£{§G#.Çt8•5R̃W€­èY(JÁâÂAQ´Ú_F]«ç¡(Ow/Î ˆK5œ)ïóJ$DŸ…¢d#‚ÅQå@»ư™íÚưJQv ôä(Ç⌠ç­FÊûÅÎfâ,%ĂĐº9¢h¸¿B»†?Eyº»qª0 #9œ¼)ïRM AOÎBQR#œàar Ỡ> endobj +631 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 391.388 111.003 402.267] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000004) >> +>> endobj +635 0 obj << +/D [633 0 R /XYZ 72 686.127 null] +>> endobj +636 0 obj << +/D [633 0 R /XYZ 72 667.868 null] +>> endobj +388 0 obj << +/D [633 0 R /XYZ 72 531.928 null] +>> endobj +170 0 obj << +/D [633 0 R /XYZ 72 517.357 null] +>> endobj +637 0 obj << +/D [633 0 R /XYZ 72 365.534 null] +>> endobj +386 0 obj << +/D [633 0 R /XYZ 72 229.594 null] +>> endobj +174 0 obj << +/D [633 0 R /XYZ 72 215.024 null] +>> endobj +632 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F73 498 0 R /F47 238 0 R /F11 313 0 R /F14 318 0 R /F76 529 0 R /F13 312 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +642 0 obj << +/Length 2018 +/Filter /FlateDecode +>> +stream +xÚåZKsÛF ¾ûWđ(M£Í¾‡t¦McO;m’Ú¾%iF¦([­D:$•L₫}±J\™’%̉>tzÚ%¹ `,đNnœ\œa„a*Áˆ)É%ŒRhM’>ïùtyqöóơÙËsxe‘T&×óDÑDjƒáÉơ,ù0ˆ'TàÑíüó×1Á£,­?¯ÖKtç_Ÿ/–™Ÿ]fó¬=Ệ4º₫í ’-ù0a2¢"¢öæú́Ë)NˆW Cu’®Î>|ÂÉ ̃ÿfé|s«V —ÆeruöçV¨pTØ©‚B„i+„ Œy"%FÆ¥¼S>–ÓUVÛ#“QŸ÷ ‹Ư¯Î#„Sÿ¡ó€P‚²Í™r?"Æ$’3$@ hÀj‚Œ„Sœb-Å&v´"`Z§¹e–;UE‡&¸¾L¹j3 +a˜FLỊ̈Û:øk1÷c6MĂđja½º(ưó"÷ăÍ÷:«ĐxÂÀéÿXWuxë\ûå9!m®’ ˆçøưè—D‚)¤¸n¼̣´ˆD•!@ Œ̣Úˆ½À’‘ưhĐvïC̀*Eô! +̀É8R†zí}=èDư¸v;Q›ëÛơê&+c'ÚuªX—©uưV=Y¼Ø,̀F£f¶ßÙUhŒ~äpư4%ûíJ"T%’RÄ™ñ¾×7Ëj¯e{̣í¶l›ïûb‘×δ”êÂŒ†{Î[ÛäN›[ücÖqÓ9H¹Yă|Ơ´áÄϦe9ưî§Î‘ —Ü—Ù$.ÓơrZg3ÿ--̣ªæuöO«æKHÖw»y È Ư¯ë†P6Saå¥é"ÎA“‰°‰“'ço!V¾Ë—@‰1HăËl•9öö©Sà˜é#ôA5¯ß½½ºî Ä¨Mü§PúÛËơƒˆ́éíXß-‚ÜA5~Ù‰­A“/`*ñèÛ]æßê†à+?|Äă°ˆ„‘"„à=đ +̣>óKư™Üt1XÀ*•»#MÂmvB{‹i=Ê›h¢½ĐvÜ*Ü>¹4¤ơvKcäÖÆÈ0í2̣„ƒC\7ûc̣kïMngYfƠ}‘‡gwc{¡(·‹|ºl’¥—¦{ܬ;~™£8f·+­zÇÁû}T›Œ‘,8B”„xT•cp̉t ́Ǹ3FŒ +ÖÊp÷>6V₫ɹÆ&ϵ<à ©O76lç¬?¸ß›ZhDƠP8 ™ßª°¢–!ÚÎ2À•{íÜk·Û\· ¯eS+ +ÜëzQü;›ÖS?ó‘GÑ!+Ÿ,ll%Øu#Ÿ¼ưẠ̈OP&Q^—Y½.óîoWÿ)l ‚‚|pÜö¼ÈC}ñ̃a Op[+"³¢‹%2íVgª ï(3½/-Ö/fœDÜ-ÎÙH*æ\U™·¯…$Ó¥wµ‡GªƯº\"äyđ|áÅ,À!ÉDu"ÖÅÚ¶‹eà¶¼YµÎ«ÅmOLÇjt7-»´FŒ⼈¿BToøÛªÀö–U§á-"ï/ÅI¬&ÔF[˜)àœ=j5êY”1áÄ@ Q1 +kÇ®:b-‚UÛ1j'6M$F‘d±ñ€.έ›5`Ÿ%ÎßÓÆ°!I‚u`tidm­̉2wƠËö&{˜Q³uZ‡º„J¤vP̉@å—"³ „Ó‘MJœª4Ó TÆ‚/p ‚ÎiYTAĐ?â›Ẫ9ĐÄ›º ^4èØî Ø +>»Âasº)ôü×*«cjqµÿî7Œ^Ä̀/nÄ¢^,_æIP#ßAñ¸iD…’b]ƒ¬¡ƯơzûÏ7ák¨àÍÜÙ&Y9­Öeø³E~>äđ”ùy8ªµ/ùóuœŸẾËzQzë¨KLV{…™îZ”ƒ×¸ü~jmn¹Ñ·(ĐXY-mĐo†Ü怼B«Œ¶ØÁæÛ w“Ë‹Ư¦<”`TA"Üà«1×j? +„p›w6ÅơƠƠHT; úC@Ñà?_TÓR}Ö8ƒ‹/ |ôEƒ÷;Èϰx¤ztœaH\=̃ïdzïG<ÿ“ưï“•»́©ú»Đ°ưÎ…¨a5[n€S™Â°#à=¹vzQÄơià§‹Ù…4îßø¸ßÛUÛ_)6~BœjYë¸xO¾Ư–móưŸ6À÷8èÉZ ¶sÑ¿]5p¿wP©¡€3Ỏ™„̣êjy\g²'ănm3~ÎäéâÆ¦‚íư3̀ Ữ̀ö÷.¤+I…A‚Ñ#º’=¹vÛ¸Íơ9º’§ ÛHxÈÛÛÆ§ï?±/I¡*×” ëK̉Çû’Ķ$“̀Àía­¿ ¹dg̉₫&àDÍá́‹æZd-öĶZ¤q´8l<Ô†´^ ÈÓ°å +€˜ˆÙ®,ü ÿ…¢ºù/̀.!á((‘üj·£„£jË;ĂB°ûƠ^ƒ¹íyM›PÖ\‡y¨œCÔ›7¸k‡ÙÖÈͲHÿÙö^Vëe½¸_.̉Öej ₫¦7…{6}P‡7í«ùÀwÔäèqEDÿû.Óđ +endstream +endobj +641 0 obj << +/Type /Page +/Contents 642 0 R +/Resources 640 0 R +/MediaBox [0 0 612 792] +/Parent 616 0 R +/Annots [ 638 0 R ] +>> endobj +638 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 355.522 111.003 366.402] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000002) >> +>> endobj +643 0 obj << +/D [641 0 R /XYZ 72 686.127 null] +>> endobj +644 0 obj << +/D [641 0 R /XYZ 72 667.868 null] +>> endobj +372 0 obj << +/D [641 0 R /XYZ 72 496.062 null] +>> endobj +178 0 obj << +/D [641 0 R /XYZ 72 481.492 null] +>> endobj +645 0 obj << +/D [641 0 R /XYZ 72 329.669 null] +>> endobj +479 0 obj << +/D [641 0 R /XYZ 72 193.729 null] +>> endobj +182 0 obj << +/D [641 0 R /XYZ 72 188 null] +>> endobj +640 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F73 498 0 R /F47 238 0 R /F11 313 0 R /F14 318 0 R /F76 529 0 R /F13 312 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +652 0 obj << +/Length 1944 +/Filter /FlateDecode +>> +stream +xÚíZKsÛ6¾ûWđHÍD㇧Î$Óδ®oI¡$Èæ”¢’Jfüß»xI„L)’lO›™€À»ûa÷[JQ\'Ø<^aÓ4O„a†™™€§àJ‘¤13‡_]¾:{quöü†r” *’«y"i"T$É’«Ỵ6åˆÆ”ăôz₫áÓˆàTO»‹U…nÜđEYi׺ÔsƯŒˆJu=Ơ£÷Wox¶äí˜Qœ“”HÚOWgÏ4qBÜq9Ê©J¦‹³·ïq2ƒñ7F^®’ÏvÖ"É„‚g•ü~öÛ̀g Àó„”sNƒ¸BDx \¬êiW.ë6ÖÉ?Á|²g>"PÆT2¦ Á€w”̣h-hÆ1N˺óĂFc ÛpªoL΃É?´­̃–c¦½ĂY¶Séú™k­ê¶¼®ờơ¦7Ec?¿ÏöΫ(8wTŒ™›i•¡\‘0çz̃M*¿Ç§Å鲜 HÎR˜ ˜†9m3ư¶X&Àô±3Ưv`"²Ă}’% +oÏÁoœ#ÁX2& #óxuaLLưF,¼Ié̀—£Œ’Ĩ»¹¸Y‘T2™'ẵ,eätï.×'wåmơÅơ&₫9́uEƯ¡Hƒ-•Ç™D<£ppp('Œ¼Â8äÓ_>°2; +$ß úȉè“HdüôEè{tÔ ¤ÿ&êÈñ¨cO‡:¦"̣?‰:oœëZÅím3Êxº¼mÊ¢ÓA^c¨I Yú˜̉ư0í;äđHYÖe· °èt­cĐK©®DFïáp èáđÔ*‹ªüÛ[œÑñäK0p–÷PÓƒ̃“óàè=ˆâ@Á-)ÎÓưx ̉=vXÜ: “â X[¶0lùđˆP#_À5Ạ́´8vĐ2C"ÏŸŒÅ1 +Rxö}D4ª¬w†²¨^Ù.VÆ‚•àT"J®K6Ç"0ûRwThÆTA¯6å­©fö] A C,ËĂƯït37§*¦æ”J¦Ử=çëÚÈu­  n@èËOªåôOo1̣V*§…=+íSÄ®",à*¨ªLôă)°C‚đÈW‘)Hđẵ,ë+4ƒ£Ó«›² ç´̣:Í´éƠÚ¿ênt8ÔNơ›åª+ư +‘®Zkg§œÉđ987¡ÔxL¸“8Q­¿ù—?¾~é¡'&À¬ÊÊߢö ƯíªY[¸ +‡@ßGơ¨%­GÅrºZèº+îáb`ƒ(±̣׸s‘ „_ϭĨh'â §0"@w÷Tî–U¾®ƯCµ̃‹„ #@ƒ„‘̀Û×\Å=!ơ›ù{BºÊØÖ® ƒxàªViƒ^€ëB(1¡3YLJ6üí¤xÀÎ:üơ¢*ÈŸd:Xp8#÷k´½FäÀ ²:88Ă*L…˜í ¨pXEóöe›ŒaĐ>Ư¡¹’O³«I#CẓFÎVÙf ŒpÄ0‰ñ¿'fó‘ëă^<=4Ç„ÙÊkÖYTH™DB ¥>c¾\ÚĐ&EZ˜ߣ#ÄÖŒ̉Ctƒ:‘Đ7•Iƒ00qÜăÜŸéó¶¡1œRø¸]¿oâK»5éÜM*ÛHF[Ö×61À+“tå§ëJ›Xé:6_É}ù ȹ<Ñ0¯¤“óÂï3ÑÎYåˆ]̣O?0mLh’‹0M¹•]ú¸-Cí]çsSZŒÈ^n·§Pư¤ưqU62½môxZTÓUUl¦,ç‘I¡dèOZ´aÀºÇ*ˆ½f̃†!ÙẲÔÉ&ư’FÏ‘ …>°¢.4ưz₫ă»gn'h“;ØÛv@€¤_1 o2ƒă7³çwNJ˜²%ôÚï–3Çwî w₫ÍϺv‚74Z.| …¡ÛĐlKHlYö­åôn²g<¦Ûxz3 Üfá) ô?ß~›́Û¬zS[Ư…h¨ˆ®‹I¥·Ù +°Y¸Å~®cQßA~F·[]¹Đèp&2ÆpÇ„¡[('Êiü«ÉES,Œ†#B̉áÏ÷Ặ·ßnÿä Q•íưÉAÄí‡uG#s="P;ÑŒ 5{D`ÏûD*>yâ[QTürÍFØĐnˆL§íÿ@Â%ÂĐŒö„kpƯù”lÔHye’]§mHỊ̂Ëq·"Ö‰g 1¸ G+»2đAv? +[ï @2¥́ƒ°%3乄2pÓ͇£Ưh8mÛa8ô·ưuik®m'ö¾8¹Tᥟ‚Ö_|–èUÚ₫M:çû€q´~±ga9—̣tdXmë«Ô%PDï?÷e¬¬>níbbc$9íÏÿNhSu +endstream +endobj +651 0 obj << +/Type /Page +/Contents 652 0 R +/Resources 650 0 R +/MediaBox [0 0 612 792] +/Parent 616 0 R +/Annots [ 639 0 R 646 0 R 647 0 R 648 0 R 649 0 R ] +>> endobj +639 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.921 632.346 178.281 643.25] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a15d42d058c64dec106d9e3e9fc2e1136) >> +>> endobj +646 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.921 604.451 180.293 615.355] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a7a1f65b032f03494dbc68411f5614bb1) >> +>> endobj +647 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [108.921 576.556 161.125 587.459] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_aa7a737b69a0a77dc29aa28d0f17421a1) >> +>> endobj +648 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.915 548.66 186.39 559.564] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a84eb9ca31c934f05a8e3fa7a02fa71dc) >> +>> endobj +649 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [115.915 520.765 190.804 531.669] +/Subtype /Link +/A << /S /GoTo /D (gf__vect__mul_8h_a8f3e57729c3382514325612c54e20eaa) >> +>> endobj +653 0 obj << +/D [651 0 R /XYZ 72 686.127 null] +>> endobj +654 0 obj << +/D [651 0 R /XYZ 72 651.32 null] +>> endobj +186 0 obj << +/D [651 0 R /XYZ 72 492.57 null] +>> endobj +190 0 obj << +/D [651 0 R /XYZ 72 423.813 null] +>> endobj +383 0 obj << +/D [651 0 R /XYZ 72 397.349 null] +>> endobj +194 0 obj << +/D [651 0 R /XYZ 72 397.349 null] +>> endobj +655 0 obj << +/D [651 0 R /XYZ 72 265.439 null] +>> endobj +371 0 obj << +/D [651 0 R /XYZ 72 139.795 null] +>> endobj +198 0 obj << +/D [651 0 R /XYZ 72 125.224 null] +>> endobj +650 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F47 238 0 R /F14 318 0 R /F73 498 0 R /F43 499 0 R /F13 312 0 R /F76 529 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +659 0 obj << +/Length 1894 +/Filter /FlateDecode +>> +stream +xÚíZKoÛF¾ëWđHÑfßC‰S Z u¢@’”DÙh:!)§iàÿ̃YîR⪫Wă |à’ÜýÎÇٙψè:Âör1Âvh¯3ÂỊ̈Ô.ÓEZ‰Ób–ß]½:̉·èÍ„QlHLU íÇ«ÑÇ!ˆsW Cu4»½y‡£9<eơ}jfƯF\j¸æÑ¯£_F8ؾf„ÙØ¡‘ë °ă ÁÇYQĂj©†íhœ +œ!T!AH#Ï@~À#Œ6+Ÿ₫éa‰Đ‘{Øù›\!w +›#Î6¬̃‰ˆ—ya)Çú$†%¨0*4œŒ ‰ïÿt»ư W“Îܤ¬ +tTYqƯ¤xX¡iî§§yz›6©RÙOÖ]·ï “H‡m O˜V°Togº`q*¢Ú…—XV©÷qÑnáå³—/¤ª¸L§öZfíBVđ!)ë,ÉƯͧ2«S'±X³:”4^èøÜß»‰eúq™•*₫P¦“Y’Ï–y²r·¶”ÑIgó” D8i4áiˆĂ•M¿4;Ưd…^÷ô ¹§6?å6g-¬¨ƒ ¿œ}Áøá‰³c²ƒ˜¶·ÙåBÔ×SNE;eCéŒ)̃®gœ—₫ÍOiáÛPt—-Û¬7k?àªö¯¯H’¼ÍđpSß¹+£ÏQX4Ç™­EÁåÅfIíÁ®•3xÙÄ´)tª E½¹Ûăo•ñŸưöûFmÔ-G6’è„3åy÷ ~m³wR&·imë-÷{Ño`óíf1å Ô~t°˜R ÊVçù)å1&âÆ ! :˜íß)) ê'0è˜!Âùª.è©cX‡ "M„B†QÀïuí‹åæ[ï9{ Ùœ:uÚ$¨~̃ÎÁ¢‡Áµÿª‚hZq6,>ˆ†#å4”˜‡jOàFʬ«´|;³Ú ‡®Ơ×wPÀ¦åf '6̣>ÊM~à̉=7Úø·©½̣ñÉßJy0 ábïå…qqŒÅá¸8ÑáBq¤ÅÑI¶†\ih|ÔªfṕnGÆAvûѵۋŒƠá6Oꤋ)â“æ‰}†¤%ZĂá8y ”Çá jwCJ„5 û›~0fµ ]«½h°®dE[;~T́½º0¬ N‡Å‡a±¿|ÑÓC̣@ÿéS˜âm]W/Ëb§’ºd… Ô¡ÚPêıÏƠIU=ñ‰¸¾i#¸°|@’¹óf¸äƒÖRAsƯ Lw9(æ9¨Uû¾ˆb $¡¯‚ơé#‰(@§*¢‡©(V)9‰UûMĐèv& +¢iàĂ9…]ÈD ¶gën4Ç]rç‘i¨¤×8‚Lư÷Æwæ¢NîƯ˜â;óRñ₫fy)ŸjJØÆu!˜gEÚUVVpb|g°¾3X߬ÿ'ƒ5XP`¦M`¢¿…D…A„^ö)ßt”çiØI($Ør$Ú₫}ˆB:Đho3}T +iÿU…Ñqeøáh8Ñ¡ÊaÉ̀qh඘†Q¶ÿ£Ü…ĂLöc¡ḳëH₫¾­>–•·A ?wé-«Ơ´ù¢ö̃› ÎÔQâO°p"î‰B^ÖîÆ=h¸U]ĂJ>í¿ª0  n›Ưƒqœ¼C´ †Ñ“°O”0$Ú“z}:Đj?ºV¿ öiÿƠ…aqÅØá°Ø_~‡Ÿi&¬Këđ½i¢0ÂĂÿdÛ•Ö ü¦uNaƠÑ:Ñ¥uNa×Ó:á¬ÈêMZg€‰Óư™̀́1™–Ơ¯ú¸HLîLvP xÖ:$;^Â6AÛ˜ư•öÔö,¬<m]º½e&ÊJvi™U/—0D–4¹¨é¡-|¸n¯â¬-†¾–¯<‡áºëÓxƯ@º1mÇ®ëÓ4^¿sƯ#Û)zHgLñv=¾{=̃3ï¡ïĂçînêm)f:Ù›ơ0§Ô!†~g I +IMv₫¥Wó7 Åh +endstream +endobj +658 0 obj << +/Type /Page +/Contents 659 0 R +/Resources 657 0 R +/MediaBox [0 0 612 792] +/Parent 663 0 R +/Annots [ 656 0 R ] +>> endobj +656 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 549.72 111.003 560.599] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000021) >> +>> endobj +660 0 obj << +/D [658 0 R /XYZ 72 686.127 null] +>> endobj +661 0 obj << +/D [658 0 R /XYZ 72 523.866 null] +>> endobj +385 0 obj << +/D [658 0 R /XYZ 72 398.222 null] +>> endobj +202 0 obj << +/D [658 0 R /XYZ 72 383.652 null] +>> endobj +662 0 obj << +/D [658 0 R /XYZ 72 271.302 null] +>> endobj +370 0 obj << +/D [658 0 R /XYZ 72 201.636 null] +>> endobj +206 0 obj << +/D [658 0 R /XYZ 72 187.437 null] +>> endobj +657 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F76 529 0 R /F14 318 0 R /F47 238 0 R /F13 312 0 R /F73 498 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +667 0 obj << +/Length 1543 +/Filter /FlateDecode +>> +stream +xÚ½YKoÛF¾ëWđHÑvßC Z u|KR€’V6™rH*Fø¿göA‰T(%¢ÜB‡åcwæÛ™oçAáä.ÁÉơ#̀S FLI.a”Bk’TđúÀ«›ëÉëÛÉoWđÈ #©Ln—‰¢‰Ô)“ÛẸ!ˆeS*pÚ|}´5º7WÅʆ«»´UFtj˹Í>Ư¾à³%\hx ï‚~ª{BßÜN>O\ℬª“ùĂäĂ'œ,àù['ÖèäÉÏzH¸Ô0®’÷“vض©p—nˆÖ¦k ‚0扔-̣.£<Í«üÁ6nç$­ûÛ>ªbÿíûÂÛ₫Ø~” l»§—\ˆ1‰ä 0Ă0› #Dá §XÇp„S¤ˆRˆ€ƒ½áæ̃N½*ÅX\u5 +…0\öT^¬ËºÉË&pµ(7 ú…ơŒ̣0ú¶wbäx×µkcÍzÓüÄ'é{€¹ă~†O_ÿÓDˆŒÛhLá'²)ÁØñÙ›jpÏ€o¨B‚¿\󣤦Èh³…ô#Â0=_́¼P GĂÑ{ •#ÎúJ2"̉Í ¥@ëÑ+5̀W=½umƒ™?b³)̉[`ÀÑéæN0ˆl3×Ê–¯Â¤¾LÛ9›².îJ»̣ç™Jïó*,‚ ¾[är"'íª³ơ +HÄÚ9îÄf§«! ”ƒ½¶)ö‹Khëb1 ÀjjNÑ[WÅéüÀε2/©ukÇ…­›¡}ÄøN ½L½¦ŒÁÑÿMÁ< häW]_9¯Óˆ’%ÅtULÂ$‘(ÿ†Y=©i©@ön–ö@|@ûâ Gi]…û‡Íª)W_ĂƯ,ó˜Ä|àti`ô”( R”y¹¶5LV2ÍƯ ÀqJ=ly¶ °e6èèÁ†{€‘´Efaø= ÓÓ½­l% 墳@@UƠ¾¯ªük½7é"L*ꌺ(ï|‚€W@jWqº]Ùë#¤r6Œ‡íÂ$ä8ùă ƒ²)Ó +¶ờlp§2$o…¬N}m#Æek›?₫¼”îR¥•¹#´)Úl đ˜WM‘¯ÂÍSU46¬XnÊySK< +^Åû0±²Ÿ7Eø¡̉ÇÊNçùj¾Yå»)ëeϤŒN;ÆS€àá¼}àƯă7ˆû;›åqk4 ²É–½áé +O}Aá\qÑ̉ºĐôÛÅ7ŒŸ_MpMv×€Óö!·]đúnệ9ˆh§́‰"kËYâç€̣9¾ùË–A°sÅÀ¶ëj̃à:Ö³X³ä«6À»jFF_£½¦Áå1×ù‹›ëư¶ º|®UPxă}êÛ®áîcµÜå=ƯFÂ÷ïßpDöµn²F§P^ÍơĐ\pơ?´Aœ»‚V®ÄÎ\ï‹iUǽ¼b,†½,l[¬¤Gꬤ»:ÀwḾƯưaH>>Dú´ÓXI zøûD>Vå§oªïKhH4ߟ¹>pÁ%[m^¤±âP8@”ư•Æj¤Úa:tƠ¾[Ck«}/N}ˆï¦›:Z´Ñ½,‰ñß­tº8ÆŒ“÷×÷,,?^î'ÆYË/°@ŒÉ³c„ûF 2”nËh¦|1©x˜]Ń̀Øæ·Ẽä]~H‘¾h¤8yW}‡ÂrrƘ3×{F0ăR-=“pTÁ̀H$¤é·8ƒt©u=­ƒtpP²­ÿ{Zœ¾»[Ưr¥ÙhZŒXâ÷eư½¦­íMU₫RY²ÂjQ÷É<`ƒu^ׯb$nî[.Ư'¼g æ#®ó•Ô}tHSf5¬óo€ÿö´û;€êö︺±ËL¥Đçíÿ°‡<Ô³†Å|ti]ëVÚ˜F\JYäU$ÉS±hk— ơ zOå3¨qÛzpCÁ_Ú,Đ~s¹´ơ¼*=—‚·óU` ̃¥.`‚HNưă;Xú×4 +endstream +endobj +666 0 obj << +/Type /Page +/Contents 667 0 R +/Resources 665 0 R +/MediaBox [0 0 612 792] +/Parent 663 0 R +/Annots [ 664 0 R ] +>> endobj +664 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.004 480.205 111.003 491.084] +/Subtype /Link +/A << /S /GoTo /D (requires__requires000020) >> +>> endobj +668 0 obj << +/D [666 0 R /XYZ 72 686.127 null] +>> endobj +669 0 obj << +/D [666 0 R /XYZ 72 667.868 null] +>> endobj +369 0 obj << +/D [666 0 R /XYZ 72 620.844 null] +>> endobj +210 0 obj << +/D [666 0 R /XYZ 72 606.274 null] +>> endobj +670 0 obj << +/D [666 0 R /XYZ 72 454.352 null] +>> endobj +480 0 obj << +/D [666 0 R /XYZ 72 328.708 null] +>> endobj +214 0 obj << +/D [666 0 R /XYZ 72 322.979 null] +>> endobj +218 0 obj << +/D [666 0 R /XYZ 72 256.871 null] +>> endobj +665 0 obj << +/Font << /F46 237 0 R /F59 309 0 R /F73 498 0 R /F47 238 0 R /F76 529 0 R /F14 318 0 R /F13 312 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +672 0 obj +[228 273 228 228 456 456 456 456 456 456 456 456 456 456 273 273 479 479 479 501 800 592 592 592 592 547 501 638 592 228 456 592 501 683 592 638 547 638 592 547 501 592 547 774 547 547 501 273 228 273 479 456 228 456 501 456 501 456 273 501 501 228 228 456 228 729 501 501 501 501 319 456 273 501 456 638] +endobj +673 0 obj +[833.3] +endobj +674 0 obj +[500 500 167 333 556 278 333 333 0 333 675 0 556 389 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 214 250 333 420 500 500 833 778 333 333 333 500 675 250 333 250 278 500 500 500 500 500 500 500 500 500 500 333 333 675 675 675 500 920 611 611 667 722 611 611 722 722 333 444 667 556 833 667 722 611 722 611 500 556 722 611 833 611 556 556 389 278 389 422 500 333 500 500 444 500 444 278 500 500 278 278 444 278 722 500 500 500 500 389 389 278 500 444 667 444 444 389] +endobj +675 0 obj +[277.8 777.8 500 777.8 500 777.8 777.8 777.8 777.8 777.8 777.8 777.8 1000 500 500 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 1000 1000 777.8 777.8 1000 1000 500 500 1000 1000 1000 777.8 1000 1000 611.1 611.1 1000 1000 1000 777.8 275 1000 666.7 666.7 888.9 888.9 0 0 555.6 555.6 666.7 500 722.2 722.2 777.8 777.8 611.1 798.5 656.8 526.5 771.4 527.8 718.7 594.9 844.5 544.5 677.8 762 689.7 1200.9 820.5 796.1 695.6 816.7 847.5 605.6 544.6 625.8 612.8 987.8 713.3 668.3 724.7 666.7 666.7 666.7 666.7 666.7 611.1 611.1 444.4 444.4 444.4 444.4 500 500 388.9 388.9 277.8] +endobj +676 0 obj +[1444.5] +endobj +677 0 obj +[339.3 892.9 585.3 892.9 585.3 610.1 859.1 863.2 819.4 934.1 838.7 724.5 889.4 935.6 506.3 632 959.9 783.7 1089.4 904.9 868.9 727.3 899.7 860.6 701.5 674.8 778.2 674.6 1074.4 936.9 671.5 778.4 462.3 462.3 462.3 1138.9 1138.9 478.2 619.7 502.4 510.5 594.7 542 557.1 557.3 668.8 404.2 472.7 607.3] +endobj +678 0 obj +[777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8] +endobj +679 0 obj +[569.5 569.5 569.5 569.5 569.5 569.5 569.5 569.5 569.5 323.4 323.4 323.4 877] +endobj +680 0 obj +[777.8 500 530.9 750 758.5 714.7 827.9 738.2 643.1 786.3 831.3 439.6 554.5 849.3 680.6 970.1 803.5 762.8 642 790.6 759.3 613.2 584.4 682.8 583.3 944.4 828.5 580.6 682.6 388.9 388.9 388.9 1000 1000 416.7 528.6 429.2 432.8 520.5 465.6 489.6 477 576.2 344.5 411.8 520.6 298.4 878 600.2 484.7 503.1 446.4 451.2 468.8 361.1 572.5 484.7 715.9 571.5] +endobj +681 0 obj +[769.8] +endobj +682 0 obj +[273 273 319 479 228 273 228 228 456 456 456 456 456 456 456 456 456 456 273 273 479 479 479 501 800 592 592 592 592 547 501 638 592 228 456 592 501 683 592 638 547 638 592 547 501 592 547 774 547 547 501 273 228 273 479 456 228 456 501 456 501 456 273 501 501 228 228 456 228 729 501 501 501 501 319 456 273 501 456 638 456 456] +endobj +683 0 obj +[556 556 556 556 556 556 556 556 556 278 278 584 584 584 556 1015 667 667 722 722 667 611 778 722 278 500 667 556 833 722 778 667 778 722 667 611 722 667 944 667 667] +endobj +684 0 obj +[600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] +endobj +685 0 obj +[556 556 167 333 611 278 333 333 0 333 564 0 611 444 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 180 250 333 408 500 500 833 778 333 333 333 500 564 250 333 250 278 500 500 500 500 500 500 500 500 500 500 278 278 564 564 564 444 921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722 556 722 667 556 611 722 722 944 722 722 611 333 278 333 469 500 333 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500 444 480 200 480 541 0 0 0 333 500 444 1000 500 500 333 1000 556 333 889 0 0 0 0 0 0 444 444 350 500 1000 333 980 389 333 722 0 0 722 0 333 500 500 500 500 200 500 333 760 276 500 564 333 760] +endobj +686 0 obj +[250 278 500 500 500 500 500 500 500 500 500 500 333 333 570 570 570 500 930 722 667 722 722 667 611 778 778 389 500 778 667 944 722 778 611 778 722 556 667 722 722 1000 722 722 667 333 278 333 581 500 333 500 556 444 556 444 333 500 556 278 333 556 278 833 556 500 556 556 444 389 333 556 500 722 500 500] +endobj +687 0 obj +[278 333 278 278 556 556 556 556 556 556 556 556 556 556 333 333 584 584 584 611 975 722 722 722 722 667 611 778 722 278 556 722 611 833 722 778 667 778 722 667 611 722 667 944 667 667 611 333 278 333 584 556 278 556 611 556 611 556 333 611 611 278 278 556 278 889 611 611 611 611 389] +endobj +688 0 obj +[333 333 389 584 278 333 278 278 556 556 556 556 556 556 556 556 556 556 333 333 584 584 584 611 975 722 722 722 722 667 611 778 722 278 556 722 611 833 722 778 667 778 722 667 611 722 667 944 667 667 611 333 278 333 584 556 278 556 611 556 611 556 333 611 611 278 278 556 278 889 611 611 611 611 389 556 333 611 556 778 556 556 500 389 280 389 584 0 0 0 278 556 500 1000 556 556 333 1000 667 333 1000 0 0 0 0 0 0 500 500 350 556 1000 333 1000 556 333 944 0 0 667 0 333 556 556 556 556 280 556 333 737 370 556 584 333 737] +endobj +689 0 obj << +/Length1 757 +/Length2 1108 +/Length3 0 +/Length 1645 +/Filter /FlateDecode +>> +stream +xÚ­’iTWÇ¥‚…àEñ"1bYªPĂö°)R[CfBF“™ K¡ +ZD°PR* †‚ UTR¡ÄQT”Vƒq­ ²iT¡Öö”~í™/sïư¿{eX¤-Ââ`†â¶4;;đñ¡9ƒÉÚÚ[sqC}¸8́hnnt˜(tG@§¹Óéî W’5đÆÄ2 /ÀƠ{Ơ”È0E°áqQÂŰˆèÁă +A$ÆC`\f˜B!ˆ˜:!°–$Á‰FÂĂA $û)¤”—wi(Qü¾”K¤ NQ®#„¡B€`>ÉĂ`åÿ Ùœ•(²¹¢©öÓ>ư§Î!BÙ_ +L$NÄa Á X‚ΔFĂïàB`Iͬà\!Âc¢ñB8¼K!R’CaÎ>W(…§ó0 +Í„ œ›F°ç„Fú®₫k§ÓÅ0.‚âëeâ¿ÛN©§cÚ?1áI±„¿4BH|ïÿ6Îæ‹̣0AăƯÉp%®ŒD¼"r©4€ œà‚Ø̃Åpâ LÙø˜„4µQWW`/M‰¦_„HÅB®lJAú¼°”T[:Ø̉Ưœ‰ 'pq¡oû—’—(‘À(>ưbg̃Ç|„đ†S`é—›oMÖæ’SÙÊt_EWW|C»¾åúO†™½…:ª ›¾ă1ăµ¥&óô–%¿1—înJ ïd½ØP ï™HÚ4PºơGó˜‘̉Y¿xùï™O4º1ö̀I'ôZß%e§̣\ÙĐù§è>ë}xÇrVkl̉‰Öﲜ]bX¥Â 9;S-#Œä Ê\F&Ù¨hŸ®æjfúæ}ơêÛĂXSâGă +ư_O|öRƯq¾ºùd×̣¤~ăÉ£6÷̀Œú>ÄVĐ–u¥©Ú¬F7åfX4×TïË¥s²ß₫P{·=?hƯ#ù.ËđgúñO;|Z¢¢‡îz¦:è~?zÏ1É™ḥ}½«ư¨¥.:½à½®/ưG2¨Ă­'²–7ßÈv;ÔÀÖydt?đÛQ?í˜[đ[u2 Ư¥Ëx̉̀‰½-•å­®]Àg/M#{,̃u6cö=2¯çñ]Ưq•Ÿ“Å­,P‰| EvăƠUƠujeÊZ«Ï[ŸXFQ̀÷ÖÓv$øöÑbÑÖú̃S©V¿sŸŒ±j´ ̃2ÇÖœº,ŒÙ% Uëe&ơ¾8ÍÉ RĐ̣b/Fel×r̀[ºWrlL2Fu¸³̀Ô*ÖÔ¿ÉÀ"7ß'Gö[]>èï¿rÉCUÛ¼¦½ơTMO=óh)_‡J>íX̣•Üß÷ælL׃¦·™óÓ ~¸-ߺ…×Àr}Saù}À¯œ¼sy”øÖ~M¿Ê0ù¥²¨CløÅ‚á×ç=ßj­¶; –63ù1-?©-n!¹FQÜù‚ ]¸Ô‘üÁ””|{år{ÍFë(%ø:ÉsGqn₫gæ4·NŸưtp°sr«ßá|¤7¸ÿ›îÚ́%û8x¾üUÂRö +2¥¼gÙ(•Á‚Ü_ï¹oj|Û~£guú#Ƶæ›V¯¥Y†{ê,>^KákBº[Û]C 6§Öt1IGU•<Œ́-ç2æ¹›¼Z4é 5­8´2»Ươç5G·PW¼Ç“ ®ùÚo¡ƯÀε.çZ­Ÿ+óˆz*¸öÓ\’wD°Ç­>²ƒxµl¶mùÑ„(*^g´¾?('A÷à6ú^Å©áT¿¯½ÆÎá‘·dư…tơîÊx1sÛ¹W—#5Èγa+lM›­ĆF´Úˆ£ WFf3Ï  ·èÓûåríܕ姱ŵo–åë™ )û«'oOιé·V&7xùëƠZ1Ë"_ÿØÏׯ“]Z>óễz©µH]6gÍ~ûS”cÎwŸtĂMc.n­BÖ*†§å1öomh+63¬Úaר&¯¼_<0-½hÂ.{9+•₫øjåÙ¨ÓĂú1¥09dLílTi~uâ¾qơxĐøóđ’¶g*bqüîtäOø& +endstream +endobj +690 0 obj << +/Type /FontDescriptor +/FontName /YQJSDJ+CMEX10 +/Flags 4 +/FontBBox [-24 -2960 1454 772] +/Ascent 40 +/CapHeight 0 +/Descent -600 +/ItalicAngle 0 +/StemV 47 +/XHeight 431 +/CharSet (/summationdisplay) +/FontFile 689 0 R +>> endobj +691 0 obj << +/Length1 811 +/Length2 1849 +/Length3 0 +/Length 2409 +/Filter /FlateDecode +>> +stream +xÚ­R{<ÓûWêȪS.…„ïÊrkls¹̀-Ărg¹fûeûN³isK’£”$&9,¤r)NÊ¥”tEIYr íI.©3:óúu₫ư½>ÿ|̃Ïó~çưz?îî…ÄQ˜¡ #b#ÑúhsÀ@À£Q€äBÁ;HbÓ˜=‰ h,ÖpæĐŒ!€2576476…!;f$E gÚv:‹$SÇY42 $v8Èô “耓LÙ<}G§‹Q€'²¢A> (42Ăh̀`Q¢2Óoa +'̣{*dEIDÚK2u‰H +¢ó +H…́bJ¦-ÿY?6wäĐé»HŒÅöKNư'ObĐ輿LF$‡ ²“² ©~à7qBă0~̀âÙ$:ŒƒÂè €D飌¾ÅiQ4.Hq§±Éá•D—â DùQ‰Ä¿%v¾;]<|ô₫^íR̉DƒØ̃¼H@ưË^Âè±Ä$  ôQ(´„(yßA? s€ÈL + +0Æ&‰Å"ñ`’#’ c  Đ +È@®D±>ÄdKJ‰3ñ•É‚-îƠÄ 0°_ -!3`à₫’¬Í€ô2Áa‹G)±ơ{ ‘p—à-°µerc‘†‰1–HB™¦Æ¨øÿ!’9,±—ÎLbäwL¥I¼A.H†‰:™d‹ä=95)¥ Åíe+u¢6çOn½yèJ®…₫H¯…ü3VícoP}RîÜZùz₫˜ËE +Ơ¸_¥'Œơ28Ô%'\«¨SxÚKfœ<øẸ̈fÁưÛëù‡Å"¡ÈZ½ñ[?öEß\YéúmZ¤2vdEéóÎ… ûÛúE«OQ¶óaA‚ë®Ù ïŸ}çFw2‹™¢’f¥ÀÓ¾ˆTn÷tD¼\›‹M¤ÿȵü,‹̉áRÚ`è¼ ±ë́e¾j³É3ß3¹€Ô&Kx.Ѫ¾Î…đnƠà́ )ïä‡÷™V-+”'—ª̉-w–¨,«nû72¬ ¦_‡ª<’ä#ªÚ1–YèÈÚl„gÈ́bRóØ© ùù̃O_ÓTÇɱp)åKËưộ̀¬£µơFtZQ*+Ÿ¦ +á»Iá'ÅlœµSïj›´ûŒGÖqơ3€ˆư#Q±óBêVöÆ|–‘sf;Á_ïr03Đ+…Ư}Ú1Pô₫íƯÆ´<̀/v½! ̃Ïơ+®̃*¶W¨øuE°ÎѱX³n³kĐV n¥°ÙbĂz\à7.jêàfŒ†ßˆ“7›U+77Éïøl1ü˜ï#¬;o¢–°rø jDº₫¨·n¬Ù;é›.!¼v³jaËF­w̉#'¢¼Ô¥4…Á›ÀÊf—a«̃£¥ÏÄƯ˜ÂƠƯ£ +X@¥¶Ë₫º:÷Á*&Øë3Üç‹BôY»­oC,hè̉ll4¦Á-ØØ"0́K‡Ơyϳ%±Ç÷O<7R; 3_=Đ5ˆU‰tˆá'|MîÚÉY-çP× ‚Äe¹=-ư4́àÁgå8[-‰·Y5ªT̃z5căÄÈQ½cQôƯzG– ̀!(ơEŒ +EEq¨Ù–¦-Rîà§”!a}dZ#qn¡º˜ïk0ÔesÅÎv)2‡¼¶ákèºRË{V̀|à+}dÈêdzơL:Åúe¡»ÿtáœeß“9N¢Âƒ±#mƯ× TÂׯ́%*koÓÂOƯE{„înmṛùÇ£küZ&§üáfo, ++ù¨)-í‘Ô~ăàâé{ÓR¶P«µœlWT(SIÜ‹ưüä$ç\Ĩ3#M÷;NóøM —à•ˆĐÆ¹âĐƯ6ơ¯́•/xÿ>}½-ÛL™=/ëˆÁtØ̀{´L̀T~±½£7[)FSÄ,í}Ặ2y”ú ưÆ’y™Á‡đÄœÊÓ fƠY¾ ª/Ö= ×çœÂơæ']².­ÜJƯ…¯büêsN1Yac÷Τ?ÜÑĐáh½ÏÎă-èºe8¹nrẽeX̃†××Â]̉b›60đö́öËĤ‘@í¬¨¬ñ)®>¯_À¸ăÀø© Ơỳ¯^·a]’Ik 9y€£×@Êư“²î‘De,̀₫à¦Ư2¸ *ÍÄvûùܺèxA÷,'X vÖv®numt—i§f×;¯uíî¸&J3)] î¤EŒÏ›-]Eê]QÛûJ£`Á‰-ƒ÷rÈS¤’³E¿™%´ÿ|°§›S2\)Ää7-gY¿€ +o¿küN8°½a‡ê‰í£̉Ï’ÖM]vT—⧤¨µ)ĐY ƠxÛ¹-•>猲Æ+8·U'⛟Œ¼–&Nßù(HH̀‰̉xœ¸1ób©1o c>óTµVjà®̀Äp·ƯárN¯lợ[rëÏoqïk·jŸ|5ª*'[ôˆ»Èư=¡owĂÚ¨nÈî³Ïz.LF?:>¢!Đ#K)®Û(Ÿá₫!Û'x„ès=\đZđw“$£½>Æ2*1üKmỦIÓ»”aÖ–­üĐ*Êzybø€ùç›WCÙY™Ó†;j½ë.Àw£6[CçYáîJâÇN¤7ïñ3RO›‘— ô¾>™×q:¯¡tÖ:€n4è?<µª&’̃Q÷@ípÍKÍçoeôw!Tïï¿6p5vHµ;ÉƯ‡̃‚²<1̀‰¿bÑúUV®ü“Æê˜2…NM=¾Úó7Ôl¤đ’øèEồÓQrF6®ØûÏtgu>½¯RÑù~,&¡¯‡[ç§p.ƯªÖmSf¯ï*y?Äb&蟲։©ÎRh¾®b® º»wa¦¸Ó­úå§>x8Ø­út4tm¿ ù÷l|Kú4Ñí±áÛÂÑG;m›/ÏÊI5°E=FWc¡ü-w&*ø½²>ç{© zđ’™ +endstream +endobj +692 0 obj << +/Type /FontDescriptor +/FontName /CVGKQU+CMMI10 +/Flags 4 +/FontBBox [-32 -250 1048 750] +/Ascent 694 +/CapHeight 683 +/Descent -194 +/ItalicAngle -14 +/StemV 72 +/XHeight 431 +/CharSet (/D/P/a/greater/x) +/FontFile 691 0 R +>> endobj +693 0 obj << +/Length1 792 +/Length2 1655 +/Length3 0 +/Length 2206 +/Filter /FlateDecode +>> +stream +xÚ­’y ]<ƒL¢D&9HÀœFœWvøΠÈ)Hy  @dà zC yÔ +’ Ă‹ }/SüY?Z ÛO è¬b"1$…É ĐKåÀŸY₫X?·̣§ÑHô•ñ+Aư£M¢C´Àÿ˜t–?d&d3~¶º‚ßÙ ̣§ÿܵáhÙœáM=Œ!mø½ùYA\âqÈ>€‰æ®ÖAågq|«(K+7¼­åîï»Ús$A Α@ ÿ2¯j̀_Zâh$ÅÏƠ‰ŸÎ²d™ˆá ècq‰Í&ʣţô±X @ +È@®…d09â-€8˜PÀ‹É–_¹U¬1€"3ét̉Jyµ‚Acô7‰PÔ¿I#å»*ÿùÍLn0ĐÓÇ0FÀ‹ưÙŸÍœƠŸJœÛ퉣A.H–ï2ɦÔ´ª¨â0ËÜ2?ơŒÂˆ¶ÚÈ SääKS¥ḉê§GÀá‘p*T¢˜:ewEñ©V™‡4Q‘/àͰ͈k™D¹ịäñ“’-9MơéÙ±£½¿¼aUïîÓ ÔÊܶÇ]W:/]Ü#\œ ó=ód¨W!¢9’*"ç} +xtlđ̉ă¯ï1s™½ù-[g6-ơªÖtúöĂ2ŒărR=ƃJúyBM“¬ÛÏi°k]*²”av¿æ¦u/èpăK₫z'>³XT%-Q½]\ÆíT°;O?#µæ)ä]ÎB´n;~%æ̉£<₫é1Ÿ¾ˆ˜̉ƒØ·•í†1ẳƯ­\'BØ!ßù´íæId¥ÖpB c  ¨ l1ÿ©¬ÔDN₫scÓÉ; 5ºg¹`éơ×oM<Ϊ«ëđÏ$%+Á¤Ù9̃l`Tîîë’€úñ°_lô´‹Æs̀’ƒm¡Ă`²fÔËÄ­3µÏ•Œü»…ÑÑù’Öät÷¹đRàw|Z ½èp¹†4–„¦ÊDPnÆÖà́{ƯQvȱÆXaf†è×àßt|×”ÛdĐ‘tĺ؈û‘·4ëâ)uÇÏ øÁR|ăḥ¦ƒíKxí̀Ž[B’ubs?.Ÿ¥¡æË'mÖvËqo¸=] lÛ|,H¶8y*bó½±; ÎóÈ< ̉×…œÎ:J„üy„;™n? ! »Ơûè¼a?¿Åü7Q{ôVNÓÚÎ8öÚéψ˜¸Í{F/;då3¥Ÿ™Ä–ÿaë—§#>bơëæù¤îªíÂ÷Úè—/©ÊieYZ 2»¶5ÎÙçDüöĉlW`½À;Ö +«³¨V]x6ˆ*ÿ:ëYăî&t§/º™})̀´HĐ¼tµ̉8~’û©²(;³3ën«‹­<$§™¾<evÀQĂÔYŒsÙ8/$§ă;jó4bç=^ŒƯ^l~¨„è23UºtÀ>đrü…˜´è'MYLƯ·fªß¬ –̃Ö¸nµ>M½gïâù„Û0)(̣™‹̉Tzƒçt,¦NEJ¿L†Á[ạ̀ï +3»“¾ùJD¶½9m·È¼ÚrñÁ`áËÈ¢Ê#ÜÈÉóü¥G₫̃DƼ&’}ªu rFÿ zUFÔ™́ß–ÿÎ".^Ă^øíàƠÚcjZ̉ª¶s5„“²c ØÑç6>O_äæü8ùpq!vVơßëy€…[çÍû#[à&í°’Q²¢Jâ5_‰Eµ¨đ}0eäđU†X¤̃Ơ ©¤œœôWđÈưc–PË+J̀«ỗf”yÊúÓ)«a¥'Åüô¸‹kv:đ 6ơœ+é<ï¡£̀ªT¼]·)ÁXm§ơF¥pª +ˆÑïÏ>j1œéq¨ÇKVw×ïs»^h•§4j»¾D¦cK“ñ$—W]!NääV"ö±áµ7jûÆ̀æâz`ÖrÍ:×5%_–L`f2c³Ô¸Aâ«%AÂheù¶M5&"ʶ¾å68¤ùåµwạ̊9O ¥\ư¯Ăùwڴܷ܃—®³c̀4¤’t&²¦7E‘¶đê¶[4É]¹[”èîZ’´SÆfK{ϵ½Ÿẩ›…Ê'KÑzÙ¸=Ñ¡ƯŸ Ñ«ëq8O\Ï{]׈r5„§̀g˜¼ÊÚú™Ú§€¼8KA4ëü0|.CV£‚H|°ñ«Qxô,¥8°ưÑùüJ[ëÀ[aWÛͲ†<_Çg· )æ…o-;¾Èöíƒ̣n…¹,sÖʲúË[iL„o¶W„¶•‰³p5q +¡ăAQ§Î-ÈÔ£©zï‘"¦YŸ`Î ÍNU²£·æ¦o‡×¡ -3Î(z¤ïûQ™$B‘tOƯ®ÊÇŸû§7-Qˆ+́X›²•°›²HñÍo|ày7=̉c x(±!¯ëTQ]èÉîß½®¸ëîÎIËnu™í² lÎ̃ÿ|ïèăSY8ß5—z¸Û1˜®–ö…¬8†@/úïàVçí˜/1©NÉ6YC2ô©û¦Ưdÿêuư:½̉–Ú₫ˆ̣̀Å’³̉CG«Ë+É̃Ó̀´úxÚ„©ndW¦eÍT‚½áûá k-‘¹̀» +å±$₫(UåL¿;¼;4Q0Hăù–æöÁD§2,ÿçKg +endstream +endobj +694 0 obj << +/Type /FontDescriptor +/FontName /EFXCJE+CMMI7 +/Flags 4 +/FontBBox [0 -250 1171 750] +/Ascent 694 +/CapHeight 683 +/Descent -194 +/ItalicAngle -14 +/StemV 81 +/XHeight 431 +/CharSet (/comma/i/j/k) +/FontFile 693 0 R +>> endobj +695 0 obj << +/Length1 778 +/Length2 1256 +/Length3 0 +/Length 1801 +/Filter /FlateDecode +>> +stream +xÚ­S{8”ù§"g²Œ[ÄQ¿Y±.k.®¹l2ƒÖe\FE$;f^¼v¼ï˜‹ÆµU³\ÆåT¬”JkQÖôh*.›]´"¹Œ³i1r* —NgŸcÿ=Ïû>ïóû~¾Ÿß÷ûy?ßßÏ”líÎF£ /XSˆg@£3(d@!’ÉTœ©)10x03 89Ù/( +[`¯³½³½ ÎĐPn‰sÅ*ɸÇC<˜ÅD)ˆ…â±,&£,$;‡«;ø€ñ!^"Ä&â(À†YÅÀ´*ɉFă˜-ä~L%B<>& +˜¯É´˜H6p’Æ‘üQ¬„iùÈZ_ÜKÈáø3ăW˯ơ§43æ$ư‡€Æs…ˆè(â!ë©!Đmtˆ ă×g½L̀rGb8 €`¾,‚ذ€ ¢™>´†C{½̀¹5 $Ÿ>>Vfº– dˆ`_÷¿UWÉk1ås‡‹@8³—‚±çă*b]/O„…²a$ØØ;&ÇLÂa§‹́A +ÀH„ &T€m˜'i åáVê@$(Aˆ ƒ×;'@BèØ¸! øóR©¨(ÅÚÆ°Ö™LvNNiÿĂd y<¬#̀®q4Œ™ A"ˆ…{Ú‡²\2ă›³.§{V=¾¢b©L¹™ïÿẴÛ[œQæÔtû&X7„.Ö‰u4d*²GFüo%©A¼f2̣K~Y‘%~%'·…ΉéIÜOߟ̉lm₫y₫•½rÀ“á\.ÚÈ[ÏíB%Î2K=…¹?+ü…́ºj­†¿§†¾jb¢¬µÑR¼óªd÷î”d—•Ú€ßz–â÷…7H:*o-fo®«(ÜÏùyVmçLHY¬Ró3çú̀-nw™ór]¨‚!Ơn‡ú<–—Ôˆv׳“äBøÜ·_ùtÂ…K~âÂß• +¾[‚BæG„ø½ơư äU•̣­ë±Z%ErU]ï çáÂM6ÉËUM°]M“Å–uRƠó†¥w ·çÏ₫ø²\̃’Úv¯§È;·§à¤¡>¾™ ¥ưfRsp0;D7E÷¥*ß|rláïi9 ™ù4eOơ‰̃ôK¥ñSX9¯®'D3bp~ Hª×HÛn`­.¿V°íˆMXï™I¢•N>×ÑL/UR51øöJ×ëQÛ)S—¡“¸½kâ´v«Fíº¡'m¶ k[Đđ=Ü»·›º—Y)ñ×ß4áN6ÙQî5ö~ÓO`U*E|í•3½µm>“6Ù5±̃™³û³¿̃°3?ÇQ^x:ïW0ÛE¯Øl₫¤%Ă5ت™êJÓ~É̀âùEƯ +ÚzC!}^·+Àé,ƒTÎé;›³—ûơàB¬e`Ctñ°†Ö;ÿû_- åÚá:¡¿¶ Eăç-úËó|º¿81=Ïn)Úˆ{̃ïZ̃6'ư©è _ºÈFM:m³:ºy`kEÈÆÈÄ_€œ2ó¹Hzø¯Ö¨Y\A6÷9gj¸¼ºkn¬Á`®:c‰ÜzÔ³»M§a,¤M‡ø¼4ÊĂÁÀd§pk” N,zLxŒ½6¤m[AœqÇoöëơ¢o­ï=â íÇtCeƯ?äÓ©y®²Y¢ëcƒI?UŒïDK¯Đ6ózQ•o†ƯḈÏ^yá%H×ͼ8¹)Ơÿö́9 ¹ú´rZRœ_K¨²¢dÜåLzDŒé7yóωëïñ¼—Ô^̉:Ö1瑩go]Û¨â3³ÜÄ1|÷&æ/Oúz+hÆ„¾«í3‘Ƈ̃tŒ&6̃n|¶á{Ơ™h뢓V‚…°¼Î† s¯÷ œÊ¿us8ç“R¦âËѵŒ2”đöđ5ù r«/(å¦A®̉ˆY4̃nè&“₫Ö:dÖ̃Ỉ.| 1¿óoLFaØ +endstream +endobj +696 0 obj << +/Type /FontDescriptor +/FontName /JVDJDJ+CMR10 +/Flags 4 +/FontBBox [-251 -250 1009 969] +/Ascent 694 +/CapHeight 683 +/Descent -194 +/ItalicAngle 0 +/StemV 69 +/XHeight 431 +/CharSet (/equal/one/plus) +/FontFile 695 0 R +>> endobj +697 0 obj << +/Length1 822 +/Length2 1824 +/Length3 0 +/Length 2389 +/Filter /FlateDecode +>> +stream +xÚ­R{·‰Ï4ÄẒkZ.ÆyØf3%ÄUí0Öp•Í +.JÄ%Œ„ȦŸ_?̉ៀ¸i0< Ưæm^ÊC\¹°zl₫fgƒp™Ù:û¶+ÂMX Eʨ,ưäJHÍ•Lí_Ἲpl²_Zº,¨91Œ¨¦¬ÔnW₫ÜúÜĂád +λ7h}o7h2B´ÓË=P½ Z~*1z!ze@VÿÍôês»ÿ̉6uüè­E¿ oaŒ ªâEÛuEå±3ÛöŒÉ]Ú«œK*nYr3a uûj¸ñ²'ÚŤ¬Fïåw´Ëut‰¥]ÛưN|*¶XsÈ‹!NđKËP +ï›GzcăFÿđ˜UđAú%4}úSêUlrG¬{û&ÛÇw—£p>¤k´©?¹ƯɦƯ&ÂNµ´æ…øÖé%âSûÅÆûÇ¥}ü]bÚ„oñµäñS#tjÊĂÈỈ¨Ù£RÄ­Wç£_ú‡9Q¸˜!̉ìͺ^ôëäœ:Ù&² +±9W®G8)‡º›mUƯh)lÓĂ%½ªo†>®i´M7¨ÔÚơă;Í.Ï-L+°Ñ³̃Ÿ[iP•-ïv]‘„Ơd}¿êᨼ¥Y{"©«2Â/öøIË+6LQ^1N÷Äk +´}ph»]*ßËSYbµîj,sjá:“)₫FôïĂˆGpU>¥’%ù>“¿‡-g®fÆ“‹Gg3̀E¾'â‹¢Ôe;DH̀¹XjNB—}”‘)µ :ôß̣÷dKçsÏ›öÈ„–ä3q2YNCß •D ₫µÄ'{ï1¼.1œ]Ñ4 ˜ÍIưĐSWµơ!ŸloáË“6–˜y=èaé/ti„̃Ó5Öë3™ÈW[¯ß{ëgơGŸí”Èj'«îAc;í[́ôí/ÊƯëß5pŸ¾Ø”₫ấ‹•£ê憾”o¯´ISGÛO–ÂOu½àÜo~^Rb1Q1ƠÉ¥Ô=́&é6¸#£S¦¨Qă ©£‹óù!Äëµl@Åû_Ú¤ +ïæÅjÏÑQDÑxÆß©K[ûêâê?zU87Ô÷„ù<äÖgÿpIĐXë¦#WY*5•È$_`ArK)ÔIwçßQ:7TaW đ]•N+ª‡(ˆM]æøû«ÍGÔđr:ûG­kÊŒl9cH®,xàEZ̃»đ¡jåÏ-œ̣~‡Ó¤Áije¹íP|æëÈí¨­K)-¾gl]9¥øHʈ2NáÚT{̀бHjă¾‚Â¤•VMØ̉:Ç̀ñ©ưµWŒgN©̣æöî`%ën¸¦^F n[ñÓK[IØø%¢§I²K·,ÄK”]Ÿñ~ñp> endobj +699 0 obj << +/Length1 798 +/Length2 859 +/Length3 0 +/Length 1406 +/Filter /FlateDecode +>> +stream +xÚ­’kPW†±U(AkG × ơ$Y0PÀKC¸+á@Q—́&,„Ư°Ù¤ P jQÔQDk­”ñ¤Å‚ +,,¶0 RµF¡]°SüÛÙ?û}ï{¾óœ÷;ë@¡#!¢Q§!äø₫ˆ ‡agÇ'Q˜ÂÜ ¦Pw¹¹A€§ˆ 8®îNw®+Ăđ ™Ä$1XĂ_;gr¼x”ÄD0üa*§gˆ`)" ¥Ô,À“JAđÜ +9Få(©D‚‚‰(J0œÁ#̣ĂÅp}ÓF²·’%å4XCC®4"BàR5@P1ƒ- è½Päÿ€Z8ÜG!• +àø¹ñó)½§Ăñ˜Tư¯ƒˆ—)(”₫‚’øBë6ô œ?`ø…ªK1—HQà­gqœ¹oLP$£D1@ Kåè|Å‘…(t|ó loÿpA—ư¿÷:/ÂN…¨e(à¼sÏ×Đ»N‰ÄT ’Ăâp ÚHoÿ¢læ‹Ă%À‰ë`’„Ơ úÑ$AĂTPM̀fáE/t4 &HÆÜµ:6,§£Âäqô­Ä̀‰ó}ˆăØÑ0ù®Ø2ÚF "§ư(2¯¼pOOB•äèäƯ\hr®®\ÍŒ"ỈSæßßÛZŒÑ‘£¨ +1z{‘GŹɪưߦxu\XÂÖŸn®ø£WïFxuÊ Ñ¹ùAÖªøIá€öp=3®Ód‹È#×¼º*[µsü¼áEmfAiøÑ=Ü:Ö¯B¦úë̀ËfíW?ñ«O;•—>`æ^G>hëĐ;n›Ú¼4öÜ^T;Ùßc°b]pÎ:S×̃r½¾EÆLußă»VcƠ©'›6Ư¹¿Ơ/)÷É\Ư)̃d=¿bD‰•öAx7»‡¾2A^U©±È°9`÷gƒ°T5‘™b–t¯E¦ḈÊx]8‘ Ï¨³đ¼Ư×QŸÖ4À>²Ç·Öb«yó s̀+Óf{Á # §ßùƒËªWµÆ…^ª„ü=¬gZ’2U +Çå];ná5’˜PV³q2”™­a}Yu*âyqM½AOÍJÈpsw/ÿÈô9}A›n¦“¿Bụ̂Dùá§læĂÑơm=¾Åƒ{âu–®:›u‘û̀êfß|Øè¶ Jü¾lKẰ§Ó&≂3‚ +ü‡i»eø†Œ•)z/`n‰ÅG÷f&•ºÔ3:-ˆ®ï3é¶½÷âwmyî¶T﨑[¢/¬<ø·omÖB–e™a©­—ưÑ+“—ć ídôDë’Øº¦‚‰û¤>åW4J8U\¥×t–îuQ+å&¿ª5Ô[æ‹79¿<0²«âÁ́†ụ̂~“ö!₫u“ưăºùæiy\Û|!x\ó‹ÑÎûƒOwT87”T.^¹ºđµCû…ÆƯÎᬦ¦ÔX‡S›6‡D:í³‘ˆÊW¢%cuƯ–ÇdÂÚ©̉4̃1ÖLE[Áîh̃äPcË£Úé3:üŸlÛ>׆èE1­{ ï†\üÙ·!½Ù:Å\î±Óà’A¬£?;Jø¬ÅdÇñ%Æ-טwU»l4₫îºÖx«ä£ĐÉóđ`@±UỴ7eQhÎsơpYdéáœfĂ®B+ŸÅ“]…UưdrÎbiEiÍ¢°½±đ¹ù!í̃™ *÷¢ÆMèhØwîtá¢̉ªä¢Ñ‰&¯+ë’R>K3û0T?Kó=ơÆ•‘­¯˜ÜfÙăæ6bËåiyfË> endobj +701 0 obj << +/Length1 750 +/Length2 628 +/Length3 0 +/Length 1146 +/Filter /FlateDecode +>> +stream +xÚSU ÖuLÉOJuËÏ+Ñ5Ô3´Rpö 4S0Ô3àRUu.JM,É̀ÏsI,IµR0´´4Tp,MW04U00·22´26áRUpÎ/¨,ÊLÏ(QĐpÖ)2Wp̀M-ÊLǸSđM,ÉHÍ‘œ˜£œŸœ™ZR©§à˜“£̉Q¬”ZœZT–¢Çeh¨’™\¢”™Ç¥rg^Z¾‚9D8¥´&U–ZT t”‚Đ‘ +@'¦äçåT*¤¤¦qéûåíJº„B7Ü­4'Ç/1d<(0¤s3s*¡ +̣s JKR‹|óSR‹̣Đ•†§BÜæ›’Y‹.ëY’˜“™́˜—“ª kh¢g`l +‘È,vˬHM È,IÎPHK̀)N‹§æ¥ ;z`‡è»xEDDiCb,˜™WRYª`€P æ"øÀ0*ʬPˆ6Đ300*B+Í.×¼äü”̀¼t#S3…Ä¢¢ÄJ. QF¦¦ +Ơ† +™y)© +©@ëëåå—µ(C¦V!-¿ˆ ©–& +ú9ùé ÈHú(Ç…é'§üj]]K Cc#Ks ³ZuÉ¥EE©y%àÄ ?-ˆ©©©É\7¯å'[·dMßÖ¶²Îuñ…U¬úœ?O¬}y“ư@ĺٙ)µÁ¦óÓK–¼Zøhkßañ́‹^ÉÖS…‹¶HöúơÄ}Y$¼fkׂeL÷ëƯ¯lîÆûO[ư•çá°sZI[í/z<«SYçæåú<óR^8E-̃÷ữ5n!­ IZJRæ7W°ße¯¼ûüêiEÎæyÑA÷·'ÄV/ ?czÍóÛëTéær“]<–·{²TB́¾ÍÓ> endobj +703 0 obj << +/Length1 751 +/Length2 632 +/Length3 0 +/Length 1151 +/Filter /FlateDecode +>> +stream +xÚSU ÖuLÉOJuËÏ+Ñ5Ô3´Rpö 4W0Ô3àRUu.JM,É̀ÏsI,IµR0´´4Tp,MW04U00·22´25âRUpÎ/¨,ÊLÏ(QĐpÖ)2Wp̀M-ÊLǸSđM,ÉHÍ‘œ˜£œŸœ™ZR©§à˜“£̉Q¬”ZœZT–¢Çeh¨’™\¢”™Ç¥rg^Z¾‚9D8¥´&U–ZT t”‚Đ‘ +@'¦äçåT*¤¤¦qéûåíJº„B7Ü­4'Ç/1d<(0¤s3s*¡ +̣s JKR‹|óSR‹̣Đ•†§BÜæ›’Y‹.ëY’˜“™́˜—“ª kh¢g`l +‘È,vˬHM È,IÎPHK̀)N‹§æ¥ ;z`‡èû8z…†{iCb,˜™WRYª`€P æ"øÀ0*ʬPˆ6Đ300*B+Í.×¼äü”̀¼t#S3…Ä¢¢ÄJ. QF¦¦ +Ơ† +™y)© +©@ëëåå—µ(C¦V!-¿ˆ ©–& +ú9ùé ÈHú(Ç…é'§üj]`ºÓµ45T0425R0·0ªEQ˜\ZT”WN-ÀñÓ2¡˜Z‘̀uóZ~²uKÖômm+ë\_XŪÏùóÄÚ—7ÙD́¨›™Rl:/P1½dÉ«…¶öϾ(á•l=U¸h‹d¯_OÜ—EÂk¶v-X1¡Át¿̃`ñÊæ®i¼ÿ´Ơ_y. ›1§ơ‘´Ơ₫¢Ç³:•un~Q®?Á3/å…SÔâ}ßï]ẳ +¤¥$e~sû]F1ñÊ»Ï/zÊíO]Ù3ÿÑÆó½EQ’ư^ÿŸÝ^¶Q¹íøgíÅ×ôI\Ưä÷LèĐ!~ç³Öy?hKDgêV«ï;®É÷₫ÎOư©w_dÜăæf|üfÇçg‚û¸₫81Çú`¶©‰óêü´¸5q¹­ë•ê-Ûa·ê²Kô¦_j‘»•V^,•u₫ ÷êŒY³uU¾öíx”ÿkÏƯ:›K©¦—|[[äèɸŒoÅ_;•¦˜œ +Ú.í)»çG¸«DǽKÚư|æÁ¶3®Ư£]ÇwÖºåÁ̉0¿G"­½ÖGÍŒƯäÔcÓr½Ä„m{¬­_¶íËô}çé?áÚúçũz峦̣ÑGlÊ +'oúg¬ơÉÔs±RÔơå*Á%Ï +endstream +endobj +704 0 obj << +/Type /FontDescriptor +/FontName /LAJUWJ+CMSY7 +/Flags 4 +/FontBBox [-15 -951 1252 782] +/Ascent 750 +/CapHeight 683 +/Descent -194 +/ItalicAngle -14 +/StemV 93 +/XHeight 431 +/CharSet (/logicaland) +/FontFile 703 0 R +>> endobj +705 0 obj << +/Length1 1612 +/Length2 12917 +/Length3 0 +/Length 13748 +/Filter /FlateDecode +>> +stream +xÚ­weT]Ư’-îîÎÁƒ„Ü‚Kp;¸»;ww×àîîwww'Øăûnß¾=îë÷§_ÿ8ćUUkÖ¬µÖ̃‡LN‘IĐĐZ$jmåÀÄỆ̀đƯÔRßÑ^ÆÚJId́ø0r"PQ ÙôL­­„ơ@Ÿª C€0ÈÀÆ`åááA YÛ¸Ú™›8h•Téÿeù+ ïúOÏÇN{Sc+ơǃÈÂÚÆdåđñ?̃¨L@#S @HVî‡Äw1­Øwe€È +d§gsÔ·05H›€¬́At#k;€Å?k+CÓ¿J³g₫À´è́m@¦Û@. ›¿\Œ¥©½ưÇ3ÀÔ`l§gåđÑk€©•…£á_>́FÖ²±³₫ˆ°üđ}€ÉYÛ;ØØ™Ú8>²Ê ‹₫ƒ§ƒ‰Ă_¹íM?Ük£HCkÇ¿JúÛ÷óáuĐ3µ²8€\₫Ê¥ÚÛXè¹~ä₫³±3ư›†£½©•ñ¿0́@Æzv† {û˜́¿ºó¯:ÿ¥z= ׿w[ÿơŸĹAF̀¬l9 >r›Z!ÿ +#k+Ë?́†6ÿô9́₫ní_3C÷ABÏĐÚÊÂ`2B~·vøH  ưŸ©̀ü¿'̣ÿ‚Äÿ+ÿ¯Èûÿ'î¿kô_ñÿïy₫whQG ‹ïz–đ đqĂX¤Ư1zvÿW¸¥©…ë³áßUAÿ ùÿÀ‘pĐûh† •ñ‡ ,̀,ÿ0Ú‹º€ åL LFzúÛ®le²³0µ}(úw3L¬,,ÿæS2150·ú«ơœÿp¬ ÿü‡HS₫–û&¯ÎđïwêßQrÚ;(¹Ú|ûRd¬ ÿsñÆ·oÖ.w¦ÈÄÆ₫ Àơ‘›•Ơó¿Éö7 ë¿Ö2zv¦.’YXÿ.ü?~ÿZiưŒˆ•µá_³¢è geø1^ÿiøËmàhg÷¡êß'₫£à®ÿtÈd€°4omÀ`–œ–âP…›50&¬ÑÓÅ +9hST«”ŸëSaƯé¼ÉS¦ûRÈ\7₫ù­ÙuîØæuW’~o¨ Ç‚¦3tCäIA׋¾FƯú‰aϨ]„œr¢î~1+½¥ÎÅ¢²·5&¯ ]øC<̃Ênwñ@çCá”ëƒEyoƒâeT…Ư†V†Q•w|BwøpOÓ7<8ĐßyƯ½KÈOÅë…Læc›I( ®\æB“RDxƠrñFªÚá®MEI@j)ưGÎ8gÙªEú%:¥E€/NÆN¼i÷—ÎåôxŸ`Ü8ÏTÖû#•ˆ=._=ÑoÿëIsJÿ‰4Ø’;ˆKÚû`÷*Ë +ú?Ư(Y3ƒ̣mE5Î0»T,Lƒ!¿P„ĺ©Ü4¾I™€^3‚­¢úîgUơù[»¦̀+O¤ ³´́ª̉đä˜~aƠsåéƠ] ÷₫–đ¯¿Tÿ>*NQp"ïÚêuæÔCHSâwϦ¦X| ¬+Rnk”Qzˆê(hFm6!œ È¡ôâ‰C +¦Œ¦@ÁÑŸIù©ñ~Ü{ê²n…‘\väëv䨇C09“̣9̉ă–æPZZªå÷[©KoÔØ+#?—$’ETØ>,¡Œ§óụ̀Gá„kµ₫AEЬµâdÚÉ~œ!÷¶ë‡6Ö1@tC6FˆàkKÅ¿q‰¨E´%• w4%#D=Ÿ®ÔÏó¦›lǘ‡dÛ·8¨=É»> I‰kö +å~”óJˆ"Z|±2BW̉ăTiBûCz̃l˜G¥Äôđv¸>€¿0¦jÂOF‹™eGC±5¥CÿxÉA>Q¹âØ×Zpk·ºË$#5d#HỠ$®Í3–<ú€|\ó;Ηx÷̣“8ûvßÎ)VŸ8–W–dê"«!©xEUMYơ£cG·æ; —Ö¥n~ˆ¤Léq,Ị́^t/)® ;t)Ă½[lEvXTà»V©À×™&Đ4{ˆ ÿ*ü¢±1?›†ºµẼ¥Z={@¯F¦úØ ¸Úuà“ªøọ́ål`ËúÙÈFÿƪe ¨d™tukp6Ỷ…₫3zÏ ¡Ç º–{G`B¹5×6ÿ́ó;¼¨\¸ z—Œ EƹØíPaÖ­^₫Q‰b¬±_Mw]?,=G9é`UPO…‘y¥D4… íüô-̃.²çg¤<ÅeÈ‘\n Đ€̀í2ó›ëĂ\s"G¸,Î0˜°¸47-kx¸ÆJ8úûÑ÷Ă¼˜ }́Ñn¾gÎW=´o$Œr%…ÂÇQºï së–¡94öă8¨¨ó\h ³2å·ÜRÙđ‚ÏơàP#—ßê˜&\÷ÍN₫…ÈÔƯ¢>B”c%đÚJSßv¾C@Ñ´á=9©̣ºçû ;Ù£ñỄ¤°úî;̀N³ùÔ8È”$>Ä…ơFôtj¯È®’‹ )“8"c˜5ï¸éP»†ÄÍé`¤0¾r%ç‘f>Q2̃đ™çă­¥¹! +«…Z—©._”̀«)­X[: ẶO-zz«—%cươ†²b×+”‹9_kE%ƯWlê¤ô%æ%èAaÉp}¼̉yʘLW%)%t¿ü=ưa¤{‹7篡0²çƒ²AƯÈŸ.äzR ¸B8+£»£TK÷¦‚ö]Ư†fèi|ëæa,NùXÙ„G’-Fơ,¼¨1̉B&œ¥&3ï[åÿ?U€'¯`ç\Äb­,ÆM»^£J¬†ë0 +)z­ZÜ +ƒ‚\†ßÎ*¥$Ûb’Ø:¿P[x9_rM6vP==¢çCơŒ«;ßa.ñs+×ÉưÉ™5פ&¥6]b7|₫Rge9¯*Vâ+Yî;¤“7ᦹ3àfû ‚̃’¢j£à{}Ñ9ù̃;[¸ëzËHáÆ©¹œX S ‡X®ökuM†#MvøI›µ¸2éùªM¢xàƯ–Ă¥c@JT=]!¯;xt¯²ô¥këÔ%†4ÉQéª%ơƠLUƠ‘« ×"±–Ô×Ă#¾à¨â'1ÄW3%¯1CQoe¬_›B³¶$IæĂH‘$D'ꃪ„°.]GÓjË05Èœq‘ö¾{®̣Fßø¿ô˜°$ ¾äRWUOS©¼¢ßơ_¢çÁ‘sABרC–…Ÿ´Á‘¡pÍfb{?_Óư–y!ƠưÆ|Đ’̀²æˆm_YÔĐÑëá+‰y&Z¥£ 7§%́xÄ́säJjq¡¿÷Á.8§ÆñúÀƯÖzgÚœ–>ÇÑ'* ‚±ñ“\È é=NÔ#Qãdû,îgE‚’›8³›?mDQÑKbvĂNÔ)qĐÜI~ÀIÉ)²̀`Ễ"Ù£Oî$Î(«Ç›ă¯»í Ø®âe’̉Ƭâ)ÈO×öViâm<™ó¬ µ%äw’+¯¦#•'Q€c~©D¥pnX}JgKêqă®¼Åbó̀ŒWĐë ¿9T‘ï>]¯‹brÔnï^A«C}MÎ|z–ƯxÊÿƠ`Uaoå²ö¾̣Åü¢t­ium<+&ƯºŒ̉+kcĐIl-rÑdMơ=¦K€ +Y¯¬¶/ölÖă,”’üåÏĂxJ±röHíœëÚèđøç{5?n6™ª6_QÇ•o{H_̉oÈ‹üqK óÂyô LË2¬ît™y(“Ùú¿Úx™I¯Ág‚éШt¨Úù}‡d ×w,²́iiádơOttËÙÆÁ€W-Q†$ár33oÍ\ +»’תxØ?ÅÄ~“e?y¬˜—4È7¥Á–»Î6ϼ„IŸÖ2]rOlîç¶Ë4~DCàMH)|uræá°•uÅÈiq·VÏÈh…Uc¡²Ô䡯^Ë(å4[ù¿ç €̀Ù¿",¸Œ¸ Uª¾Ñ±½H÷_1…,.‘JÓ7×,±üfµ¦¤é.ĐrL÷–ƠÆÜ°=­ÏÿÁƯ]¤k.EíêZ­àSnïJ>vŒyD/@[/Ü:lḾ©„Gn-cFcM| +Xy%ƒÈlNΔ¯ë"~t`6qg'Đơ“¹mg̉brú~!éƒYLH(Óëo•â¸u AíA¢Àưô=¿\Rœ'!¥‚—tŒ(ú]±ơûg L²ZP&º̀·-l¤Få0“1>D+‚Ū]*3'^e3³2{=øäß-äṇ̃Z‹¿¥u²[d W»Çë³=ZF™$Kfp Ǘα[·¹0@'E¤Đ%Ä1-aZ Éx÷Ø̃ÉO²•²Mwê₫<ƒ'ÿơ¢­¬ŒnăÿœÀêlT ÖC̉*ÀK›t‚vú.»¯÷ª¡Ø¤¹ç§z±̀Nω EÊT”<Ê#oUø.>Æs‰g—øø+ +±\°ơîNàá@JÓ*Æ3Æ ½Æ5¶UBÄκ‹ă^î©I/©£Í²¹®B è’ă²ẸÄÓ:à<§ 4̣ \vÇ=9o¶ÈÍül̃ưØƯ„#‡ß“¹¾‹:¡ˆ?•îèˆ.j=¶ÑœkñX_ö¤pB¬)*ÿÓ¦´ŸI®×›üOS!_Â$ÅB·J3¬5ŸƯơ½Ñ 3„²´Ơ™Ùöĸ¨Ÿî×P)®ùRnm—Á¨£4·m5ø™káofë¥A±¡ăz‘Ăî÷&÷6Ç®&úgÓ̃¾Ä¢¬)\–Å×ÓM'dÛm9%[‘JK²iÍ­‚ăª0%û5ùJ_) o\ê0† #’h ÆQV]Î ^!ÚM0 ›x̀³C›7Î)öÖè>oÓ R:đœÉr߸C(‚”@%€QƯÚùT¿ÛXâl\=³₫ù%ºßj¾øi€v´¹É±¥ú|F®°+Đ%›O”ƒ?u¿µ‡&£%`nÆü ¡—Àq¹ˆN¹JÛ°Îr6ư“EbÑ.¸x­g¡yu[vd̀qÓ&pŒc,‹uAI Kó¸mbŸ}ụ̀³&öË€æWóPÏ’5D¶ïƠ>|»Äcôp„1÷ÏmÊbü®:Æ₫¬ôß„Yñ<ù %w6ø¸»_o¡iÙkîseñÉØÙrO¯ỰGi†É¨÷{`£ÓE/Œ¿ªTå•e¾)s<Ó“åiÁƒkĂ^:º`ûá &ûÎ( +EƠo"¬Áỵ°•ÍlbM7ÙH,ê«pêPÈß"¢£ø²^)WĂ,bœI¸÷BrǸ‘êDP֟ߘ5ŸỷP•£¶¦jŒ“uæ[L +±l̀ Ó́'MO:”©f¬½ơmƠˆ( +³wLấaó„ßÍÚ“Líuă‰̀‹ cL[VôÖxæá́ĐÆÉáôgî’”I©U²=Ùe- +Óơ·ÖÙØ6‡„ûê^êÏêôñhÊ Ö¾|r§´’†Ư[ØÎ&̉‡ª[·D:fă-ê +ƒ„`ñyÚÏɆºßj>›@æŸÿMÖ`Óï€>ÙíôH@O.x›™íÔê]œ‚Dë¡4đÅÖÿX-##'5°=$k ½¸Î́kÓYAO$¾)g¢ƯcÛA­-÷Úgw[m௫’ ÉĐC̀°»ùơ@Ï^{;ÂO©˜WơÈ/4R:ÛDío¯h1ºȤ̀_QcÜÖgDßzÍø˜X6ƠÙư!Úg{"~CÈn÷Ôd¨¬#µÈđRª‡Eo“á³#Vn ÿp·ÚĐ@ÅƯú:F̉##n€Ô†á†™uT‰~ÜJ¹~¼’HÆnîù³ëÑ¥óưŒtÆ›.øæÆI?üi4}|²“ß<‘Œø0k¥‰cÓỜ;.G®Ëc£¼Í *•¡úö_E„¸›b`Lq%`ØÉZ’‡‘øƒ™ ¯c¥iÍjWN…p˜găÇdv‚¾Ù„® =‘;×2ˆtÄ1Êú.Å]5E½Ư`Ï(6Ä›´̀R¦̃'¿”LÖdæcOÉ©Ä*ău"à,눔o.i;„NyWÔjë76 ä´ă²éÉư~GNµẪ^¨ơEù$đj`‘äƠøÅc09|£³£2OßU đ¬`ª̉¾üȼ; œh4ERü*Æ^üö›+ÇvÆ\˜Å~ë¾’SÍc%Ă;º'ć½àIàUCÍüAx*Âù  D²$%½"ñ0‘<:°“¾S-Hkö#~N9)í+ƒ¿,¬È¢ă/v'wo¶ĐÈHEáóø7…Pö¾CQưgHBñ%¨~ dÆ “q7éôUrK“† Aăœâ•b§áº)Èdº¸È@Á€âIÖ̉}r̃÷"'ç¶8e0;€Ñ%U7́ ›z*µæÀŸº–+$»\.êN‰¿9Ư[$]  Î"Û+‚Ơp₫b êăû:KœgYZïkç/ƠPÇfƯ¦÷₫MÇ]ÄœÆ̃©h+Z2à"¢j¬Ê9nqDÏxàÑÄIº›ëÆI‘(ûă + k|{É„…Eù'ÙöˆúÈ«C¢¼HçËÊ:Ï<_1ÉGBå€*¥‚³„‡uÖöA»£D̉äæ`>}h¿?¥Í×{4Ÿø+Åù‘N—#¯²ư†ù爋³ëÅà„‰÷rr4± +.¾^V¿Æ™L$¸bZ”æÔ!ôZNÙvHÉ©|¢¢n&²§œ°ÅÜzggk©’i?ÑÅûéÂ7 ~½N?”ï³7 ›ß` + Zü¡ï¶±;¶ÈRØ¥ÅR¿‘&#Óvæú¾ƠOO703̃îàö[Xù7˜î }3jạ̈o¶óÙy»Ó^5áŸC½+$§ÿd1¡~V‹¢¾×ûStM‰7 °À¯~Úœ]5Ùv›’ơÉg t Ư¸:ßá±R#Úˆe! LQˆ9¿ +2P₫éDĐCª=åúË_ú÷ïh5â5lNç0<öđ°h!8…:éY¸McÄ(ß9G/Ûä€uŒPX ×|@¼ÙÚÛ®̀ë9w‰ùRĂ~ù†X1NJ‰w!§ëïS„k°àđèûE¿¤ 9~PIµh;n₫ô!:†Ơ·†₫ +÷¢ù‡ÙàpXơ c‰’ÏC›‘ÅGËón8ô|ỳÙûƯùñ8+Œ†&̉gæeZü-n˜½WÚpߦDNRëFDé’SZȯr€p®…·ø¸•î×M©“N-ÿÆÏhQ,{²̉ÆV́_̣ +µÂ&ÊøĂ_îxÉ$̣¾%É*'ù”đQÙ–Lä̉¾usäZÿ|Ûe½å©¿6Ă‘̣¸¨Û{Úô±§>ø~ÁG®.{áaĐ¹ +]Yëä!åñ>ị́ÏP›R¹¾"‚ŸsVˆ­_ºæĐyjz »L b7*_»ÍÆÀ Ä¢ưp×î6龨´€Yé̃'íS“{`¬ñ†…̃đ +k̃âơ}I›+ê{¿ +·́zŸÔäØü韶sI§pvF̃8ơf÷§‘¶u["Ë₫ÙÔäIf—& +Eº5øÑÖ|`•*@œ¶ÂbX~XPV¯†ÜïI+äS![¢ ½Û/¾‹:;S 38±%µ1(Ï¡­½çR)`Qoº+t÷ä@©LÊJóƒp¤º/¶M°¡’8ƒoÇ/ơî̀?gƯv VM†ña÷¸ ă×¥\rÉD…†˜ö̀ÚCÓ"íù7\)ù*‰‹áH̉Oö ڮ⌒'ù)Ó³Ó¢læq4Bi©C½?s ׯ7Hæ¯")¤ÇøxúMx6¾åƒ,hú‚dï“Ƀ³EAåŒ(‚oW¬£’sçp#lqd¥Íƒ~ób%|ÓA(ټĉOCS¿Äd.fä>n»ˆç0CU¶ªØ9ç«@‡fiYd́ăµf^ƒ÷îû1<ù’1a™˜[Ôøk8ת™BÏ©åM”¡’rPk₫ăó”°ă«•Ë¢‹NK3¢ú­˜ǸMJ^₫¡•X/ˆÏ—.UaºÉ«(ƒwd‹(`”‘gđq$kÉ¥ŒÛe%W”CG€„ú·•‚øjB‚óíN–ƒ¼¨UưüU῭M›2h´ß÷:ÓđÂÜXÖE>swߜÆ-gˆ>̣pÏ̃c@bvÀ†ä'±Z.Å,Mk<Âñ\>»G0/TÄG=I⟠Û'ê]^û¤‹Ä½øyÄ̉ó ´RÎ –¡g8·§‰×à7E$ÑßÁ’w„;³qUhăÊ ăUŸzæëÖm—Ñ5æ(H’…o÷ôîóƯêʆ÷z‚›58MâÉ3o‘ªÙ±k̀Ú₫ơ’-÷‘3”#@dT­̉\ÔxÁëẾèèÔùTËæ·@Pa‡é)Ë„W‹ œ¼¾iÔÑÛÊÙ{#%~»Z(§5 +ë|·æ”úºI­ª$L2_Äü“:ƒ°=Å3ro´ ¡2À8’-WZƠ¬>µÑ6³¯ÙÛæ­ÿÊöûÀ^¦Đ]Hâ¥́‡ Æ%ư”âD‚GÏÏZÉë¸Ñzåé–¥~mưI0û©°C.Enô’f-5r/–ÉàTZ¸…ß‘S‰¶ñy&ÂÉ7Rü[cSô¾û¥ F°dª*–Û{X'O‡5®óBBÆ£±̃\sï©flæú£·§á†*Cª~1×ÅpèŸñ"°NCéíPp r-º¡I,,Ư¼§Q¢R7ÈѺKágÖŒĂe8œN’‡| +«úVL‹\4ºõ¿›æ„îđÅlm¶ÄzizœY›ĐÀKvbüY¦f&…”¢ÑưYƯéÉ«¸l+-+½C̃7¾b—¼²ˆ?aŸ&6/X+âqçÛ–p‡¥ùÄÆ‚*_lÎt ĩ¸>Á‘áMÙ¹°2G¡ưÚ:¹¹rù,¥ƒ«1tÛ­úÀût9‘ˆcăklĐ<¯£Î5™–Xl?¿', x±‚ở/ lh»µÓBzÀJñIƯç!–|‹ó2äƒuK +ŒÓm  ĂWÙx +­Í¦XF)÷饫EmˆÎ×ÿ’ /ă˜€¯+Ø35-Cwñj̓…*º²0¹€ĐđƯ}̉4@’¹Nüe/ĐÚ°ö×Wh5̉ñtR +RüóøP–˜9ɱ ¿(8â´®•̉—4»ƯÜ`‡RĂîGN›µtHŸô­[¥› ·Ùú +L£@®&Ï8BXuD¢Ï Ä)9÷…u˜‚h7?2"-ù=î́JôQÆ¡pÑv†á®Ă@ø¡×e[ñ₫l>ăv€dÏH4®üLƯđ“ƒ¹p^i¶>qv‹d$%S?Ă+à †ï ƯkƒE“è”ÓÄaÅÈ£¢®¯ Ï&–ÿz }UÇÏ Gf3€â͉íúÚhÀ„Ú}))å×ïK“Ă(Á_«qpqƒj @æK´7® +¯ÓJÊr8ÚU2:¬û₫˜ÄI{.v8“42wœ³ +n µ5­G¸†KN‹̉ _oL~ë90‰F1,•eè“g…đ¹ÜÚ?̃×Ä¡Ö Pûî2(Ăö·gÏÎå0±pn­oJ¯CQ/À#©+F`ùaHó°Ẽ§8ëJ%YÀ̃OL«‚›å½ÉºÏ7g .Mí¨È=i V8™àW€a:#oƯ‚ÙI<†npưÛââѳïĐÉXƯ#úbè÷RÍ̃Ña%́˜®“#?4¨áú,m|.³?9nǸ‹–®ä~˜·Íđ8§”à¿ó±Â¼ ’ŒÄfXÖ£üœv* sÜ\M÷¬ó’ưÊïüê·T'^€oø œO9nEŸa†6HûêB vH„c̣œp“$°£ö>°ÚÏÆ:‡Ê»£ưÑ2kû"nñwÀ$êQJÇŒđ(˲p”ËgÏÅoï³=ÇVßatÛø”¶ă'ä^ưm×pÏŸ;sƯ9KN$RWæđbF´h-ÊëcB¬JrÆ]Ơúô;däÏ9aÿ₫¼EíÂFe8tKÏ^tŸL!FẸ́Ü>`đ1 ĐhFŒzø–vôÀH8íöÆ̃móÁ _ƒ-“£Yaœôf ?.±ÿfgͬdv 'f÷ y‘?{âéó]ÍïƒÀç>Ó́ÿ²å‹”ÁđyʤKI_?4¶É`Rj̀•oê¤É cÑ1¾!L0uA3Đꦫc´}F7´…Âr©ûöüSâ¶Ä.x6ñ +Tî g¦ë÷°—Ùdzđ‰¥K'çàúưº'xâ‘à÷PÈYa‚×ø§Ưåçv;©2Ă|̃È{QA·DOñDèG)Îpro\ +¹13 ½m•6i)™Y,‡ÓŸm ̉t*±L51»‰ê‘µ£,ù©¯ÖP@D³¶À)µ̣ÿ¯; +_̃"¨,'7o’‰c8™Ưü^ ¨ ×àào9`ȦS8Ï_k̉¸w›_<“÷̣²Wfj:&s#*©Z«Ă!₫l-4V0‡\:'p•đ¸ ³¡¼'´̃èƒñ­ ơ¡r“"îÇwëO'u±HÆ’ >™_ÖœQ 5̀Wƒ[xöƒJÍX\’€o¹±ñù?Ú“í@S…sàƒ%áz1 ) ÷´Yt:ÖˆOyr…éÚ¥E5‰¬†»c"m} î87ªúáXØí**üµ¸ÊskŒVF’Œơ4Å"ÆA₫µ½áJ\µĐ"́F8Ë;J?NháÄÅä„fƯ[ç)́1ø'AiyđÚ̉/™ĂI3!¤â"úäÓ‹Û rqé†ûˆñ?.̃;ÁSăNé•ñw¦Ë÷½^ôÓfĂ´¹ß4 +5}Â^ÄñµRcCdfi&gŸ¯ØtV̉`úg7C­ ’oe pÇ¢†yH‘œæ½ç‘Ü”ñh‰¨©°­û®>^¯‹Œí•8̃³í¬‘U69̉éz1ú‘Ằ寴Œ̃Å÷́» ¯½̀Óu܆BKë|ƠVtRé;á.‚E’Sô5B@/̉7!¼U’Dúh).üïy „„ªÈ‰%Ơ³§¯©!,dmí[%°HVî±è˜'<’¦]G˜d‚ÜÀë@v¦ç &I íZkôw“µœü¿ƒc^ÿX/Y+‡y&MÇ.ăkPNŒ4G”ùpºÎ÷L ǺL6r\o‰3`RÂ"q>̣Ld(v‡s¼u$G¡.Å̃K~«ö¢êÊG#ê„t§Ă±mƠÆ2ÇÈÊ«éDIKóĂñyÎ!»§µ’%QÌ6)Àà¥Ô›0¸i:AÓÙ‘Æ"ø¼pCX!‹Z—¿Z{æÚV°MÊëÑOöƠºU`™æë‚ÏhÁ<Γ}Ë ›ˆ†^ ;́¡«ÑTP#í|w—€ƠW3*½"gñk‘́¸<–ưR%&¦.‰á«‡ ×vê­cᨉIErÏÄ—y]ym~ç…₫t]ÚÁØ,ßÉ«Ù*¢ơÓ…L¹9†!; ¨•w…ôבD‡Uđê–Ÿ„»K¸M—ÔªÓ]— 8 ëj£Î•ä߯~I0Yˆ±¢ˆr7„záñ¸^¼]s=T‰ŸÜ¡ƠÔiCàW›ÅYÊ,#j;u¸Ë5íÖ0ĐÚhE¿'©0Bá˸Z ?•¬Æåq®̀Œ0S[H¤Å¾î È+C QU×z™¿O椸 +“|XÀœx•^‘c.!#£X»P’~Ă:̃3  ü\đ~ä;ëI"Ïä*;‰CbB°ßŒ2Of|ê~Έ̉f¾4Ø={P8Ö*¥‚´’MAQöÚ@îl:…©₫r»”\ăÏgT¤>5_tô 3› +Æw+áá₫à^Çơî8諃v]*ö¼Ư÷úç₫ăb̃1}»ÍÆÄéëÑ5tZ¢‚Yxé7|TœbÈô2E´Áÿđö`ßÛîMÖMF7?…# oƒavS^¬|‘Œ_BF.**ó“ÈÀçλzh‡‰¹0³¶÷ÄOyđY$Ö6Uí÷qŸéÇGî́ט̀Œcu]|Ä—ºë0h'ú‡“¶Ubû£6g>i¤éé¸0ăhM÷¶U\¹ÿXôï+ù-öÇđ°ï}Bß¼ÄĐù÷«Ú^]|–InԘċ?|̃(ËÖ:©/—<2‘ŒÑ׸°Ö°êê~Ơ´4=[„j˜ư÷ëæ‰·J=*¹yë_ Ù̃±ĐÆ{Œÿœ(’ÀpÚªèd®́^^H<6t2[8¾ÔÓ‰Å[mÁÈ)]KRIIé½|sO­†ĂZeee½ǘ¿X}IBÏsIF! ’2,`TÚdI?œÅ¯r¾úî.*öĐÏÑfêqÂí{Ózb- “¿lø­8Î̃\u=MRü5“s(jèɃ¢ŒŒf hJÆ;–A'oæîîú\Ă.Y¸³°& 9’ŸưǽM?0)ry¶̀K—ÄÂ/˜ân¬¤̀ª£¢IÍÇ,ánÅèa7¾Åâu©óŒ{ü;ÁÁajˆbÚƒ/yq7*[½Ñoˆ…æ[K-Án0dB·Jy5JbOỏÜæ›´”d›Ërüú“]ÍÆX«[¥æ¶ñ¼đsj!Lh€„)s¤’ù@’à!˜kůOƒjv›€h›ơ¾˜Àưă¯¡öĂåÊç¶ôx$>ưÁ£xăMëÆ·u^ưJ/eXè­¨ùrđ-°Ă[W¯I—SWLÿZâl8§ H‚*g!7t9œ₫¶™%KÙ ›óîơ}¢Eµ>`“ñ:jV¸C&QL>;*IJ ÷y´ơ|‚‚Đ‚ +U;ü„"µIèbpa¡đfyÇâ£íDB‹LĂÆ’;§Az>·BíñưQæ̀fh£“5÷x9TÁ…r%÷/]ÈsZrÓ Ïë´Ô°j̣Œ!ó̀êæcºù₫¥öCryǾÉÜ©ôƒ‰Úë•ÜUö¥Û̉ôÖGZù ±%Jsøh/µ¿ĂÉ̉P.M”ï'T$­TêLî…Í‘¬÷œˆIT™Kà9ĐƯèºX0)‹åÏovéd+Ô2>¹ ÚR[X²&O„XÀ“e~¯d€”Jœ¯÷ñ" ̀V'ô=GÂ"é’ÜíE +?pƒl»Î5’º áđ=ycÿx¢çtt[Ÿ§ÛÀ¶’f°0·-ĂtóC]Mrư;•‘óWéù±­đ:âЉQ/"ŒÓß¾q ½}>GY-K ††çÙ>ñÍ4Ûô b›Ÿ½PøgË …Eæ‘LúJ‰2Âɾz6¸qEy){¨*g#€–÷›U«‚doaô lTÀ[hhv€=ÅcA”$ ÅL9¨áV/GĐ¥%Ç·D¹ Å½Å:9 4ÀáPËâœö +jÖÏÍm₫DÊNËÍOL T«Å€ú•ɨÂ_l8,*́OŒ*^سá[‹¢¿ªvÀîÓô˜ñv¦ºS²7´;ëGøúrL4mVbƠT( ›ŒÙĐPĐg|µÎ<ü} ù\n7g™2öưqỊ̂À®q!7¼s°’«øÓf-/~K‡µ†Ÿ££̃K ‚ÖV¥Ïa‚̃>ß"cIđC˜˜C×RH€̣|)đ̀ï}ÿc?°æW4)J'˜Ö…\ø I"oÄ +dzfî6Ë‘H”Gâ\{^ ;ădO—R#Hjon9 ~£¬“9Íæq˜ +rÀ–ï*+ơOˆ̉¢Ézåógs+ز6Ă(S=8Å€:ï…Í«²t³ú‹­ ©M#ÚG` ơá•í¼‘•ÀF{Ñ…' PÊÊà^ª÷C¸X»èNư¤G‘Ư y§±À]îḉB1·ÑrgéR*ÿ¼åƯrjUDy‘Đ2IÊèß Ú M§mË \Z¹Ec¢˜ªjñU ơ“l&‰5¿3Q±ˆÏ¯O´gdÜ«̣ªv#1ư8•Ù†¤EVÉậđ‰̣—µZ#kÄ\J,<ơDPV;(PƠïJß§‰Ô +¸z·0mÓIœ±Đk„j·Dơ:v³LFPƠ3–5~¹€wzªC~ù̉I|ÓGÄ͈J”¤ùå0CƯđl °zyß»ï]xgƠå(R-¼5é%n—&"–ú”<,<ÿا4‘‹ø-ªÚ"L1/G7 „às!ú= ÷¢¡Pd¾ &Ú¯f‡·^|·ËN¹7ÁíûÄȃ ´ú;Q&|±>Y¿»¤kQÚtÏû1æ¹›Ÿ™°+ip¢ÿødUª +endstream +endobj +706 0 obj << +/Type /FontDescriptor +/FontName /YDPBQZ+NimbusMonL-Regu +/Flags 4 +/FontBBox [-12 -237 650 811] +/Ascent 625 +/CapHeight 557 +/Descent -147 +/ItalicAngle 0 +/StemV 41 +/XHeight 426 +/CharSet (/B/F/H/I/J/M/N/S/W/a/b/c/colon/d/e/eight/equal/f/five/four/g/h/hyphen/i/l/m/n/nine/numbersign/o/one/p/period/quotedbl/r/s/six/slash/t/three/two/u/underscore/v/w/x/y/zero) +/FontFile 705 0 R +>> endobj +707 0 obj << +/Length1 1608 +/Length2 7084 +/Length3 0 +/Length 7904 +/Filter /FlateDecode +>> +stream +xÚ­TeX”í¶¦¤D†îînî„™†˜Á™¡¥;iîPéIéni¤iƒ~gï}®ḯ_ḉïu½+{ƯkƯëyiµơ8eÁp+ˆ†âäåâjB­œ‘z–0uN9¸xç¼ÏÈ(€X¢ p˜‚% +"4‚€ +È+**zŸ(wrG@mlQ@]#Vvvy~§­Üÿ¹;‰„ÚÀ€Lw?.¸“#†ºƒø?Ôƒ@€([ĐêÊki?WÑT²(k•!0Ẩ¨ílåƠ¡  aZĂ@‡¿ C·†äºĂ’E-H'zw â‚8ưq G(y÷„"6Kên(8 +98ƒ¸ó[ĂÿrBÀï2ïbw`Úp$ + B@PÀ»ªÚ +JñDÙZ¢~×FBïÂ@¸ơ]&r₫ỬŸØ̀]e …!(ˆêw-+ E:9XºßƠ¾sB@ÿĐpFBa6ÿbÀD@l,`ys‡ư{:ÿêø?º·trrpÿs₫'럠($ÄÁë>/ß]Mê®¶ vŸû÷¢¨À¬á@^¿ü`g§Ä\ ˆ?bù½3¬w$,Áp˜ƒ; ±¾Ï­ GƯ•²üßTæúωüø?"đD̃ÿŸ¸×è\âÿï}₫;´’³ƒƒ¦¥ăƯüơÀï^$Pøûù_¹–P÷“ư÷D#È_ ÿˆ +Ện ²0›;)x¸x₫rB‘JP7XÙ­-îfôÇoCPäNË?cṛ + +₫-¦o ÙĂ~]HôOÿù<xs«h몰ÿư5ư“¥}§:JßƯéØ÷¡ÿÓø!'wzṛ +ó9ùy„ï.?PT@ÔëßÔûÄû/[Ă…€ºMïæáưÓúÿ²̀₫£ÁÁ¿÷De ß­Ö?¿Ă gâNÑ?·ư®åØ–qƒ€îÏNÁAâvI©É¨J̀îÓ6^̀î §‚Oú¹Ù¾åđVŸ¤ĐeÑ’—¿*‚¸ª†ÄnêƯ'wœ®×UÙ6zÛȘ[ßAö³xѳ¶g/25 +³oøs›&ïEzL¨/a™ñn¬ èèçÿ¡jäGÜ;8gơ¥wÉö%e8szà Jüø†¬‰¨ +íaeÎÎ.ÓÛ­ó3æÎ¾î®ÖĆöu*öŒ7xŒâ.X„L¾¯2¨¤M J<£¬̣yßv–Ç··°đ/Î’W/ñM¾á}*Íyî~€Ô üü=Ÿ]™ÏÇÈÊksÓệ™ËK6̀Q­]%&X'3đ=Y?±Œ–öîPQƯ÷]]ôx–LyZÿc X•{µR içË }hwáÑZNc¥å0×g߮ˑژDµêÉ +¼8eRĂwH+ׯ~̉̀%Ûo1.́«Æ̃æøZ{ûH̃¬oæ»ä!"Ë«é¸O ‹¼Qwϯ¾8‘e…†= ¶OŸÉ—ëüø¡ñøØ%jíéa¯ Æ’¯h?đ²¤_`•*E }À©Ë+^+—)¢¡a'6°¥Lëă¿pféKaǰ­“̣ÏđŸơë&à"›SqyTâô©½¾½7øYăơ¡Àî ¤yËJ5À¨̃Đ ÷“]œ ›PvôvåÓTà~. ú6ỏÄ…ÊGѲt÷mnŒWW¬>ÜWi$®₫`8ø+K…I\æà3&¿4ôQƯ!£•O„ö Ûh#ă¯£åĂÁßC;âT +ïQđ"_%\Ö–5ê£Ä§ Ä5öÉR³qÑWg‘r ₫‰rú±g}ÊOû¢A„H̉Ç|>¾̃é÷µ:̉açh9Ñ÷x÷¥úg̃gÇMIü +Ăg9KÈ`-טwËC ¼XÈöµ­¦Fv-₫¾|8^äpk¶B½VéuºÇrÊHvAÍíúËÑ7—«Úf¦è‰°Iï‚ú̉W ¶§#´² ;ÍD_Ơm•æXø1̃{}ㆇDŒ«c*¢ÄjöĂF)˜d]ÜYMÁ€ö÷ơWáÂåÜ€ Z‹ +¤Ï*.¡₫&ă¡ îk³u +ÂËGœ"†AW²Ù3Æ¡H3R\ªñªV²#/È)»…†âo|.œ‡«iyåBn2uüSû3‡ÉjÛµ›™Íéœä(J$°[ à–wH‹J:I2ÚÂÀÜ4ER!‚†¡A{vî¢ê'CñCgÜ‚4 ¯W:Û5è¾Àè'8ÜoÏß Ơ¸V4·•2xë>ñ€{Ä́ ÉŒ¼–0Ïù±ưêxhßI›)Ö?½H²uâ=z³ưÏƠûCg½„—?(Aè&¾‚E­Ô9|Ä6a úp=—«îºå(HĂhHtfe₫Å•º"5Ûśó̀)Ú³Z¢V×^ßFeÙüÂ=A¿Uç¦ø½]OïĐ³‡öá¢Üi=äxƠÁe¾)¿‚–ÇçÔˆ’ơ^î0j´P°4Ÿµ·NbNØy€\*4À¶‘4ú°ƒ•H̃|ù\̉÷8DÊ ưw´Ä Vvq£•ó¢«r6ÆÉB’QƯ’ï{‹ĐÄUU›]ÏJöéˆê+/ÁéçuëB5Đj+Ëgn.ËưÆe^̀¼ +Yé=,ö_•Â’vi@©2íü÷P̣9èTr(xu7ËîÎW™oÏ tF +á­›“̣đ{¦T“¹„«?4÷¾óQø‘"ΰ¾̃G)wsơÍïË'“€ùÉđ +÷4É›¯#^ă=]/¾?ƒTÿ4ĂQ¸XáÑá<#B#o¾TE:q% ÄøŸéh“%ܬ #„’Ø=á^nư5Æ:L§<́™ÍË¥†­ÂÛ¡˜³®!xŸé“–r]azÍJ M½¯ÇmlĂ)¾̣i½5°C “PyD¹Ơ£I3†ẹ́<;S•&cQQÏ”j3gµóbÉs’?wG Êô- í­;{fyœ¬C¨±8ºYä…œKN뻳l^ÂéMö¤„¤?}}x¶̃! nAZ龬϶_3ë…”dÇ?AŒæJs K8îÖ’?†ïH½°'˜ôúJ¶ ă²m ^­Öœ¨Cc®ëºGæđ.ăƯ™Ç@£r1…8¶ÆmÖï9„Ï7¿:é>´~À|¼£M~øÜoÜ\rƠ¤íƒ§V{3fGÄÙä®$³¶äö3›ẹ́êưý$ă**A¬‡CúíƯm/Yc ëœÔ‚5*ŒÜ­çËŸ6Lwr™-¤Ø0SḱRWI'LD^DKPbá`l.Ä øcÚÚ~ŒS~\Ÿmö’øñf+DÆ=­û€‡Ëxz̃ˆEuópă·Bª)j•Êá]5Ïr2·TlÂ}"R?M`+›j‰Oó/¦èK½“r.+îùÜăOJÙ®·SŒx~ø!]m §›́GM<_··å+÷Ëb/kO’â(9!ô^>±• —Ïm¼ü˜x Z&XH`â¡‹Ù`†€Ë-wñ,‰L]Ä®„ÁRe¦TÇ¢-ºÙ&a€—fPé³ẹ̈C&fk_^>§¸+<×^œ ̣c#^4­Ä¨2}+(ĐVƠE½ Ư"Ü“«ûU °Ûº|mus_ÅDqäÎđ0l‡¾³Ư‡P¥”ÚÛó¶·¼ àö̀Æ{Ÿ7YËáV₫°ïñ¨Ï/O)ÇñºÀæ‡ü§Ñă_ZÏ©ndMûÔ†°Ç$®ñç*´è»h1k^Lˆª-R`3E-ñ}«Íy…3Ă6l6ËkM°~̀H[cp¨B¯…÷ùjvˆÉÔṆÁøœS»ü-5ÚƯù ê/˜T²LÚ4ơ¸O‰:æd 9÷¸q;–ùØfI$Ge~pp"!ưDr?+9vuÜr;~Yr§}~ æÅẈëz$`¾©ÑNỊø½ómñí/r+Q¹·^̃² +MK2́Ë}_ +üa±ë`3KMPºKÎ}pâx)-|­³wâƒØa¾Ơ³«Ê¥™ïɰÛx…³»p¹—ˆ1 +|Ê6™)Ơ‹'¡́áâ7TX ôCé~^Zçrk®ƒÜó”Ó¼äÜÚ{²ä?h‚ôLơ}CÁăw)ôßËØ¾÷è)î½÷zơ₫Â9ß>rTz½̣ô₫xSC=8@hidé†;đ *dd<ÜîỢCd€ÿ¾Œ‹¸›W= …BÙ¤£ɶj-eF\Ḳ`¡]Ÿïø%S®tÀŒ÷¢y ¤mI'Đ­̀̉TÙ«¸½zé)¤³5Ûó|³?ËzŒ1Ïû¹vdÚí·'fz¬Ú.NYơoñŸưtBî1À}Ÿ₫”`y0ÆF…ƒ]«/ø ×´`Î,P׬O†Â{ÏTëµO\ỂïÉœ£Y W¬KQ×®ÙàÖd2A/³0€cŸÈoG›ôL~»„Đ(H`‘C^K: #L4b|—"©?í5—úˆñ‹ ›H¹#{èmÔơ½^₫üƠ\ºÇ•ïʤ Ù}»ÏöGØ-pÜ‚E§¥Ơ>'Ÿ5©w¸Ü‘S7®ç%\ˆÛ¦uÏàá9Ơƒ¸œá¾§ù×´‡ÅKÇ@‰ óRĐ4‹›^'H±ÀÀvs^ }…„Èd&u·©ÀÛqntveåêpÍÏ’2ÀZw¹zÚÙrm ‘º^-3 :ªbẁ“eØMfso›¤ẪÑE f¸ŸîưØx̉c9be¿‰%A¼`Ú ªMMñ yÔ…¯)?“{r¢RR|È(ÆõÖ \E¼Ä–éơ*†÷¾]®mÂèi ¤½ü‹–Xo‰₫܉¹<ÿZ_Vă—8Ù‡%NU•uüƠâ,•'q×îR9^Ư^oGy;µh©¬`ªvi•+U¦Ü'á8&Kf§:~̀"æ¿V‡ç‰L8đêH5}Œ§D£ơ)ÊlHgŸ!1}j¨ê‚zcú&¢]ó&vª/ÉsfCM§¦A^ô]tBâ¾R3Z$Fü¾„Œ´6Ö¡m»ø~×d¤ú³,¾bk±#=­€Äª÷Ï>’ï£+ư SÿIï@¿k}Ó?K^ªđ«ư³¬.^ơós•=\́O“…y›JøÜ“1-{:ïÑpÆè̉ºë2†™ç•iøÔxĐ_¾ Ö1^Ù­ßy0|Ú~[z½º&~̃Ç¡C”ª3Ÿ‰re£Ü8³§c©È§ü1HRrâ“üZ.´øI䜹<¬L Ï782†“Td»ư™Ơiưôê£ç˜h;É1©êí̀@kŸóđBôc̃,Ú^đª5­đdJí(¢Y·ôÂÿ×»«²­Í5oµ•EFÇ€I^Ê—.}º¯³K<Ó̃Vâ÷®û¥ŸG§s¡Qă-§UO›˜/̀µ÷Cƒ0qH'qp3sg₫è*ÓÚƯO­¶¼j•U°›–1i¾ƯQ. ¡d{:ụS x5ạ̀Ϩcß.ôœÁãÛy€kDèû´DL¿óSĂœÙäÚÈ:1Qα—̃s,éA‘ŸÙæX±×2Đ_ăhĂܲḄhlF-ÈîăÅA^NƯ©8ï7`½ú„ƠÁ›i¼hŸß 5†Äáƒ_ZHP²I(×Üơơwº§ç¨Ü¦™N+ùTơIJ0µâÜ€4”áÅ9¶”AÇeÂI-¯®¥`ªÎˆA~¯@A4̀úÜ! +cL"¸æ`Èxpª¤àÈ©;Hq—÷B?•­È'¯´sËê™HÁÇÅa•uùP8ºaŒî&‹ + Çsqøb³ZqiB25Uß´bVÏ7ẻäè~Ó•ÓÂ_ôÅü´aôH¹ßËiê^-¶ØCoFPüzûÑœf8­aÉô+eáºLß[)‹îU²GK6؇=™F)·6né9.?X!ö¿vYùUŒäexŸ¦ƒ {/ùoºô¢²ä|Oƒ>MÚ¨sï£đ‡ßXü`ØáY“ºb¢_\6e£ÓƯZ¼ú­Xó¼ôözXo¶nöluæ\!|ư¼Ä‘*”º:̃́·ÊÆ)x?›¤̀PpA1=ü'̀f-í¥aͪˆ*Ç*ˆ{BXV:f›QµØj”;îœ,2¾Ơ+íge ~(6™¢¾)…OgXnËe<©‡µF+Ë̉˜vDdÏøNŒ^ó×KÇờ²/jÑô[ñ3 ÛW>KO8oR/ üÏ ˜Q~߈‘áf*-]Ư¹!R¥oDù>Ó =ó +&ÂmM¿Ùi†·(½2<3©`Œ€6Í’h]…¥‡éđñjcÍS‰̉ÀPø$Ơtơ—D¾)KÀ0¢¬F‘&UY£³ä$Ă½9ˆ³̃¸wv )Ÿq*º—ù;V5W 6¾sé…u’àđĐ9¿ô¬ZÎ*ÈV=}_.»¨œœ×ź"™:Q—·G%åÿxHFʽÏÜ`} ưjÖçqsD?R‘;—¼̣ñÔ¬û%‰´ë[ †ïgAïoù\äæ MÓq"}Ù&Yă d¦ï¼²»RlF^ơ¼̀[ăxëvZbq[ ÿZÁæ¼:Ü…í§aJBS̀)(«8ǻ>à¾5°'Ñù8₫@\í¢ăÄAQë5Å7©x²€Ót‹ZƤè{ôá…ñM +inr̃ôµ6G̃g93+<½s›ëD›†˜Ïm~™å.%¡Íh™&yÜbYߣo%T‹\2ºŸct…$÷°²_;ØGI#đ,¸Ô:‡â 'rÎéÜ•€-́45!¥û’ù‘ơ'ósVƒ̉áN@JûM«£/Aö3c!=L® ˆë Ñ7¹Ö¢̃“ư×Çj‰l£„×kăi÷æ„Ûˆô{&­)ªz=®;ä;«*nw"Ù©M)$Ë“ƠÑhP:<$ÄËñơ:ù¥úu׿{±Ñ)»&Ϩx́-Fßt…]+¨§›}KÑ•đ¤ß×9{œ:̀¹%À;6æ»UJH…X+ˆ`¹VsT—̣ơëu€YU40å]hW¡đk©Å#v&û/¨2n¥Îp™m}bú“­$ºÀqtư5ÚĂæ¯“K7>ucvÅôGæâ øü0'(-ë̉íE¾VñqDø{ñ}äƠºÅøaxKQåϰ¡ÈÏÙ%¹ăEÛ8 ÉÑ ·‚ÏÛ} tñøô¤±MTôD—.ôØE´j”vo ¸đ[yߌÑ? •OOä5w¢‚‹ÍVnê¬mx>Ÿ²#Î`̃Vå-nqĂ¥_¨>̉ÿ˜gGF¡‚}ÙÄÙH°tăö­Íæă|ï‹Ê~-l³éRÊ^¥=óï3,Äy‹¨3úøÍ•« «ñá?ç!#¼_e˾’_ÍŸ'^*-Ö›­̣JSŸWTJD—HÑ4ơ—YMdWƠ8ë@ Ạ́ưIww©ë×af¤4èSŒ?́Ö\̃bµm̉B6¥Jœœ[U%ØM±9m ¾•´·hîŒ÷SÓ·™ïkx.wCßRÏ<¾YïçÄÖUEZü¹í;}Á?B +1hÖÑW‰,ë̀h"ç†? +ÜñˆÊ³ÊĐ’„/¤EÍwzM64E{WÍ7–óVpœD¥~A\ÁY£où¾÷™Ö|b“-%âyG³ Ñ€e‚Óư₫<Ûe"Í»6WÂ(Y?Yß-vSÆÜ5“2Ătíiy3½Ëư)E±]L{¡ú&̣É4\¤6eEưè¾[®l‡üÚ¥µ¤wľ‘„é«Ú‚̉Ă¯M­BCĂ2KtO_Üê°zù$f4N" [¼©Qo+¯ˆP öDÍƯeÏà9W¿ è́·7á“Îikï#–ºç8Ÿ?ÈplĐT¨u¥Óc¬[‰qdf ÷¹áfM½bm÷hË©2Ö°I“à—rÆ„·–ú’;Wf Eở‰2…vìR„‹ơOi^Đf¨tœŒơî‰}OXhr¹Ơè̀Î}InÿÊùt>pq>µId‰uâÀMđÖ~®T›úœ‘=ˆÈuŒ&ë€<.»Ễ2X)¬̀…Œ˜̣vó£ > endobj +709 0 obj << +/Length1 1625 +/Length2 10429 +/Length3 0 +/Length 11255 +/Filter /FlateDecode +>> +stream +xÚ­µeTœƯ²- 4¸[ă®Á!¸»»Căи{pwîwww'¸»{Đ¼ûÈû;¿î=?zŒgƠ¬5k–¬j2"y%:c!PdăHÇDÏÈ5·6trP2°‘¦Y lŒ+,™=ĐÀÑd#làä¨Â@#33€‰““– ²u³775sPª(ªQÑĐĐ₫·å¯ ÀĐí?‘›æ¦6̣g ÈÖhăøAñ}Q 8&æV@€œ¼†„¬€RLV ´ÚXä ­̀̉æF@ Àd°ú×`ô‘¥ùßÔè?¸[ ‘ùÇ5 «Đö/D °Ú[›;8||̀¦ö65p̀mŒ¬œŒÿ +ø°›€₫dkúđ°₫À>ÈäAFöæ¶€¨̣¢ÿ̉éhfàø7¶ƒù ™|xƒŒœ₫¦ôöAó:˜Û8®cÆæ¶Vn±?ÈlíÍÿ‘áä`ncúß +hö@S{c+ ƒĂÍ÷ßêüw€ÿ#{[[+·nƒ₫ñú/ æ@+zX&æ˜F±MÍm`₫‹„ ÀÄø/»±“íbÎ@û +Dùwf¨>Dƒl¬ÜÆ@XYăGHåÿ]—éÿ÷ü¿Đâÿ•ÿ¯´÷ÿ­¹ÿ̃£ÿăÿ¿¾ç§u²²’5°₫€-ÀÇ–qH₫îÀßEóW°ñÿï–µ¹•ÛÿpïßƠ€ÿ̉ú—îß1 Gƒ‚ؘ~4…‘ñ_FsQsW ±¼¹£‘ÀÄÀê£ZÿØU>”Ø[™Û?ºúOAtLŒŒÿ†)›™YÚü-?ë¿ àÇ¢ü7åúG7ƒ„†¨¦Íÿ´[ÿñ”ÿ˜Ge7Ûqÿ‘‹ Èø¿yA®:¦oœºoŒ́µËÉÎêơ?„ü‡‡é¿Ï2öæ®­¼™₫É₫?~ÿ}̉ù7#ñß¡Qr4°1₫˜³ÿ2ü…œ́í?ÚûÏÓÿÈú?ÏÿL<è +4‚ư½2â°HIOu¬ẦÖêéb‚´-ªUÎÏơ­uú¤„lr–é¿T̉×Mp½5»ÍÛ¾îJRï uaXQt&Ïsđ¼H¨ºs‘×È[Ùiöüt‹ROÔ"<.æ¤7 5ÙU÷¶Æu _ đ'Z¿ÙC_!?|¸§èèï¼úܽ‹K“ CÆí ‰@îk—‰Ë§©RæQ‹7ĺñĐơñpüU°*Ă¯:s +‡@4a×/#ă²Äæü74ÛP̀Kl3=k]qÇ\gn£¬4ôở¶dêØÂ ±ơ·ø̣<ûÊSơ8û̃tLøª5Xløzé8Íac’¦˜®@Æ₫+(û!±aFfú²MÈă5º„Î X¬@hMüTÈÁDeacÏ!jyalcĐ3¦f´à¬̣îØ] k4{̀ơyØưç&ªA¡J[ïU /ÑY —`;–ÁÛ̀ +€&El’‡º«.û¸@)Ÿ}‚„Z/·h£âVưûº_#RÆ1z*^ ₫§œ²2 +œĐ"%´&9Vsàđ'²Í|û\Ó‹b7:5ƒr·p¥̃f…z Îå!*¸¯¤̉/Ă²Ỷ«­1I,V‹ û^/P¿ )–¼ ˆ°›n}mM0ní5Ex7Ñ=‚kk%!é\t®¾Åa=̉}ÅG ¦Ç`I A +Bc R®rƒăúpC½û'Â’º́„>6‘Kê`4à{%È6û$³8¯3³ü ¤ưTU D'ˆ†µÙ²c¸àvé΄ Y-’<`ăöªÁ/ăÛå€(.₫Ô)Á"N“T.@Ê-#÷¾qD̉%£s†pG‹Ä÷.%_¸¤d₫á”Yü=3*x!_E´¨¬ ~sFüWYFI¬̣a³WeT~©Â}}‘ô™ûM¸Đ’jä¨à«K»çä+Y9Oç×(Xo/8m¦»9A}ăü-dÖ×AîàM—ZzÈăS1· +ûS•îº <»—ß•¤OYé*· +Ÿ„…ºư9–ƯEÉ\íÇ{*^ª LA§d_ªµ ,2₫”¸̃x’%¹ß]µ÷|·e Úự,—gEYåÚ$ 8剒ÜĂ&F0jï´B¢úô,ß¼ù} ”̃x¸‚ ˆWJÂZB3”YO2—Rëº÷Ä +Úü”¦×ñ™W‹}*fj….Ü–Ëî´*wVĐ, +ă#ó ï)¾¡„̀-'¡+øẳö–’zĂ*jY“¯!útđê\äù¢7©<ƯX¢Üđ{l3yơø#+z1ưVótQë ‘O¤gG~éó2¬jJa߈Ú´Ô¤Œ¾ +̃ibdñ«åî̉äqf|eî6₫sH á !<”ú —5Ç7±nZ3O{'ă!Ùaú£èMâ¾Ç‚ÊkƯlMKq8Ñz̀<¸#Y* n?{ë|;5vy>LÖÙ́L_9)>T ü©óÓ~tDk\ơù= bYéÁy¢ø42o™úg_V„Öz™ +ó. + z¢³|¨ÚÔF@oÎ;%›Å—׃qKVÑ_Œ»‚‹4—%jè à¼áC†ÚÂÆV«:¯4¢p©0¾3Ö—Ï7¢¹¤S9ltÀù́x¹%.9„=î{<eÍß#́<»d)°èÛd*§\·û#*y}q|œåBŒ¥mÔY‰lfÖpÙ^ÆD}‘ưeÏMÅpAde¼g‚Ï'_™,av?£‰ïå;²(qö€œœ“z¯˜TE(‘₫°¤Ă¤qÈ’ ­^ºæÁÅÁe2£à’6{5ÙD́ÑøM +/Ë÷‚¾\–Ơδåkåu +°˜´¡ÍKƒá[¥Jq»&₫j¬ô¢$ Ñd±˜j«ç×ù:H¬Ï7]̉̉:÷j‹́¶đµÚ#C¶>J“ U|úƠñ¦%«BÄlßñËXR¬…û®'2Nd2±ßF€‰ˆÉâö·m.üË0¥ÚÓüu÷VƯè¬̃FgÂ*–CÀÙâÈU}@áÖî ·ÂDßëă£9̃€Æ~•”¼–8…µơOä–.6Đ)£²9Ylôơ]h©SèxI¶øö|=$íĐƒf×tw#Œb«ñx !w'!’2UYS^Ëë÷°Ñ°öLWĐÿ”Aë¼̃ÍÆâáCa2̣Œ₫Tô¾…Á eĐ£&ëê¬AqY¡Úèw¿¢Åoâz÷4Aaí»C´®©FǛÜUn_¾;̉ºÓơË̃®ù±!÷| ÖŸO ÷"µëÀúôµ^U4rç«è"öË”‘‰(¤ƒ¼*÷ +zv9“ êp…₫bxm{²^h̃‚T<0Dăä>טîtá$‘ƒú¡a‰K½ơï=lÈï ×V|KûA7Ó̉ÏO6(fѸŸ†Q¥̣Lâ­6_ÈÜ ÈiĂ,wk³ÎR£_¾ºü"£« 5=÷́1N+ăltÇV%MÎI@_*t±.;m[½ ü"–ªhë ‘W²æœTË#‰¥†öm«kOœ²xA/-†é7€ßŒ́Ecă₫áă’指j*r¾–¼T¢³VÁqÎ ´ø?ä äcüF~ÏboåßäÑ‰Ç ¹á<•¡¦I1N)®0ú¦s÷mU€=J½ưÛ­Œ3@̣]àr8¶üIïÑPsÑlK~Gb…¸ọ̈uÔyÂ÷‚®%ƒ?–˜Û‘cÿŒ×èX62`ˆX¿F®8_)ŸĂåZô¿Í‡y‹ÚöÇm¶9ÔÀßq¡2¿»¼$áÓ]jĂÏ»g?ÂG»æ;‘]7ÂyZ*Đïù9ơ.lcÖ˜»äw.©“ØíYâđˆ $&„7s\ÔÏ=6˜Ø,ï Äö¥¿Ú]—¤é"[g'—+¤ "å9÷•\S'¸½Í¹©Â_A_öryé˜K”ƯĐPæ$Êèđ«óöˆsùsA°é!¤sN¥̉r “ĐŸxí”°ù bæ<©D_\kWÆz đK…H†˜Èù›j~ŸµÖËñ­™*íßjoŒ€ÍI¡^m«=^Å*P&.lÓˆW|•1:&>–ÓÔ˜j,å^éÜDÅvÓt’¹Ñ¸¹U“)u'™ºăTve“EuºÔ%b­Tm €lÔÆüưºßl•T² m .©;d=%ùmlw +á₫*èçdA0ØlĐ%;ʵÅ|眢 ¡î›I™ r¡“S4¢ïÀ ·ÉØík>%ñÑXÄÛojƒ% Ňr³—…Ÿ4ÉæoôEr¯½ä)0d^÷̉(‘…Ÿ½Uæî&_Ơ»k/p À£[ÔK +c~Ô©zfÂ"̉Èc¡a= +Đ,aÈXK÷rq‰°÷S»`(蘃kùÖî}# z +G‹10}W¯hƒPT}‡Ú¢Gͤ̉Â?7†«5V¼…á”:“©VÍ+i mCĐÑ nkơ1~V~±º‚(E¼^SêHØb†dR<`1^1r¥Ç¬m¸ßD„´ô=„ƒ™5¬L£I*†24’™\7TÆd~s'̣jº¾†é»ø̉ưz ‹]ºBL·ă`Å-Úܳá†èFh̉™‘f£¼I<æbÉ® ªPYe¸0Àơ¥×bŸ i|®P‘4D|'†I`”yÂ-Jr$xv€Å+o`DH‡8c‰›Bʇ¹æº‹7$Èd¶3üÂ:<ØGÖÂä>9–7(z| i~”&^D"Z“Yđ›çâ,Øl¹Ó‡^nbÎ ăv$Éăf2JmlÕÂ}˜dU—↢'¯Oăè'.Ǿ&%§O*)ôÎa[̣:ÜÍ „W +A¦Ïs_(ujơcsg"q₫Ó¯VÔŸe³"NkøÉκ2¿®;«¬ÑÊăY`†S~”ê†Í8µÄ#y¤ÆË;Ö×ç‰ÁÜT¨¼5¥ÈVd›Ăk̉ÚKHh“ +"̃gy3m)T¾møMÁÈUø«́>îâENϳe·Âr|Yäª÷žº#¸)|”}ô=7â—üM±kú2È^O¥›Z·%‰;|Ă‘\Dlçn¥ ±%³j!`÷RĐt¬kƒÑY#BÛl1 Ÿ<Ơx­Ṭ*_z"ø/DƒÖdă JdZ®"kÏ*n¥3#Å¢ÍĂ< °̉’¯ÅeØ%qü‰["ăÿz¨O!ÄÀuÑ^µĂ9Ïy%ª#ß?½a7h¹h}ưŸÊ YÆú… [îưDºÏWÄRm²°Ç4M±¥aøÂËkÈ\'pE*ªÑ°=wl™AWsÙĐÖZb¼ç¨´̀ ĐYVÅó4xEZ°î6Í}£ z8Ó#̃1ÜÎKï3œo›ˆ9L‚HøIßO–i³£ªâé\T‡ Z"©Á€º¿XÚå₫yR:JÂpà»s+³çơơw[G7¶$ß’Ï™f1µbé0w(%åac‹døMÛ)a{©Q"lÏAóøˆWÄby*"̀‚Î,·t)°q©_]›i™Û|©‰w¬ưü÷î^=;́ü÷‡e½ßưN) Çer„̉ÔÓeª jñRĂqÀ”,««¶íqj†i¾ká§ưi9ˆ € +©+¹´·Et ˜÷»®Î?ÀU%]"Ïp—ṆÚñ×uJw×(b#4?I'5ø)Â3 ×zKa!ùØfLûƠ9Íôo +(î§íÇZ–†œ8ÿ́­́y[^H~EO¶=ư:—–G˜÷‡ÙÖÅq́$]f*Âx +5æèˆ¡!B™ƒ¨+âj½™çơŒư¹qˆØ$¬àtíÊÑ3÷mF„‘’ă s!®«‹¹™Îµ/ºË1Ñn‡ëÉPdÀ¤,üº‘k\&¤•‚çQÛüÆ•&»”†m̉î£O* ·}mA|Û^$*ˆ”åÛÁ́¡rÛWjWøñG$”NYèÁ4¬P:Ơ Üç° +ăxÁUˆ ·1 +yøïĐĂ-Ù»6·R—ûûéÑv/&8fxP`n2áí_ Ilđ=Öª&­©ÛÔ)ƒFFœj·RQHEoñÁG¶‘h¥sV0Ox¤aÖip.‡Ê[Ȥg^™Ï[¥Q ˜.Áïv¤cÅ9Aw§X)FzmÄ>Ô€È_WºˆÉƯ÷Çe!÷Q*ß.Ú5 ZN`êÔ´ăÔ'́ ¸9ùƯeâT=Î;G0íhsjsß»»=Vÿ¢bà(£¯ïxO™X ÉĂÎ SSĂ¼ÚÙOL̀V,ø0zth₫<̀V! yljçæY¿Óú1¼ƒ²ÿîËeVœ±§JZ8Å ¹M¬ÆÓO¤cÊaʆz 3+æµG6V= /Öyë=—nÊz°B ̉MwI·ĂÙÆĂÜưî&’ưéẁQ̉]l¯c/ÈÖĐGÍơ2ÚîêÓ1°¾+s²9bY´!K…Y±‘µo Ÿï*Ñ>·1ḱ”M´]ê$É8ËÆ—Ä¢0›r¼HÓ»s sLO[öc(=å–·Đ„z“΄z¤áÓd,p ZùªÑ9©9ủÊ¥µ»­Fu®$ú©|e¤OˆéEV:wƒóŸëÚ!¯ÄtA€Û€føq$ü¼~Jú +×ĂßGDăô-2ëàaM̀¾§O:ŘkÜwô÷&´»­ +ׯÇÀ­YåÔ₫më1¡–Ư>Ơå-›æaûœ0R<>®‘ª†JÂÊÛ£HÊ×ĐǶ­uxhZ¦uVØÏêƠ–¢zf újffd?ºđ鯳™f1>Û•-$ØMX~Iƒø©«6»cÓ~>Ñ÷ßÔŒ¢ ²ẹº*̀7¸4JgM¥V2]n8¾t1~×tó1pT©ÔórG2ê„|É¿t˜P¥˜€f¤9â–¼°7X0PˆébDöZ™ƒPÚtæÍ ƒ‘pM"°xOÖŸØÑÖă7ScRØÖ9_ÁÍ]å:aƠûÛâJĐx8¢*¬[»'»JIk.Ư#"|»I-j4¬]«™gÊ£º°«Uị̈^]7×#Å¢âư1®×ûỒÂ…̃Ư:˜LLö©̉Ñ4ÄÜù}1…åvÁ¥}Ï›™‰ŸƠ.xXV¤.êû…5ŒùH¥̣ø†m—Í~ƒâ¹¾|Y½C÷°yñ ­B«Ơ唥9|Ăo1sC³Ă.³Œ +e¤7$» \b¢`Sˆ‚fW¦½ÜÍÛÖÚ7»ÏK‹Ñ¿W®Å]zØ̉-ñräÛU#Ãà`0ʹ<¶¸ˆ6ưj^¤Mä6*7„ÅfơÖm%*¡̉Ư|€oæí‡Ÿ†Æ4‘(¥,ÆLŸG„Ù¢¢>¯̣“0(—Ûÿ±bY}ư³¥â+p鈃­d4a41\ ̃unĐüƠÈB›éx—âQ‡Ø $2<’LÆÀ¿®¯Á¥nƠ'‘Œ‘đe"Ùé ) ¬ _¶€¦ơđOf ×ûmúƠ Ư’Ÿ¸¶˜B i2 ùèÂË.dÎÛEÅ̃Wˆ8»~ö+÷ÙĐ…§§‚‰'Xº¤Ưn$ê´zONxØœ+7úÀØY°A¸0#­2¬Z?»ËŒr•Oy|¼ÀÉnđN£bÙvaÔA4_ÍC ¼ḿD¯%e*o<°p8…a› úͯîAÖ˜¼0Ü Ḅv4èc&́Ơ áƯ:ç,XºsçGÂ%°¿ ²R¨ƒ­mq‡ŸYà?«ªß51ú&{ă^9@*?‰À¼•G†´j@đë#PăÆÓ*T>@öÙ< - ¦Î²9X¢W©Ä¢Pïá£ưĐZF$†̀ ^⥻ íW_é]U¶­]îj¸Ôá¦OăR̃ä w®é5ä8ƯƯIç_ü{ŸÈ3•b4ØZW +×eÍ„̉ƯjùZç„PNJ xó•@/¦Œ¤8¹Ơëz-¡tO- àySÈ]Ü/2&ƒ—±ŸsƒŸ#" s ;Ë{“Í>¿¹ EO Vµ„Ô£†Ǵc/‚¥|åæí C^ü‰ÈƯn®˜€%˜ö–›¸ßw^ùJ₫)_â×ƯÂr¹É£0!,Ç9œfœö€-ºVâ1ÆFlJrùÎp6–æ›*Fc*¶ÜÚgœrCBèi3£9îO@‚J¨ă&bª¡ª¹’ ˜[Ñ/.× ̣ưc”D–#ô•)]_˜éµh€Ññ½˜Ot­Á’1|úưø\ÊÏ+́‘Ơ™/(!Æ?úöÔMD}Y$1Ÿáw̉Ïjn„~‹,mw8âc°&s(Mdçî-́̀¦”î̉ü†Jˆ6xàØ´L/LŸA)‰̃·Çµ*™¤=m̉`kT»¬ö¶@,¢ĐXgabN´0‡đ #¹/ |;m£¬×ơAi5hƠº8‹'T†7µµUU /W•₫îhe9GÔ Cº¾]9æ₫YNtÔÇt>“%yÂÈ o63¨¥!—~á©åÅïÄ6©µ¸h1ª¶Íö +/çÓ³³ l¢‚N^öb]Ó„kYù•8Ø!$!€íẶKIDÖ{íü9ó4•µÙ¥óOùsÄ/ŒÇ•·k„­â°°Ë₫ùê¨o|1́«¬¤6©³xkø‡bÖ +ÍúƒÜ4€Kcq=É L₫îR7 ßÎ9‰0ÛêT—< ÖÂR.båF¸R·cñüs +é-zZEp8(<ŸOʯp¥‹ưpu‚PÖ¨Úâ¼æ$@›8I®Ăê¡k%Yµ iâ7£ŒµăÈ‚º=Œ_œñ:y>R¼G7o¼  Xæs%Ù‘j²Œ`Ư%K‰(± ÏWa~ËpmañĂ8"\R_ ˜— l dž̀ó:̣:V$?^#†­´ zÀ¹`úáiđΫ…ĐS5èjˆŒ‰ÎbÍ +,½rDz i“ë%ÏŒT₫è²!Mwpˆ[¤ÄÉ_CƒàŒ¹dŸî+ĐZ_́ơè>µ¯è®Íb)¢7ÑÂë§̉"h÷Ă²üt̉¦‹l\VRâ%åmY.Wb ›í'̀R&ơs ÷Ü ]ºå•:ü®ÊØ$PÎÈŒ}®„Æ£Å6"köG)ÿZæŸ;n,¨ôåö©çÑS3̀qÿ(ë:8Œ@6XIh!¼º¯8Uˆ“k0`đùU¿‡ơË”K®ü/º^ÿ€r>ó2+Np¢ µgZujúw±/~u›̃„ăJ_Áú ÿiw ]Î W2›Œ¤UûK‚¸qƒè6xU<;ÉVP~§ë÷̣+!ô/ïÆÁDÉlî¨!v¬M>ø>gê>$Œ˪̣¶Èú̀‰êôpôZÈƠçˆăâ©rwo› +ºcܘ¨-í4Û÷YI´ßüai¸û))ƒ§;k¿Á¥fçŸ1-b–°§Ïs„úÛ/÷Kx*âŒ%–÷ÎjĐ["$•aKôpMD±¯•ÛÛaêa–Ϫð/ ¡ÓûÑJay¿Yf—Œoo±¹F›N‹̀ÄĐ %ÄwsÏ;ÅåíÔO²T‰®(|±ôˆÿbLá°Y ^[8ơ¾*+£K 7r̃’2Çú­Q°Ù ú:¾Eû¢1¸€MƯJăåT^p¾fmûÙ—T¼(#–?bé=ÍÁK42vÍ¢2¯‚‹ô2 j®; +ĐÂFçOÏ„YBq¸–%¡UÔ§_"&Nô”20̃\»AÁ1úY@¯«xNKd C”Ü߇P1‹nN!ŸèPWIeSË­Â0½L«₫Цڠjơ˜¡ÚŒ«ư±dI‰™á‡h‰¹-ͳ²1u#̣ +y_;¶§Í\:Ñ/D êúÿt»Jq́Å{0íưÔto–•Fç#çă-.P ]Câ¢ß¦¥–%`đMü`qè¤úñ9¾̀́§ïMX‰„†Ëó;D•f¢†^àç‚pûe +ªÅÉàOF0=æ1{ÛbÁ÷—†mMÿ°¬ƠJ%¦åEbHlQø¾́˜n÷o•dh±û~·‘«F:ôŒ/æ€m\–äø\Ă!E¢M₫Y€ă,”m”S»ïdtjơ\/ºä­³è•ÍÏ µ(œJ× Bá}¯´6-$̀–9Ó•j錪ăÇ—¦B©}sˇ!P¶Ơ¯Â½¿;N ẳF ñ½ï˜GÆ‚¾TE—‹ ÷$˜ ˆµ/tª|z©(•Ƈè2J ̀O [ù­Xüîï±VS>åb†̃÷«‰p¡½€ aÚ"”¦I£3ík*‡8?]0w¼ä`} ºM₫Ÿ_Í\HËCûùs +É÷`éÅ€#I°Q’¾qùxHÁ¤µ¡©m†µ¼¡¥$ÔDî$W\…|Î_ ̃°ưç‡EƯfè£₫©_å-ç¡;«j‹̃¨ ÏJØeçñº`ưt,âûÏ:05 g©â4)xˆ¤ñ/CH»nâT²†ßÈ8Ùñڮȹ~ÂÀ*Éồ÷ăOR*{½PÇĂăv>˜ø<¯êUD̀$qóâíaÁi”kă¢ ŸyỰ0¾•Âé±¼̀G›(éó:;­‰Ï­rI;^º1ø°W‰À(]¸4Í|êḿW¾ëưªö +…U¤w%Ẹ̑̉×öº÷üêȉưă Uûå<1å‚W†#©qL6Lír?r×{NÑ g̃1s%ñægÁÙ@O0œ\â¼ư1̣1­6?Ñ^J“¡ dĂĐæ9œẶ̀×}ö¼(ôèw#M>5K˜8§)Ú9V¢Å +ª{»Wi„K»íwµjººj¨é´_f-êevv A:¹”Ơ°†yèìԷ²̉> dwÁO×â"Afđ3óÏBRJl¼o÷ăÙ`o*m¶‹ {*ô’¤OÓÙ¡trIû¦ô –Ñ&g=H[€̀ûUÏ}`fß>‘ü‰FpºVç©PP t< LôôÿÍc>XOËü +ÍèwÚª‰—HœJ7%¾ª[•†;2 Ăç̉uúË“6ËË ÁÙom!Èe1?6HÅÖW1H GÀưà‘ºHÿÊÔ4AÍdµí:́ØßrH1*GäåO“¸!2Ö°›fç|8}́n!j‰ç¤y¤Û>k"%Đüùư}£~'sêÓ2çGåaUù€3Öq_ŒƠÓyMåC•C¸'¥ă~ø³ü"²$–Ggâå+"º˜­ƠS‰Êè× jO2¾k®·•)øs! *d“É}̀}? ^D6+̉‡„Eơ°ü: g뽑Êf˜Xo0Y%ÑŸ¹“Á`Hˆ¹#vy´¿î}ÿ8₫Ă¹Íü‘øtrç[ßÁDƯÛ¸>$¤ë”•¾†¸́}f»÷b®˜P¼Ö̀_ßÛhÆÈØyƒqWZƯ’ç­́™´¿AJœ\)ÿ0₫^ÔQè…Ç”mŒ$Ö¸7¤ăg½xÓîg8¸”NÄΜ·¨®Ü·¡ë %^4†ZSa ^úV“àP¡+@Ơ(²GCµ°¦(Æs^-ÿX{k@Xª4´¶Ó÷ÊFé9ÅlÛÜ5 ‚ĂUÇ£Nø™[ăÿ(pU +endstream +endobj +710 0 obj << +/Type /FontDescriptor +/FontName /CIYFZS+NimbusSanL-BoldCond +/Flags 4 +/FontBBox [-139 -307 822 975] +/Ascent 722 +/CapHeight 722 +/Descent -217 +/ItalicAngle 0 +/StemV 114 +/XHeight 532 +/CharSet (/A/C/D/E/F/L/N/O/P/R/S/T/V/a/b/c/d/e/eight/f/five/four/g/h/i/l/m/n/nine/o/one/p/parenleft/parenright/period/q/r/s/seven/six/t/three/two/u/v/w/x/y/zero) +/FontFile 709 0 R +>> endobj +711 0 obj << +/Length1 1625 +/Length2 5831 +/Length3 0 +/Length 6655 +/Filter /FlateDecode +>> +stream +xÚ­TeX”í¶¦étˆ¡chn ¤Trfˆ™afèPJAR‘nD@:$¤;¤”¤»AZäŒ~gï}®ḯ_ḉ3×û¬{­{Ư+Èah,¬j´ƒj!Xa1Đ€ÜƠÎc Fè «!]́u°`"ƠÑP0Dh€±Đ;s¨=@ +ˆ‹ÄäääÈu$Ê w„a|¦̀ù…₫eùí°ó₫‚‹ÄÀ܇Ô‰r…"°8ÿs 1 +À ¸  ~ßđ‘6€OÛÀ  E@Ѹ" Ưí\à€>E` ü$ạ̀×A"́á¿KĂˆà¸T10ƒ‚Bà¸0¨ú PP´+ƒÁ}à€#ŒÀâz€Eàˆ‹»ưo8»̣ ‰ópÅa82C$‹ á(,—ƠPCë/Xû;7ƒHœ§=â₫»¤?‡bÁp€…za粃́á” Ø—G†BĂÿÈpÇÀÿR @CÁh{(ƒ£ÁqÿîοêüêÁ(”‹÷Ÿhä¯j€c1Pr1q\N—Û ư½,:$@ ô—Ữờ₫Ó ¾ß;öG"\¼öPrQ$—À÷›²ÈnÈÿÿGüïÿo¸ŸÑÿ¸Äÿßûüwj-w°+n₫zd¸WĐü~g¿8ä…€]á.̃ÿ&èïæĐ¿„₫æú;öµ*Â7a1qĐ_f8F îµ7„c!0€Ø׬?vS„=íG@qCưÓO\˜Øß0âŒøƯ}i¹?aÿwí¸9ưQ.jđÈüñ}-Á÷´₫ñ4Ä­ÖÄü·4ó{Hû~ó¨©!½¾Âb22a @L $“’đÿ79ÿ‰ưë|ŒEĂ½ H €ûÿÇï_'«¿Ñh" HûßKcŒ#́q{öOĂoâFăÆûçêăÊ₫ÇùÏÆC¡^PùÔ"â””Œ-gÈ́аho#́EåW™äæ<-E¶t䣩éû` ˆ°×S»¡v̉EÙ©…ŒµBR)“QûgG–°~î4Üm”Ê­PevFÍu@~8¼0.oÖäZ£TáiƠîØiîẤù4|'ÍG.¬Dưh¤2ăϧ¿ơBÑø™“|‘1k_B‹,ÆÍ|xć=%ù>SØ›×)5)gË$\Ë̀qqr8¶ÄK Œç¸ó,ºc†ñn0e—¢ÏàÖlT¹ơW}-‹›ù$YÖ dlÉ̃½I±áODC<ùƯDgµ]U9ƯYLB³ø9½tÈŸ-SŸ2Æṭä='8n”_ÖUv6³^²‘¿âÄ'åw¦cŒÿä¼Ë–ÄQûœXœepú=ư;€ˆÛ«ÖÖ @‡]èêÏ5fXô‹\føNäG®J˜6=¥4Z,Z˜t^>Œ¸m:[iU—⤪ª÷™}Çj@€—œ̀_T4Â;”¯˜¢íNª˜P®•êRỎü¸.dRïÄ÷€̣4u›̃¶z™iêM“èv¥°•»ƯêB=Đq1nÈ\i§kÑ!O´ä¿÷‚¶÷”˜¿Í@r€^_ï×=’ËÍ÷AoåưĂR2³dà%éé¿ “6UvDå]Îf +1«?mưU©>g̣æÛÅă"Íî;îư¿ºÛ̃rJñ*“ ôùÉǵ¤?~láÄçL½3[óÎÑUŸÓ“g¨_›·z²ß&ô~æsH§ûøṾÙơk…¨[3‡®5€tÛgÊNäLÆ]yeùÚ‘ è̉ÖGôX–\ôê¦`Ö)QlyÇ:ưTR¨ØJ°Î9ưÊS[Çđ©Æœû#„­’‚›9å·Ç ™ÆTj½h5Óבt¯óT³”¶ƒ +ƠÛnFíLÖˆû¬½Ï₫bƯJâ5ËHD·ăú~}lÓåUäÇyO©<¿…ÛzFD~…µ¤¤4ÚVc₫’Gµ¯²¾dwj%̃XÅ›}aö!¬‘Pº;…T¤%Zdj/¥7eµê/Lcx‡ÂY“/å•Xÿú´~äơ3èâæÍ{?́˱‹/ª"6û¢¶«È\¢I¬ƒw ̣Ù|̉ó)*?‚xëăoZQQQ‡̀ŸäđD¢‘× a…·„Ú“¿w¶;M55ÅhF|Í;oj.³ûvCº c¼µ¨]ÁthÓɧ¾”ÊOçKê?¡Í=yk¡ å(¡?ÉƠ‚Ë: +¢‰w j̉—›'€ ~+J¼Ôßl÷uäI[`L»œï6äưB™‹•«3ôŸ ê-ÑØ!(8ßàêºÈcOR Å©GûœêÚuç +ßS>ºu)¥Ẹ̀"»‡±†Håé§hºNđXEQ̉µ\ªŸEØ(̉»Đ”ôéá­­¡otΣơˆ™À¥Wư!N<‹G7ŒùƠƠ<^°4m˪†Ë“̃°¦ 'v±~µ5r³í騤QM_£“ î=@4Ņ먿P”¢‰¸“ƠfæÛ³ûf3ïbMlfÉlơ¬}94#W£î-¦L+Z·Ẳ‘íåí:!Ë@óNɆ`Ơú$AR¯úÔjU_rÁk"Üí}†”™î;¤V VÙë̀¢“ÚÚŸ›ßïR寧ü ΅đđ½Ñô`Ùy!ñl9}ĂÛQ¶û‹ Û2ƠŸó7K¡¿.Ï„èL’g¾ÿ̉ôh“Ÿzgü‚2NưÚơWˆ÷s}ª/+Ô¡ƠFăwcAm¿^yjåÇϬq?"åx¤yƒE6XNïƯ¬óB­'Œ̉£39% ê<íÁóƯeíN‘ƒíÚó_´-ÑëSJÉØ¹NÆcæê› I­¹à g3è'ÆĐ@IuiA¼Mt„ßÙɆf¥®ó˜{üơwëC>:îềĂSĐ£NÎʺ•­dÉ*¡!LÄ"굲ʹœă*öÈ>RoP¢ßôG9‚ùíÂ÷}h†­ø—Q3QÛ\/€&Ùê¯fj'V¯©·¬ù+Í^έÛöÍzÅ4¤F<óƯg¢¯YyçèỂ2Í]fû´¯̉5UMT&‘˜îO'VẰظ„¥vl¤ÆK®Iú§»¬]G‚O{.( I9Äơ¢̃÷Ï¿l5²¤´O눫Üä”y¢s₫¦ư°Îí°+®Zbº1=*·̀îÓíßaü +ñ˜Ơ-Nq±ẂW© h·Ư¬¦êơ0J¼¦êc«“[9Ó‘?"ȸH€‡û=꣠)'=Ï_çrc.’ăËÈK¥«ưhàƒ¨ÏPq@Iw®äél;&Xÿ–¢l̉Ç„Œă Â"wư^»2Ê(/ÂüCo +ä¸̉̉'I ̀;¼åT¼}9‹9;sÉJK91ÍmçJ^!7ù75t ½œë÷D¤kg3^i,1²&ˆl×*/đ,L"'ö(qI9~̀¬Cäg­®—r6–C(4. ‘ư0 ₫eê&Ù¦ªñÖ¤›̀éwç]ÜOîzê<æ•QÎ4Æ+'Ư Ø_„æûïºÈÔÆ¡ï½zC~ 6ü`íGmƠ «¯OnÜ +˜#¼7 Å#(iÎ>Ûbè¯Q/E×8G]¹ûE?›j7TâÍgô LüxE§Ñărë™ø[™Í^70f¿–pYù*Ưëûözi4Ö&ü™‘}R\(QWÏ"ëƠ¯™´H÷øo+y?O} ÓÎM‘ê¥s¹rçrÙN¦’<Öæßî2p;¾'ÓIªĐhDnF·V¡®vI¨5ë§Ä ̀ź#ˆ&Ioäaè7̉@«¶À³Æ* +^ÏåÅœÓ3VËI;y¶ª“Ë=B«æKo¶tåÏÑœ=ºm¼’\†xĐ¥Pă€á.o¥NÓ¾đƒ¹ZѱW|̀çKH°z¥îÚÑ¿,Œd'V’§\/˜đ6nó[Ú‘,˜¶d5Ư2~Ÿ[Ô•¯Ư—~¾+\ŒeP0ØRQœ) +“Ù†;ë½´́óDQnµˆYô·½oÅ4Ø){Wơ@†Îœư €u–̉ª,EhËREª]g'ˆ[†ºàÔÖ‹.U÷ÜÄ—ÆjÙ!_ßn›k Î0ë-s\͡۴ +•¨¢2¸?וèƒ7a +ƠX愘®ŸÇ|l=UøeàM|¨Ó›vZ¡{ÖÄ|Ul†Au/%Ẁ͵Ơ£NÉRé)9m²´Yn̉˜¥˜\¿´Ó}™b³{g +Íé^zÉ•˜4mă¾Ëax—rÂódà`hbx’Ë >3}²bÎó¼+gê±­l(ù~—âH5µû:Ÿâfm3^À­é…¯Gç —Ü[ĂO–ç^¶Ă8íT<6Ïơ1~/ÊïI›¸yR[2!"Íg¨¡½Çîî3¼v<ëú6æ6µh^›ù”"p_¨\[‰·÷|JHSÔ»Îô4Â÷{t£cËä«ek¸ÊæƯ¸ÅÁK̃XMV×ơH~ ‡ûµ̣›́^l +Ñè`›åŒ­‰?®Ú˜(̣a—Í 5Ê¡\ùdmt ëj" ypl·¿ơ{²í.øÔ¶ß#èñ̀áµÓæÇ¬ +ºÛVh€/[ó[,ÎëPuÜØbÅ0¿¤Æ$W¯™¦Öm:èÿ´¬y‘O¥2>ó€ZIï–yË™¢DáˆÿP+Ç86‡§lo÷g1¡ơ‰†ékáVî9zNw+EŸ~Ä$½ƠUá“’g5cƯè<JoTyk:ˆ¯_2çÆn4iF} t­¯.è ·ÊøE´ÈÚº^ê~̃okÀ4ξ8YeƯ¾VÙ@H{yƒOê<ñJ¯5XbLcñfUî‰é|ÈưŒ_́d„¿Lđ³LY*Åá—"imĨ—D2î€}µ>˼†ÜÅ­4úÍ//=Xyr£§‹æ;¼\ŸKê§{_Ïmg@k›”? `g•ÿîÎT¥ÁÂ;Ṕ+)¯<™1öD$D;¡à˜EÖg}eb·ú‚ ưfÀªy,V¶~ÿ£zkaD•:_µÎ.à¥_ÙM’ơ”ˆµ;’¾»>m)̣eOÖEƒV#úS´«<€¾ƒ·)ƯhÉ—úÔ´ûIE>%?\'<ë₫ÂơÁĂ=̃+c +´;k!±÷eùo±¾¬U†RP‹*Éà'®êxGvz1HJ;±xư¼ +f£„6&ađ§ +³WŒU¨¹M7úC('dđ¦ÎKfrIÍå,Ûæb¶4é₫çb=  +Ơ:²p,•küáU¿xưÖ•qZ>E/kû·&ÍŸYø>m²,*×èvÎVc?ÿUê;Í|y$&pPËnë¹È‰/o TÏR2¶̃'6$½¯̃Glưtǹ~=çS…êZ!×iXr‡?pIđèIïuµ†P̉mërQ̉À×¹¥;a¯¥I-q“©Ù“̉æ,¡*:鯦›Uy¾\§oø’$üùơgVÂÎư5†û®Iq!1i›¶uđC{e +>©åƯ¾ugooî¹mYGM¥Ï#¶¼dÛxíÁ ‘Û \û;JEj¼‡Ùj܉K% àn·:î’ÔŸúר̀ ®  ¾]̃ûj—.¨%—¶« ­I¤ç›{œkéî¿czút‚Y×ߢTÈ·ïbÙ«ó5!a€Ä­b…Ç1%Q¦×3ecs6¢CHC„ÎÅï5!ɹød6ü̉:™Ü¨Ö¾ +¿{gdơ͸ fÊá)3÷¯oÚĐdyí¹Çù¹­(ZKF¡‘‡½E€ëW€ÊÄUåzïĂÛdçƒw,Üóçœ×ËÂWĆV‚™•íÛ)Ÿ-z?n¼¬3øl, >~:¾mÿ`¾0:Àf&•>¡ÚƠ8 l% ÷å-2Ѩ+uÍ÷r’aÙ»Xà1h°­ơíc̣ÿ&\uèÑ£đbŒ₫6—Ívq|_÷fœ\â)ơŒkíư!á ÷j0ƒŸik4I¸ï8OÆƯÉFgsNLÇ/elßäÓhÿçcÍy&…M´/¶>­~®é)5aÏÑÖ C! Ë´7ŸqˆÔÖJ"CErßeQ;[&¿»qwEă;3Äơ(Ä׺S8 ‡'³®½G7“=fùgú˜ºéIT9®ÿƠ‹_ÊI·˜<µzEoE9p$rÇ×Ăê~xÏ-"*>b8OJqÍ;ú¯1ăœ1Øy]iyæl̉N…z!¢W( •øÂc)³ô¬}a¯}ƒ³¾Ouo •DPey/¦sûÜ”66æV‹ ²ÚTT9_1‰Æ¦ ‰0mÈL%xTø/WÎ44₫œĂñ¹€ḍö¶¾£³đé_›cÖêcXĐ@›(µ‚ϧÀÊ…´¥Û€ö¸̀)Îó¸̀¦C×tå©o0Jª&øn¬ÍGß" ;ÖG0fwÆo‹Ù-ÖèƯJÈƠÇĂu5e®đ‡è‰áTzưZă]MK +,¬‘Äm1ø`q%nø© b¡@öÓ»ˆd!•0øåCËÙÀa§B‰*çcø¼ ¬(yăưüD‰z9X>\8 ÚVàF·èë‹“qiÍ«\́#cR&­€s>>×ă*Wḳù´qM~¡Æl{”÷è7v+NIÁö-ÓkÙæ¯l4íÈœ ÆîsÑC< +á%6×ă^Ïë7FñG5 ¤F%¸¼{Ë f73ÚmíYµûzÊË6ụˆ¬³wXÏU+×¥\—_tăí1ƠÀ¤X§;§N«bË~8ziNjœ½<âJ›”z1}W¡ị 5x)@HwÉ6¦ôé‹e¿bvE~X-{(g;µn\990￘ă•́é¥Yëy¶í’ÙÁ-Êđó +>RĐ/kDpSrdǺi00'C˜TMvq¢¥5ơÖienUI˜+̣́NGñ0Ë$ƒúÚ·æqóˆn1M {OƠæ4 ºJîÁB¡qç“ú'°Æf1ʱ\Ú\z*ñ]‚0PfV²F=U>Hí'mEj?)^¨jy†Œ”Iü Nx– +endstream +endobj +712 0 obj << +/Type /FontDescriptor +/FontName /NYWZOF+NimbusSanL-BoldItal +/Flags 4 +/FontBBox [-177 -309 1107 953] +/Ascent 722 +/CapHeight 722 +/Descent -217 +/ItalicAngle -12 +/StemV 145 +/XHeight 532 +/CharSet (/A/comma/eight/four/i/l/one/p/r/two/zero) +/FontFile 711 0 R +>> endobj +713 0 obj << +/Length1 1641 +/Length2 6434 +/Length3 0 +/Length 7268 +/Filter /FlateDecode +>> +stream +xÚ­teXTm×6Ư’̉ˆCwwKƒtw 3 Œ30C#RJwHI)ˆt¨t‡”„¤ˆ„t4Â7zÏs¿Çư½ßŸ÷}~́}́kkë\×Z{q°(ƒN ÜK@DPX }ää2ÂuT0°*ÖöÂhP‚ˆƒC zAp5 D`Ô €¨(@DFF†ˆ đđGB]\½ÜfÆ<||ü[~»œüÿ… #QP8€ưá!<Aà^hÿq  đr…œ¡0@ƠÀĐJ[_À­©oĐ„À!Ht†̃N0(  Aà(ÀÀ₫:@èJ¡¿KC ¢¹”Q åAÑa?Äă7Äđ€ AQ(ô7¸ p/ôx!P8æ ₫-mwFüäD =¡14™!å…!¡^tVC5¿tz¹½~çFAÑ0áŒö#@̃¿Kúƒ¡iШ +G¼ ~^¿s9A`(ÊôGçF“y ¡dx£ p—¿đ  ƒ Ph4÷ïÛù»NÀ©èáóÿøăơo P/æ,H$"Î ̣Bçv‰„~Œ6Ü₫ËööøæA₫¹ îß3Ăƒ#à0âL$¤đB§pÿϺ,øŸḳ Åÿ‘ÿGÚû¿kî?{ô_~âÿíÿüOj oLø=-zÓ º€ß»đ{Ùü ü^9PĐÿ |…ùÿ7áÿt´€ü%ù7ë?±¿¨•á.è̃ÈÊüe…¢4 ~°!Ô ä +pÂĐ·öÇn†V„„Aátwÿ\,@@DXø˜©+äÿƯ‰¿ üOéè†ư.¤£¡n¤«Í÷ÿÛ³¼ ÑóàeêïüßTzđ¿¿¹TT~€@q1€€¨Œ4@FD #-ôߤưĂ#̣÷Yè…„úl„……Eè÷¿¿Ovÿ Q‡ƒàßd℃Ñ3÷oĂoäD¢[ưg  +ÿ×ùÏôC ~ÑÜ4$î–™åUM›ß7¬fÓƠ!‚ƯáñºÎ´¸0¤Ñœù́›L¹ăuU„`ư΅ÍÿÏÛ¿Ọ̈~è qµ§Cö ˜‚Øx: )9›¥ø¾?²}'kÇ"6đ`Jw ÇZRØüụ̂°‘±ư«k¼{£ÍbH‚ƒ36ŸÂ»́§¤O@µ Ô-äơ”ƠEÛ;œ)›g§\=ƒư}½íG¸kŒ|y „r>8w8cB<ó•¬ÍÊckÚcG:¾Đ¿}¼s1£IëX 2`¶;6 tỤ̈M̃G>@¤AùX×8E#€Á:¿Ú(́T寫‰Â„)FyƠ:+o)À +ˆ^₫0®WkàiÀ¹ô°ÑpŸ ½#ëÓ󟉅cÍÔN_ẼüLjçư8~ç[öúaÓ°m³{ßlKV<̃;%€̣¨[ËœBơ{ézoǰó*JPdÇsăáàÙ5»§(_m×ûfÉL*f„wÊ„˜›¶o:`Öbˆ¶í}3+ÎÆÈ[}µ̉ƯÓ$¶YÁÉ_8qC#_-ăYm|«t¢ïÑ à;f´-ÿ¬Â¥8Ä•½Ü;Eº(Ù'Œ.*´̣ +]æ¤Oª ]%x¹~v¥Ø ÖX#î`ë”ïwr̉s Œ7§¹9i'C^æ‘J>̀)è¤å 'ÿØGxó§q²D±BÏÑo·q–å[q2ZÎÊs× pßbLbRH¼áGƠÇÔ[>>÷¾ñ\‹Ơ§O¶OGM›áíHz­Åœ®đLî×'̣F¿%1?É~ö¦·&xT$?se»ÔWºIaØægyâOü•í' P‡C‰>`¾ùLtÇ3›!DX<”ï4‹#ȵӆ OqßM·$¾äª^=#µ Z!qz×^w%;cOª7—6Ưn©g_UPùÙU#”Ơ÷ ªü²åđS¾™1)#“xL¹*‡ÿpQ)r<અ¶LÁó¸h’Åđn* ñơ.‡wé:³ /8}>cÎEÛù"89”àÀqÓ¼`èÇó{틳sƯ,î¶ÆŒ§|÷͸hê]¤Ñ6>µÛk>ºsB7¡ +…ºèéú7œä­hez–Să¸Tôé9M 9ÏöéÓá|s·¥pÙ₫æ5ƠÅÙÔOíÛí1‹:5CjÿÁÖuö‘“5*—̀×÷¤îb®8ƒ³ ¤;$Y¢4#bn»»>WïÚ†°e°̣r²B5Q‚ÏËÀ ú»Iw©t®ÈÇG¾$0%ɇɈ +y®fÇ[çˆ:+#׈…=J½èô®¼h•P_‰ËÍŸÆëQÈ(„L ̣§?)MïHÕÂơĂü¡Z'ÑPç©+BĂ!¥t&Ă1ëdl[²®œûÉB"ù"?D’}¯dlæ̃–)×:c¶ –J<°Ú¯Å¾›ª‡‡ÁÓY¤ÉÈîø&«"`₫S2?ăö›¹:©ôh¬ë—äùÉ„¾q̉(܇‚Ä^?X¶´Kî¬qJ;¸*äq‹-¯Úë_d™¬¤h5¾æÁ¿ +”2̉÷«aˆ¸X¸yà¾Y¬Q«₫S?UwV#Ệơ9ïQ®áØÑÀú˨f`§R›ƒñ–uø£5É6ÙÀÇQ³ÆÇ‘œ·b¡̀Ô¼û†Ă|ƯP•¸tôĂŒ¸¥-PÓ N—ăSêc˜ -ô[Ó*†ÎÈ!o­:`âÄè²̉>PI)à,v™z¦¹Œürg=£\€Nåqc¤j–#M:˜øa“FYçp¬@5†ầQâ<́ c‰÷µí³Ù›¥µÁMä0b®`á3^5÷ApN®¾Ö̃8¹´\†R*ĐÚî—ø†¶ +¢pè~ ûœ©»ẽüóŸw³V7ù́¤¯~¨Ï4È„²"6sKµ.~íö9êiÅQóAµevÆhà÷¶üˆŒJOϵn‡ Ôđø2î[×4•›9¥ºGÆ%µqzgAÓ£uNÜư¿ŒÜ²W>Mà\¥_’øº;8rm+}†»ƒïDK©Fp©ë̀Ü3äÅ!©Ÿ©¼ßs\x˜\´f+ÙÚÔµŸ*á|Aûnµ¯qÖá]¾tˆ,4i¬÷ízè$(ZfêẴä%¢bpñ~­3+®Ø/;Vz;ªi !=]¥÷ŒÍÙèÎÊJ6àpqTL¼Æ |ê\ôb–"đØơ½x ‚¸:29-ëå9£j¯í³¢*?ĂëuàÅ„Y–Ú•ú£4Z^»c$Í-FM\éwá*Hê~¹ư¤O£5\Ư¿́°Ê†oäÛ°WU“ É+̉Çx™ÙÄ₫²§\±9c4/Ülêå?=.hüƒOAûefyV©RèëØIƠ«öơd±KæÉ…w¡Ÿ&mËúÚ§FW«@Ŷ£ŸVC®•~+ÅHtNAö+HÔ6•á€Ñâ‚ÁªæÈbá(Œ~âCØöjÉ›)ÙùưÄăU{†v ’å!lûÚÍÁ¬Ês”NÏWÄLYF³ÅÅGCâj¾3¯Œ€R."Å¥Œ§æ‚£Q–ṕÁƒ]$ÜξQÜÓØ¨&¿IÂ@{÷ôƯ¢ä@bÂï*œ8ñùÖǦăU•Wጠ+Æ8*’óiÇ₫<ûfƠ¢%W7VIM]fn[y±ùsk‡l5l +7<đ¥V>&‘Óg̃\p±Ösơư ñ'oÜÙ¦Ô#O…q&àDBƯr7¯gưA?›zơ¿±£<çà”ªd”w~w'f +¸g6¨¿Đlm—¾‘X·~ oÿ’·éÂĐ…nyÎ|™CÛ£ßăëObí}@ ¥ÙhÑY¡ß›;o¿_¸àëG(ù%)!bñịÇRå̉4|Íâ'ëÑkç·çz­í^]•sß,ƒ¸Rm? kZoꆜ|€¼,³º=±Ûÿ¹ +₫¤̀«Í®syÉ6“™–JE—6ú>nĂSI)†zaÑoŒ{ơƠú±yj~̣³‡7×¾mJkÜóơQâP®(t±¯1€<ÍCN—>0̃ÉÛ‘×_²§øHySñï]æQâ&F1‘ªV®îËW̉²Đôûµq„’-s4t=cbÁ\0K¢ªơÔËJ9´9zæWc¯rƯgÎI–¢ZÓQåb Ụ̀増¦—åÁ¼)¬ê}ˆà}]¶ïKXE~ Éêæ¬Q°@Rö3Đ ]ĐL¥qÔ!`Û¾a´:̃Ç”RSX¥Üü^Üë™̀Gdïoƒ"¶æÂUTb”ÍƯ₫¹E³\I~̣'£lF'ïÜ« ÁïztÅ{‡E#Bzú̉-yâK}~X&”Ur ĐmÇ[Ṇ̃kú}ˆ>¥´s×=Jfö½ÛeéW+9‰¬‹"–/ß2j"ïÚÖß”XxÉ»Z½DÂx¦àŸOG´ûf€üeæ†<x[ +]·}üˆfÛ»¥en¿Ñ3fgÖÜVªDđxXûn—ÔăÖ¯ç'QĐ·ÙmF¦íƠæÛLcI&ÆrH}Ln‰oL“w„8Ë₫K,n/đˆîB­-8È Ân4·Xeu0Ǹâ2wöû\TÚÁ@jÓöxÎ2r̃¹ợ́‹,Ú‚D!“5;kÇRE£‘#v6ÑàÜbáu­Rè̉÷ÄBNÜ”E+Êr™8Æ”o§ưí B°¢G~D§S~éä›-n¸WXáP©‘jñ2ågN<¦&Aê$Ơíđ‡ƠåÙ2xØ÷Z¨w\ûr¤ME%RưŒæ#oÍçuäJØÑKáZÏFi§‰»]8Rö{VæS†ĂXÍ»Rx”ñ¶pé>ˆÁ’Ÿ1Ó^™báGïơ₫D4È•p¼N—S.F¢ôˆeư*́T­¹o ¶ªä’5bLØƠ5å¢uMH2ü 2÷ÿ/GÊCU”ÜET»ü¹Z63át P¬iă úÆçˆ)êKŸÓúôË«M₫U¼FxƒG2¼Y©)~­D|¥dú₫¤̉^ª +1çE¡»£7Wc™ïå§÷âớPߥ¤>#&I›I~ÀömP0¸Ø´|ÏIlË/ˆ©ö46Æ;Àµ½Wv)áÙ̀Ïđ‡ ÅÊúÇr,…C~H¥zb';/º̉ä±[ËJ¦OG<=K<µBϬuăáÆÏˆ³\̀H/̀|˜ÓÎÇi™¬¹:éˆ$Hp”Ú¹Å~,½¯-ù) ª²6ƯCôTµ«˜[̃q û ˬ¹Đ³øÀ—û†«·,W¿«ˆ¸Éăi +A½Œ$“íÆOVƯ¢q·Ûïi^ôج́UX’aàÚó¼"0q1ÓÅWÑ›.±ºøº£Xà¹ơ¤Pêkc ær¯öYôå;A0M$È/•{>˜H’º̉Súd1ûÑ`ʇ+©åÑ­ñøĂC‡„÷7CWßăØôÇ6ë#FñÎï9Ê–.÷0}Ÿ»³ú’3₫;»­̉Øeg4fƒbO‹¤9&Ïj¹ơÚeô ïAOü—KkLœÚ[OäđKU@₫”₫k­L¾Q¼ƒvƒÇ¬,^'¦ RöWàÍPÉ0¨¡åMÄñIà]y¼>^T°]êU‰hF¸î 9û]ÇeB½—2ĂÓŒỌ̈èL +"óæ“>-°ÛâÛgmÏưÙ½Ç|ÏË[»9‹»%>́,RD5\¤ÈÛó¡„„Ÿç–ÁäG+YQ?&`₫Tf-µ q:)Ía—v?‰1:Ë ̣˜Ø°·N¯3o;¾x¡®<àö¼Á¬ C]÷øAf¹£ÈiúSÑéúî&ƯLsPƠ.`Åư¼S¬› ™Á]”…¥̀aë¡/£€„haïhˆ\B-zx̉!̉zº>ÅT·ƒpïΕËƯ´?—Çô‹†öćêf¬ ³’`é5(64k¦iíØ(Ñ‘? ́Ư.å,úºáªjåm§°X}×Y?¢&Y JŒ7h:/2©dH³3{ úVÓņå±Qn2^aéÓáù̉Óg‚\K¤k~„ÚÂä“Ưnÿ +îŒÍz0Bç^y+Q¡HH¸\'çÎË\ă”Tü½w£Ăj3á2ƒñ¨T¡6«"Íeô0é SGntÑØ{«5aÖ<'œ7å†f‚₫ >,c¶s IÇVüö4›¨ w“'|¿œ{ü£®WåbñăT­Ă6ÍJ̉”çQñé47Á£&±<Û_¨PƯME×ï\Ú®!Msõ¿b|A­y4z—’£ Î<Ï]"Á¯ëZ“9ÆP¬êª‹Ka5ÛD–<‚T™ëùaQs’±Œvg“̉ọ̈=JÔÆÂj·…P^/%“KÏœ+mZ3é…Å"«́1=s’}e1y§¶Ô–{n{q€ơXÇ52ŸÎJ® ¶ŸU6ß 2„.>ªău\º’sn–›¬̉•lb°,ĂÄmëÀÓ‡÷Óâ9{_|M5V[mVgȪ¥Ø/gɼIă?„Ü̉çA®W²,ªđóŸø»¾¢oQQ̣Ư—€ô­‡wá<j²÷̉¾ËåÍø‚º]€éD.¢Ëzº…TWÁ³Á<ăm'₫FE‰®·$³6Æx,ÀÏM:`b:FáùF©Qrz¦Í<èÈÙÿ¬¾å‰Ơë¸ü¯“¬EU)R÷‚Ự`î3ä3/Pè7X¹Á8Åư¦úX{긛B…DƯ6ªä3(|7n¾ÿ#¬¥ÚÿNJu)¡ ­ÛØ@o1ö½vÆ€üp"é5WæÇÓb¸îưAie4'*IÖ×»´~ +jĂÙƒ%k²¼(Nâ¸Tüå• Bˆ ƒ—äˆ-Œ1ôQ~3ʯ±ÅŒØ_8ÏÛă†(MB‚&jL˜FÊƯÀÈJ-!ËèRÙh1²đ¯g¯Ïäm¶r75ănơ°†¦™JVH™®qúëo’½J„ïÊiE=Ú:`b¯ Ơ¥³:Û ¸÷;ê…K‰́ă~Ză“pSá·µvÄ?ºx”¹It2@BÚNÎ<ËÄàc²ºÇÏ0,H× ‹(á̀U%e®øR?Ù;Ü’Î̀"x†U]„HúvaßN¦œ&°ª0'/Çậ/ötc¹đˆll DÑMy ƯœÚ¶*6~}YôäÎŚûJ»ñFl—m3q¹₫„¸¶‘G½ñ‰Ó–„áë ‘˜ư,á'ûƒÚ]» +sܦ©´çĐq̣S≾\>ûµ ;.­wå+S…Ÿq¥øí5™¶CåH?÷í]~¤¸7úƒï×.%¶‹³N©«=‚]è u^€§ŸÊÁ€¶`‰Ơr‹ÙÚlQ×ƠûîniI8‡6gĂè§.µÚƒ•n=ç³ï\jª-BíçÜÓñgĂ©¿àuÄ.^8̣ÉàÅŒ®4hÆ)Á3AX ^e»½¼Dºo6`¦H gªÖö<ưżÊ2>¨ ˆÜ|MWDÚ»Z1“ Wª^/cö§”j“Å"7YƯJ'7C—|ô' `’_³¬L%ÑW IJfîä¡i>ƯåæÏ đ !́ö·ó§́É6«óû¾oB¿\ẓ́²nâ¨5—wîrü´6œ8ÎÉé +&È9ü fÙbmaÖ’ÔU3ƒÿ¢‡ÍHL¦"؆æSđËÖ _£oôCGmZ$í˜Xă+³oO×,m+±…²>±Zà…otÚµ\ó-"§ïkY'º›6́50ÄÓ–ÓzXÿ`R‘t¾±=&— 5“”´!‹!4óO í̀~ úƯ©z„ts¹MbŸ×ơ‡&Ÿs­|\Nº© ÚܽÅö~³q,iú}‰l* ´Ư›ƒ vH÷½ÅÈ]Íâ?¯Ø`ÿvÅt¾ƒ™gqCèF)V™@`GÚÆ8}2:º-iŸ(ºQ÷Œ™„üä$Ÿ₫|±7=°`8ùZ̉ư¶s::Ùg?~'¡6+•1 ˜e$à§ÆÉ Uoơ]±iµOÑXqSQ˜Á"{äVưºØm·JVÍáeȾ“©I»%<‹~d–l~4¼u½µÿñî&‘ǹ6)ÊsÆ1=-ª=âưX™™ÉpX_i,sj)¦fv<$•<ѹÓBSFä´¬¥¡_Gà}øÙß S₫1T¹ŸÍ$ô\ß·X «ß€8¹[•6„ê¹¥-ßÁ9°»Œđ[}ªëñó‡7sMÛ¬aÍ~ù2ö)x{] úÔ˜{Mr–Ôµ₫‡‡‘¸w>‡=æ6‘$.x%®T~¢AL¡¶s{8Dµ/ă]ÑVó‹ÔÁ¿Ö0ºÙ¥Í÷ărÓç䇇j/°·¶Că@³2đê62Ëu|7TưV×b#b¶ªƒVWơ›₫ă/ÆKª»/Ú©Ycâ>›á‘ëZs}WV_Ûb‘ïZQ\Â^̃È%Ư=j̃£¸¶m’‰IH7fø%ÿĹH.îGâÿÎVD îT´QÆE‚„ø;ñ›jÀæ… å]2"¡I›§ïzëAl\Óα€+ .́¸ªw}gü™î–Ï8ó£ÔR)?Uw, ¡IT2P0o²₫:D°;åßøÏäÈè°Bp¶Ô 5¶0+L®TI|‰ûƯAk[}¶ÄÜ âdâ±óP6)ÙÏ~µ½Ï²ÉÎĐ€gŸ8P&Ï̀sÍæSQÓ h%3LdEư?Í ®Ç +endstream +endobj +714 0 obj << +/Type /FontDescriptor +/FontName /KFEQLI+NimbusSanL-BoldCondItal +/Flags 4 +/FontBBox [-143 -298 913 989] +/Ascent 722 +/CapHeight 722 +/Descent -217 +/ItalicAngle -9 +/StemV 120 +/XHeight 532 +/CharSet (/a/b/c/comma/d/e/f/g/i/k/l/m/n/o/r/s/t/u/v/w) +/FontFile 713 0 R +>> endobj +715 0 obj << +/Length1 1166 +/Length2 4511 +/Length3 0 +/Length 5274 +/Filter /FlateDecode +>> +stream +xÚuVuXT[¿V@i$eé:%†î¡%”˜ÙÀ3ẰĐ%5R„€ (R +€„t(’̉]R‚̃ÑsÏ9÷;ç»Ï₫c¯ơ¾¿ư‹w½ëy6/Ô\Tr´QHœ¨„XdŒđröÁ;! EÍW”q¢àåµ@à<ÑB8á(¤¦À[¸ù€Œœ0 I0H¬–W”‘ ¬ÁR¢0 (á… +A€ñD ”& +æă qæ>h´'€›X”`A.„Î₫]¤B`®n8€¥™µ °°È߈„‚‚È9àO¤ `®Haá x¢Đ¿*RèHCh₫+êâ¤Gà~ pĂáĐââh'€€‰a]ÄN\Ш®̣ú•KñK3M€† +ÿ§nH”2è_°  ÿ=Ü-n‰DxûzÿL€(₫Æ\H, VK‚oàsÿỦ" ü&%~ÁNHxH…¹8yb„ @xQa|ă„ư_â?w 8†9®„cø;;\₫Ø9á0X –=­nBzüńä€ÄơnYèj ÿsö¿¢ !¥¨„œ4HTR^†àBF©füK‹?uøBÿÛ'øï”zHHáq:₫9’/€Á¼ ømcAĐæ7Fá0$đ·úÁ2`‚k/‰ÿj©ÿàÿ«±₫YCÛÇÓó·*È"è‚~)âé„ùW¸“Â3à¿|đÏ@kà÷ÿ?yôpN˜:̉Ơó/™Xm„?‡"p0·?̣́§Êđß÷€¢°ˆ_7$*!#ñΠó@X,á,~S₫’ZH +@º‚̀qW:aà¿h˜Cç÷¾ưsï‚ 4₫ŒblSrơö¨RÍOt±_ªUỌ̈à§§4E‚çùy1¢cfgl̉¿É?ÈÑ„öº©”ÛŸÇ'³i%Èùy(@ÄHé¢é‰tcY7Ī”©vÈ>|·²¦ÜeNÏ]ƠèĐƯæz~`Ă«¢ÑGoG1†qÙ.¯x›\d»ú¼ ŒÜdeDPé$bËD×3ÔTñâPw£&Ø=âN:¥~ÓëÇüú¶”¯7Êè‡GÚ Ô2aCx +ÜËg6›gr}M’'n%ơ.'•Ưè}©›è ‘öPüëQ·åWwÇ̃ +{„̉]¼ß₫4Á“op–Öä"}¾–J$z…䤸5 „^Ùü ­Ø½ Œ/²mÄO®æF)́¥u=¤zn;×M +NuÜI/¹ÓÀøŒtªL«53.ùI+„~ÔxĐ&•Ht¾£̣À¬Ræ,èØ ́‡Ă–sºŸ­îÙ +dT;£«ƠRTt.ŸÅ"‚Tl¾5 ç— ¸€y¬ŸÏɱ!Áæúx’2¼ ñîߟR²Ù"3K(¬&9GW +²ÛLuxv+RƯ`y*₫BŒ|üĐ*™DV›EqL”ÇmOËóüÀ ½lÙ¡±́€A*oöD₫6‡SÙưüZȳX2–A*›µhöÚG±]wNÏ…Å|3¶{gư™Ơá-‘jgëàơ±c±§,‹à-Ú[›),­TxĐ½íÈpx“?3·ø#”7æXơ†±8rX+4¹–¨RÜtØ —²’²tg¿8Ÿ¬Ç¡Ÿ*WéDGBl\Ù\ôzßY¯ƠÏ%Ù‰‹qGÈS?!q¬ă´ëMIú–„NËùŒî~Aß.Ó Ơ/È ơ¦Fê2̀FÓ&÷/jT7gÍ®ÊAÖ2̃ô¼'?m´¹µ1¤Ư Ù*"¢; yK×ϱl¢ +í(Á…¾,©z/ÚØ-ÛmA57‘"©${`‘=‘^¼3É~Ö{-¨NmA]Ôö°dÜlÚ}¿×"¨Ïú:\w’¼)l÷ă ²çBå ©™…ª.Qtđ/vE®́‹&dv%¨óèˆs±'ƠăŒB¯wđm6 À–z,©–KĐs§†»ÊF„0$>g +çñd²˜¡—X #+£ÁÖÏ6²—y)Ît~+p,Tª2s{ŸLoï£56œkÊ¿S–¦_äµ:Pˆ¯Èé‰h¦ƠÁiT2Ô‡xä;ơ˜DÊü©8X¶ÀLñZ|“c̉è—€ÎWSkºZGNÑWBX=+»€¢g}%“/~¸.…»~ûˆ®œ\²ê#äq·n¾Ÿt¶çơy9Es3ï§Y1ø̉cl¬V­‹ KK}ªnôs¶0¡ª+̃O˜øö“…÷½ÜÚ?¬%Û/x’FöŸ=ä(6ÔĐyÜÜQưC:{¦JŸ²Ø:₫+oLp|Á7æÀsfåny‘=âZë'gRÍjjó›E4ùJ‡Ît}xû×4HëidsÍî ½ơwë•"Rj‘Y8u¶ }©èqâ[V®\{ü°> Àø‚ơعèÏÍ(*†³xUô—¼~v/ô=̣Ï‹J½¶F×4ÖI»tÊD¾ß§˜Ô¥·À.Ÿ j 6ë-ÎkÅ唲°%’ŸÊ{™ô«ÅSGsÄÆƠoˆÈ2s´£²ÎÇ$Ư.Ü[ªHHK-Û^g̣2x›D铤±đ‘r;ơËơ¬—LlZ©1¡î%b?ù̃ô½ÊwÈ ’qYƯ3ËL©‹¨Œ§­¦fY’jqơ_‘ÉơÅ`—$@fÀŒ¾ĂÖ7øfđî\ÂV­jWø9÷©ÍÑL“ƯÚÛ¦ ©w'œÎĺ¦̣IA¹å¢L µ₫=™5}₫{Ó>Wú ?’¹íĺhy?º zĂ@4±úøV"u®ªZ²Œ±• ~Yø`üö”Đ´}éŒTc¸k¥Ø5f%yÝkßÈLæ»™Vx.ĂÈñhY³¡­©•fĂÖ—ë̉ŒÚ@ñXç₫×4ꈜ‘-#ïÍï)F°âæƯ\Xv“³Ñ`o>î`åúYn º$íT§æI³«¬jsÏ̉aç`}wN^ s]Y. ,NÄvZc_ëf)”Œ)ûÄ\¯%UŸ¿‘¤'ÙnÀ¯,é ¯|$oKuA“Ưæg[Hܶï些ˆƯ`ri)?÷‰É̃ÄRAa_2öǸ¨>"¼®ùN>Ú:6ˆ·E‚†m›ă 03gTKŸ,lµl·3–|ĐêrØ]åc˜Ưhµ‘~`>¼ÅÜ~Ù¦ú[Uóƒ̀4?¸°û^’ÚüZ¼Æbذ[2àu\Dù0‹T;×̣nơ÷bˆ²Û9‰¤ë-(0ÙŒ#»Ø­Ö/:ª ›§a›£]9Ÿn}™B¦ïÜ4wçEw \&ÅæE%N‡7(ÓÜ`êü”1Êh˜Ëæ²a¥Ư2j’Kÿ¨ăê6qË©ưņa¢–F⪳gdvÉ@~–Ú’W‰Ă3₫́ØçäƯ÷ßk¦­Ç`¬o¾è́HiHYZÇEF;Ów`ºh%&2iæMâ/.4Xè»áë}èènSѨ<ƒp2·óØÏGûAÛ9XqÛûÎơÎ3ü˜û͆_¶:́gª6£¿1إѹe:•l¹6p^MÊẵ4LeW˜Hàv†ö-ºOY6ÚÚ₫œíù²™úïƠ8 DrcX’·O’|ôÖ>ººKŸT£9nsÈ%Êœ©\Ä8›¸RІ];̃É Ô%bμ}‡ëbîâ½îøđGˈ ̀‚Ê¡½̉.w ^Ùo«”|yÍKÉçƒ(©Í¨`Ô­́eycuû̉Z¯M¿¾æ^¶íOAXÏư:óñ"ă3̃¹ÂŸ?Æậ‚ÇƯN_|y¬_úÆË4-3‹¯Üt̉Øg¯BÄJ2^óăȵ{Ù–(%a6/‡†´m[÷ŸrÈ¥(U‹±ö…Sơ±‹ê¿́}‘ ]Æ̀ÿ‚4cíwªˆ"̉GÈÉq}Ü!kI}ÚH£‘A©¬Ù m÷*fè•{Rÿ( â]ǘ³Ô¯Tă²́Gµ̉…6Ó·äàăVOÙ«˜Öb¾©’´jŸmV¿oÁLy"D×=Ù_€âGøCGu¼oJr̃÷¨;"ï&ÈhL°Øu³sŸw†]xô$VÓ›™±‘!øÓøđ*úµ¤Dx†Ä;A¯ơ€‡3³(¹R…‚K¡|³r%¥”¦4º]² ï£Œ×%1)±·~J †­BçÛŒûÎÂÍŒîVO^_ø!yÂPC¹ê“Ë Q™1 –Qæ1ÅZ5OÇgOÆœqµ¼§uª#Ïëï=Ù<·¹ư´__Ơ'¥C„KAæ˜$4`eô§SÍ0?¯uÜvëTƯ´Ă¸ăƠ{]:œÓB5Úl0’`H6pf¯<ư¶Ÿ$“¸ê8a ÄơÓ‹\±û^gZ—œvE=âpm\⤖‡Ö~¾JUpól¸QDP[qs©̀n˜^o×s‘ú¡ÍĐuăx ¦kSb«Ư Áơ;Ô— +¢>’ƾlº¼Vwë»x³‘ç0}!|g£wtÀ”~¿œ§û©Z7Ö$­¡‚’ÂTü‡9̃9ØA“ 17[ïvö¨æíŒe|per>qHùê€ÅÔ\É¿I A6“jT†đÈĐŒ0œ~âư1j‘÷U­ªk®8·;v˜‹÷î`oPº;ù¬äçø–‹4#•8Ư­¯ä«Ræ¾̣Åä d[øÀ+´yÎ}5N ́O—Î997FaY ÂÇÛ£‰̃×XË ¬iá»%v®ë,y¼,h +^Ó>¡ 9¬(4äà¬l̀i5đ"¾ZÏÈBD“ô×®³®<È<PA|©Çê'Qd—†¿2’œróÔHû(]©&̃¹åÙ))ÂO^äØưånœơÉPëQ¢‡}»:¾4Bô*Uó°)å‰UèÖ9Éê9Vag̃½(wná¦)¼ú&îsF\)Î +}Œ+¹+X h̀̀@SFöWY-Iô›?‘L¬2Èăi*¾Q`0¬PÈ;†₫)$ŸÙ%ЦS[&è=çjöW‡<™å Ïc‹œ̉¢M.29ƯáưÍÎÖÔa>+¾­2½Ä×ïD²ŸhD^̃)¯e ɤM¹²¯(•_ )̉[ëhñOö+Ͻ§¤ª/«¿|Êïú™*vàªèRÙƠêt;Ó`G½+­WU^ÅÈ£wêû$jŸ=Uuˆk£º›.\)÷ +ûzŸïüßÊ[$ª/½c—ø¨”X²½kÇƯ£¸Ă[C¡̣›º"üoå¼Ü/èª|ơÚ”ó«ÄÆ[fCª)†Ÿ²ÇÊ \”ˤÅFƯ˜âD‹=Ö…) K8) +æ*Ăà́“G¨wĂ¹AÅ)è·7Ï–é¤Ydϲ̃y ˜ŒáfbºËgơơ₫K®Ûø‘Ç3†₫Ơî=W5…{ăv»BMÛ“ ªBS&¥àE|µ†yăAŒ烡*v öÂ2”/fƒQd«}X â5éB¤h‹NHÏ`!{¬Àà«w‰¶=Ù:x+‡ÂJÄ\¸\Ơ×p©Q$@“å¾ëíQø‹\âçém§ôî®íØîX“½Æï™˜ÅFHÛîÉ7ăp2[ơÄ1](§¢đ«œ;5ëØw,'îCŸwvưS´ÇöÄåXưäí9¥·N¥¢&chÆÚCÚ@¥}r#ûÅƠœ:6‘²'fGN¨ÁBÏ&æeÓ3>;­i_đbä‡÷n«æXîf×<ßǘ¬¾³[hA·Ä+âf̣Ç8&cW'üo¹ƒjK¾íF>“ U°7< }pû˜Ÿ¦w˜¦®ŒQ đÅù~Ú5:ƯÓÉ!2¯³÷aܶΗ3á?•0wÈÚƠ*yäË̀æđ6ÚđPí(WÁÉÑ[#NqåKĂƯ™ª ê;3¯ƠƯP+ÄôîíÈT°Rˆ́1âdƯ”™¹×>™¾YZñá)_‘j~]´…î6&̃>ÈÀ.Î×DÚT­J̀bP̃;ù¼.^F£?„†¤$8L·mh?6/=52̉¡™j«›7¾¯0 <Ơ zÑR³±^wEJ7à¨?!nœgüÔ è±®“K¥›Æâï vƠG\,hE}üK›*çÔ8“Ù‡¾4XÔƒ*w›HƯ^‰V©-vÈa5©¼U¤̀׸æƯÑ÷Éœ´B¡â°y³k =€êÂívCư4lÚ{[͇h<[¯'E’yuÛ ’[┓S“n×I­².wFÆbC<å\†{`RH́·Û©tCơƒ„2¥¶˜o€·Øøÿf6 +endstream +endobj +716 0 obj << +/Type /FontDescriptor +/FontName /IXMTHF+NimbusSanL-Regu +/Flags 4 +/FontBBox [-174 -285 1001 953] +/Ascent 712 +/CapHeight 712 +/Descent -213 +/ItalicAngle 0 +/StemV 85 +/XHeight 523 +/CharSet (/A/B/C/D/E/F/G/H/I/L/M/N/O/P/Q/R/S/T/U/V/X/Y/five/four/one/three/two) +/FontFile 715 0 R +>> endobj +717 0 obj << +/Length1 1626 +/Length2 12707 +/Length3 0 +/Length 13550 +/Filter /FlateDecode +>> +stream +xÚ­vUT]í’-îî×àîîîn›»KpwwwwînÁ5ÁƯ ÎåÿOwŸçö}é{Öë+U³¾Z‹‚DIơ‹°©½ HẪÎå 3@Á̉ÖÄƠYÅ̃VÁ[î‹<ÈÔđ!gG  u»XÚÛ‰»€x S€`a0sss#PDí<,Í-\Ôê*4ttôÿ”üe0ñüO͇§³¥¹€̣ăÅ dcï` ²sùñ¿vT. €™¥  ª¨¤-­  –TPH‚́@NÆ6%WK @βsÑ̀́6ÿ8€öv¦–•æ̀đKØ` pv-?Ü@@Ă_*z€ÈÉÖ̉Ùùă`é 0w2¶sùè‹=À̉hăjú€¹™ư߀œ́?,l?tÁ”́]œN–.€¬JbÿÀébạ́WngË5À̃́ẲÔèúWIë>Â|h]Œ-íœ. —¿r™€¦–Î6ƹ?‚98Y₫ ĂƠÙ̉ÎüŸèN sc'S³óG˜ØuçŸu₫[ơÆ6{Ûÿmơ_,]œA6f ̀,9.¹Í-íÿi;3{3Ó?䦮ÿ©s9ưƯ ê¿f†æ„±©½'Àd†À¨`ị̈‘@ư¿c™áßG̣¿â ÁÿzÿÿÈưW₫Û%₫ÿ½ÏÿZÂƠÆFÁØöc₫±cKÆØđ±gr€¿«íÿåblkiăùÿrúWkMĐ?ĐØÛ˜₫«NÚÅø£%Âvæ´010ưChé,aé2U²tZ̀Œm>úơ·\ƯÎädciúàơï–¾031ư‹NÍÂhm÷́ÿṔLÿ₫UƒgÔÓĐÔ’¦û–ë߆JCà¢æéđí?J‘·7ư¯Ă_aDD́=̃_˜9¸_XÙ˜?î̃ n&Ÿÿ!åߘÿy–7vq²ôè~ÔÍÄüwơÿñüó¤ÿ/aÄí€ö¦ª‹±éǤư—à/5ĐƠÉéƒà¿/ÿGƠÿy₫{æA amÙÈl••áR›72%¦;ĐÇ 9âPÖ¤V\è_kßë—¾Í]eôRÂĐüç­ƯséÔáu_†ö`¬džª7ô«€Đ‡Œ¦¿}ƒ²““î Ñ  9ăL3ÚûrQn J‡ƒIă`gJYÅ ô†è{'«Üå2·B,̣{_`ZcvZ3F}ÑéẻñŸ{ª¡ñÑ‘á̃kè₫ưOt¹qđ¼nPÈ”Q₫¹ŸuÔ«¼cqĂXjP0 ƯI±O}[OƯ„°!v:Sê]kO À0ăhëdBCG*Å&ÍƯø1Nü½«ÓebŸQ῭nï>bđ‰vÙÇ̀d2J[%86¿†Á™¬ÅÍaT+Чi}‹3>åµïKjDâ¾VøFĐñ‡é—Û@"…IùtŒyjJKŸ'‰fç’æˆ`×Qá%i,éÆ ‡¨_ן§R›ÜDíĐ6ª’U××Ás&Mïgµ«xR£’E• ÆË»ÛPèr¶÷˜f9HyÖ@ÍÔ¶c₫…˜à!ÓU}ªĂ”Iß•ÔưTä¿Ndmë¾§¤ƠÜÍ ±ô!!"ÇLsXèỄ́¢éF<ÙŒ†µºq’‡¥Ür95ơ£k0üp”®‰`á@/$›F]PøBÅû³Ô”)];y₫aE$4Xûf§D#̃ÓpnÑ0ÚƠGFz¹l9@Ó½3;Ùføh>[̀%@£ù„¹H$%ïœ+å#ísºzó¥¸â“@’9cf§¡’È%I}K ¯-ÀÖŒYZ¢4”Aë7#j)×SnŒÿ=DÙĐ`}oZ7ÿ†Jô¨ Â!̣j̉¾£‘v́7Ôûù6×—$}1Âf/œd‘8 +́ăơ¼₫ÏRϽ§ ¶"¯’2=úH*S8Q×jLúª 9I’{oàW.#öÁ7ËÔ·ñ‹=Ø•\n0‹4Ôí*HNơ±ă íơíJk¥Ë@æ Ú;w¦'ߪ…Eùƒü¯eïcº5ØÀ–×Á{hIêñÍ4ă÷Ü‹¹%Jº-ÈÁ{dø6_ó•ƒ}Nè…Ó&˜ư~Ơ.Ô¸(HCÊùͯS(‰¾VUO8CQ§₫ÄM3Eê)ô’Î×Ú~"Ó:;Á%‰fˆI»Ư(2ÓtÈÅ„ ¨î¬¸…H…&\’PÛÏé$½[AYŒ̀Ú  RÜ×±ï©=$’CL0 2}§SoÊVÙæ[r#¶øÅ̀_ÊvµAË₫‹¼£|iw£UnhèËÏ<'¹3ö™u©¯½̀’ƯÈ$Ñî­âñ¶¼¹Ă~[…ö0¨cA¡"¡=}°AåugmÛĐ‚}«É€ë$<ΫC?JÛ”â>qúî\.¬±ëÁ!C²€¼ä,Æևçă¯Ld̉-¼0à_K…̃ ËĐ(úï81ImtbÓ—*hÈ©Û9ƒ/¦¾%Ú—ÛIk°á ³"Œ‰q<Ÿa%Ÿ4TT˜=CĐr®µ€”¼¦ƒ3̉p¬¤¸À¤y[€È!ï±B¥Ñ;3\Vßøä|©xÊf¢@ D‘ÿû‰¦a‹y„ÚEK©ÚÏĂne¾ŒEÈ^Wj+±ä9¨z&xé¨vQØ×A[´,ƒHk©–íÜXX¬h <ÏG.y³Ă³¸ăOÍd€SG**_Í™<…8ÿZæ B­œ^)íF4xøkJ¢_PĂPÉÅæƯHñ”¦ú^k4† +bÚ­# ½v,¤¿¾º–t (äÖhtXë&èø È“—QØ:ă+³X)VbˆB‡{¸sBh^©[\ưë,^ùBŸ²®áùw¶Œă8Ơçû¯ôl +63àÆíïF²ª&)S!—Ê +z![x̃@ÀTœ¨öă Y¨èúÜE˜Î©øÈU¦çyWmà œ3{q`§qÆ}»ˆÖ¾ gNU9ƒî‹á¾¥`íÑ₫ËY8½9{ơ¶–ƒ°U›Ö¢²½0»ÓL‰Ă»ˆfͲgú¼‚©‚̀å9 Ú[N!â©GăwØœ)è«ne £” 7mô0á€xΤǤ$Œ_ß°^‘đÑ1 +Ữ5jëqA¬±±ÂT Ïæ )53oï‡ÛB²ƯÎE;í+)́¦Ù·t¯ùÍʉ`΄> ÖÚbb™ ^[RD|±¨Øœ}4́íÆ%n'̀êêÅ­ëñ" ÅúÉØéîh¨AØ»ÅƯăç]WMË»ë^‡>“bµm^Ơ1|Ser¯œp§£ºĐ‡-¹¢Ew‘jG»DưϨ[fLÜZ©Ơèë?­Ô·½!ä£éÏ)t%¤?ÉK ñ ‹Âwf>’Ùd 6>‹m¦8KpAK̃SHưñæè’–̉$3Yˆcïߺ/Í’k´0·I.<`a¸Ÿ‚ó¸™toT‚—‹úfyXâ÷²ÙuK± î¿í¥ts€FS3“kâAyÜ™Ét¤rm)ºö QsĂẦüh*¥¼ û}’ªNlỈs'g—Mr<ĂơuQĐùËE·Ö³}±½·®h”»îSÙ»₫µ$J;û úºƯÆ7÷.‚ưÎYÑ­m­†›ÇÙ8®V8+jKµ/ï{™₫‹8¶±*LÔŒ­ËEѾœpr8îĘữ3D°Ö±_/ơẂ&²èZ‚̀ ¡µ…”Ă<‡›çWP¹Ôa–DóđñùudG(|æ&Ľq^ó +lû\PE}î®›Œw« s')¼ Åäçê/×ƯBtßæÊjxư¡4>éå_¼*|vü„Ó‚>h~–G„í¾́kå…›æY•£á\µpZă¡`Ü đ/îÆÛ<?Èœ$Pï^׆½*ĐÎÓVvé·R6ŵ_aÁ Û&„1å©­®a¬hJÄ’¹ñö\̣Ÿ:)‡]r]÷¿¹Ư^ä₫áÍÑÚY8̃Jü†ƠÂùÙ@¼ =4ÉHRî†éÖWÔᢷÚO˜ß„ô!lNmN»2æ «ÿ^N)z·ye{LëR2’*Ǫp>º´"< YYđˆH˜nt +œ%ê€KÍæPöFûVuM*‰Ư}ˆåé†=Îv¦OHÓó¤¿ÈɸÍNÙ¶ETbd|Îȼu‘<œ*¬3ê„_üá³ |Â’船a`‚©jv(ïlNê²9Ú́" fk¶ =Yµh³– ,Ô¶ \”n\\¤9{f§)À‡lo”n%íÅ™½~cÿ¶µëiü½/₫&¡¤ nwvÁˆjÅÖrÔˆCüÔk×> áđ-[?ál ̉}ûs}­çi`Ä ç÷|Ñ£î·Äø€©EÿïIC¿¡C½'’0»đoÚơk‚ÑÔôĂ/úơl².ö^2́ßóHZMÏ~̃5wNH@U°·ø¶‡£–`ÔÁvY†}[:₫*’ø.o udYÁF¶¨aÊrŒ‡ă ̀?r*¶|´•g+$%¿Z’ícø&ß +ƒ<,xæxưM™ưÊ·NÎpføA—–Ÿ—KSx#Pë\¥J0¨¬ôÛJ˜É¾À“i¥Ơ‰È¦zß8C7úƠ)˜-u€‚Èv\5éƠêƯđyđjDư™°0ªS<̃-ơA|âj#«ÉÛR@g +sBĐc@Μ-§„svh¥ï·1;’¶T¯€S ¹ £Â5!7ªqṿW7ăçdƯצsÜûŒ”Û +¯äTµDÊwOW¤9·ÇÍ“́"…ú₫Øu®›ƒh<Ï9˜]¢Lu đ"¿­ 1ØCζ5à‹̀Ê×6Åfèf§/‡“Ư¡×è€>2ÿ„§,B§Ó̃2Ö|“†9o‡}‘ë(^ FD ³kºÍï*ư['¤¾dK}‘“Á0†Ê¸¢›–™êïG­íR+3̀/́ĐàÅ~¯| ªé/•[₫_C²—kƯ´Mc>4D3  1ùÇ0´-pEèfîInbqéæ—ăÛ́údŒ¨D₫Wél¢Ùt\<lK²nœ)¤o"¦ƒÅ¿6ĐG¯²6LŸmiF¡ç„ÏsëyË̃æÛíaĐÆƠ“¯¶óbáy‚ü´Aa;w6ú‘Ø*1=Hµ_ÍàgYW§¤>×8Tn¢PºM ÙÊ”#0q+]ÆÆÀÖ8”̉E‰n8ÂQ9Î+ùˆ†¸0Å‘Å+ÿ€û£üp>ơ%Èú́=“Y«¸k¦’lÀ¹%¹ñÁ¥y½öˆtÆ@êöܯ—]ëJ‰Ư1ÇVѪ'Ăˆ3gÔ7 &„Ïœ¶a&4Qză¯C‰|đ¼m³Ö/°¬ÀRÚ9­ƠË¿ÜöƠÀÖ(»̃´oƒŒ²Iù<ÓµjÎHÔíÓ•_p“lÁˆí¥ÿô¥](™½¾]Ör3̣È1ïgæ’8̀Á>íxZ¬‘u7+-eៗ̉ƯŒâe*ĐkVI?sбz*H¶JNȶçúúfù°cĂWÊxÄ…ë±=’Æä=,gô:~‡ñ̃ú̃åßJÆNyÎ ̃ÓÀè náV<œ¹¶±¼rƯÙñÏâˆbë°e•xZÀß«êoS½tm*æè>8¯¯‹*¨µPÀæ>NË%jç'BkS€Jó¯ ŃSD€¤à÷}­₫J‡Â˜¾F~±T¥̣-ä·ƠƯg!®P ̉Ù¨àÆ” aC¡†Aù¼1|räi®ïµçă"Fz̉2W³¡¼éL$„!TV|+ƒßÎ ¬I¨RT®Ó~ÜSh[Œ"ë÷#ZüÏW?¢NƯ<ü[aä¡kÙ†!è嶈›ù‘2O!ÚE‘Ñê‡èYè\ÀKÇ´÷‘û+ƒƒkS¸h<Đ8f¥Z5|ûIs5÷ÑpÄ¥¦m̉•«Á{N&\­3O<9¹ïñ–đ©ö¤´¹-½ă“íu9N₫U5Á‰ǜˆ}ÿ́X! +¤Săr§µ_}É)p!O­¥Ă¬́fb&R7— kGß,nøƠ¨Ó )rÂù‡ç—ư6lI~Rn¦˜‚D̀m9ë†2Ji+\Đ˜S°ß˜¥GBªUÂe ?ĂH½Ú†€ènCóI!£ÿG`5¹nZÂsÂO/”|ÔR¨ûkư~RéÇ{8)E=Å…ï¿íËøSRÆ(o ³ZZç’Vú˾¶£"8Á­.O2A‰tfưEï°ÛFåȉ µ? ¸óréÀ>_ºÑ-%MD×´-¡ù#À‰1tgM¯â{ûMjƒ÷ñZѸo3ơ<(«·Đê»S¨ä}¾Íoaí—ÓßXĐÑ:%t¿ÛÙœ_[9H3Xp\ epYŸ‹Ö `(¡4Dz˜Ë›́ë¶2{‹D‹¯vÀ˜ËçTœ¸è!»uăÊ×J䀿µ¤½ÔI¦›Ư¼å=M²]&Çé¹¼f36—í:­O‰‹©Jtqb0B<”âK ˆGâÍ¡gµ{¸¤n-ªld¥|D}Á÷¼Öª³J‰₫™mÇ`Ư4&©̉‚=Ö±²®‚¦\́Ư5H~Ö¼œúåVê5ræäRÜB'Vv7:ÙXe…幨¼ï½Ï< ]Ó7C©WÀør̀₫å€'«ÄQ±‚5Eø}̀6bƘûÑ´Ñé¯xäÈ[3Ơ ¡¡­˜4«ă?…Å•…>®ÇĐm…5ñÛI£…ü[==ú—¿d%ĂW€đY‚@Ÿóm¶®ç4âo|ß!³£|²×O,$óÄë…T׳/,pÆúÆ8̣]{r\ˆđ„`…ˆ Ü–˜ÜU&đ°|-.){œÅ9̃z)´;,É„S}ïˆ*Ûí­à§BphR›[ZP8([ƠWñlyQưC®0%&cq§iW~ú´÷>æ2m!âàŒ‡~a"–.ßvº ×?!v’[u.*³Ø –̀ kêY G¡ o„n+àưÂ4'ëw¥:ÔsÎ ¢º¡`U₫yêñÆú;Uùñ#H‚ë÷B£½êe÷RüôF‹êa!T^*ä₫ï|ÚäÖ́ÿ]̃Ë ,×§²3^3¡Ó‰Ï̉!S\-TÀ#qªya¶Î'!¨Ô9ÍÍ>“<‡_#Ÿ³ÖÅ|6<>*GˆB°4Djˆ)ƒ! @U,ëmÍLlÏ x«,ëo: QqĂ½+W$–  ©3Ú3Ûh¥Û›«x¨̣®f_ËăVi‡̣j̉®SqT*—!w7b₫N¹@>â5đ‘±!X’‡±{ņ 9a ÍoĐH_`Ê©ÓÑ +÷¥‹Íc®7Ôcá kpÿC°p?öIă³±å3’ÅΔÔB´$iÈ4/˜#ÿ ï È †#tæưϧZ´E|]Ö…“0EP#ŒAŤu û9%`Û®¿ˆ7³“s1ZƯ¾­©păuºº Å\i€¿1&”XïñÉ8Awˆ'ĂËw¿÷Âü'”X].ß”ŒøǹœoØỤ̂²ÛŸ™Fv(…î`’¦ +ÿg’1¾ê¯AÍL[ccâ•‹äc§©³̉ädµ2j£¸IKá}6#ºq®YơĐ´ơ*Ü lÜ´0q{~§Û¼­‚©Ä(ÜWr$̉;3ËyÆă˜8·LJeä”Ç\p‚¿óaŒĐDN˜2ŸªlWB[G.Rµâ®ØFC97£‡Ed`W§?뮳Øp'+±C*ÚăÚo¢7}1_CµN03H˜Kæ/[oƯ¼¢±‹Úµq;“n>WŒö™ÖÖ¹Oö¶BÿQ‘ưU†½2ö¡DĂdĂÑiĐ™AÛJ}€ËJ×t`“Øæ[Íq'Pw•@|£NÍpø̀¸ˆó3ö±ÓËp>îñÊÚ°¿ùÙÛÎ‹à‚±ÛúøQPùoI®¦(Đ´ù’á ’©O´ˆ´“­Pø)À¨n)¯Ù ÆÜ½åó( çk­â zÀRÂm˜zB'Z˜=íỵ̄´`×L<_£S,=̀Ưª6}>‚1ơ;ïç•Ưù.9’v¶ù«^¾^[ïåÇÆÉ5Qå\<Êà§X­I>‡ö¯É»®\e» YqÖ«cƯÀU±ÎyăÂ|à ă©^EZHø†•O<Ö(,²üSöđË9{á|VƯ,¦đ÷+©[è:N‰ƠYy¶,‘́¾d˜–¯'–5êÇXƠ‹ â+ơíçø2 ưúºy¸ 4_n·LPOílÚư/º+%HƠ‹¹²ç=] +1bâl½mÓ å4‘œçđ´{V@Q³1†ÿ>ô Ư‚ăûG¨y‰¾VÂÙVÚAm0FÖö}ƒÅÊE£Q0B :•<æÓeQ̀Û²ü®¶¸ O₫Jƒ€g(U;îQû:YơY÷÷EB$ă¢ )ƒÙMGpĂ—_ø{—G<¾̉ZàjäYºÙGzüvN:yơ$Âc–ûÑy&«`:S68H„|¶í‹ä˜,÷™ưMàú扉!¢¿«÷¢ X úèC©’.œĐ£JvÚébựQ¦ă5IËôæ¨k}Êik’J OrÚ¯ 2.qñH̀ñÄÅÉ:ÜHw÷¾‚8] r’’6Æ5•ô[R擌(ø(}á›4.V'1ûv…̃“lÂkÖà ¾_0jR¯—̣yđ ·ŒÄnüE¸Ư†çKØù@îCTI-t6 ¥àfaü¶­rªå @Çü8ửC«¼Xe]Đ₫¶̀÷b9ƯʇÇ5áK=^B4꯭a—w¹¡Íe´øÙ±Q†̉—¿ü˜Ï9‘bf•_FSè,ÖCÔư5.7Ă4»…–ˆ›qív/ă(dá/°{'‰†U) ¨ˆ(Ø>·,Å{§Ën¶l„iđœ‚tÎϧ~Q¸9Gåƒ3-Âá‡_Æï°äú;̀§fèơHr<屟=%ºY_yKt¼MŸs„)̉á)j•߯”#́› vI·"ͧư †•)w´Ăt‡́?{)g¬uùÉé‰^ỏQá¸D‰/eº̉°„j½¦ 'F56l p˜JÜ×ç33 ÅéH́§;ÓđÁ«ă¶¬qÌ5ª]'¬ăù´¤Q´`Ê'à'ïky¸~ü½pOtrß“ÔÁ±n ˜GNàW½OëjùO ÏHvL@£f!đß#<(đ1rơMœF4Rñ«#4àë3R¸Ggä+6ôÄp9ÜïAÙkz ‚1w-SæM*œßà~b¤o…?‘Œí2á·̉×»¶ÏbSZ“̣A +¦g§usq1ÖÆ%Ơ¹¯IGTẒªĂde{´Nÿºz:“¸jn H́´jp²̉Ë@€x‰a}½<Épëç ½ä¿x\æë"|c˼7û¦-p̃•á˜Ô3¸¶ÅN<Ûúm[ ªĐ©,C"æ2;ù|öhC̃Ë ¢T„eNg§ƒ<I>Ÿ%ZóΆÅàr§ÈG¾vŒFFt¡Úv;ªº”ˉ^ [NZđW™BÍZpoĐñ)¡߈,»ÅU¬¡±øj̃9J¢Z/s +Û~4Ë̃ÉZ‡º–A˜̀1ù³íØô¹ƠÏ:v´ºÛ€½Â‡ û:ñèĐö¬5#{º Çêÿ¸q¤”£HœúĂ#vc°°Ê”ø3ÄÊ$2 ¥¢.àÛŒëZn¶Üú ;tîRj•„~—#c?¸XKÇÆ W¾aF±Ÿ½d j¹8›HÓ̃=ÚÅ đưËë†ßíö÷ĂØ&¸/ØñÊR!i]^j“i$k0 ÙE×ĂDQ ¡ß¯•RÊœ +x¤ÈÅ9#´÷SXÖúü Úê» HôÇ1ñIØg=f$)dà~B~Ă\èj̣ƒW¡¬–)åy&Qʵ¤HÏuưL6¢v“Û$|"%Q^²)Q»Ơ‚2*ØOÛz2Ô6,ÅhÙÔ˜‚²pg©̣CÙ´„ë‹rir†à9ØĐÔp¼w§¦NprÄơxÍä܈ U‹RDAh9 (@*.â+X¶rJ́}®'óĂ Lmöä€?Gí…r|yƒ¢Ká ×ơŒ́ÜeMwäï’»ÓÙ¨₫s‹4»©Ôâư&n9­ˆÑbû·n!ĐÏ„dD}„Ü‚/Lé§×ôSWѺ-1 „‘qÏâGí̉Tá9·(Đgl6›ÆºßïĐư[yzR¨bO‡vWk*Æ{²‚́yqdºh́4ÜF‚œb£­S¦Ô±IƯùá}g­Í™̉¬Đ’æYÓ—Pßl•é2ùw: sñb¡ÈK‹È¿¿Hs₫ΧfZ¥ÂÂc8Ç,PlÔ>åÊ©¤jÀ9.}̉]δßư}S‘Đ.U=Ö$“iH–Wÿ%ÊÄå©Eă‘(QØ[‰„3ˆ3X m™º.Úd1\îƯoÍÆ-±k_]ÑÁ L„~,~]'í!Gî́*„ùî‡ecz“wê±ÉWơ¤Â[ÄË*Ü{₫»3&D­h—!Nˆ1,¤.~₫hëŒeë=¶-?—®uÅ!×Y8A›ùªvΤµ–›*¨t¾º5cNÎnp›ƯJ,œ(l_ÑGÏ€ë÷”5JĐƒcƠ´E)ă§™¾O¾¤̃ñßÉḤÜœ?¾~oÇăÉ}Ê媋ª¡10d`v-¨i˜ŒX6?®MeU+ü̃‹mÊä@¡u1ôƯ¾5X-¡™I4á*QcƠÿ÷ö½û!Å’3Ăvư³₫PlÅÜ>îzÀÀÂH¿úöÚEKP!̀]ÿa₫³Rç*Œs5s›JTRDưOœ×Ïjd‘SÑŸZ.œƒ=‚] Z¢¢ă(%t¬øYúÈ-5÷ˆ µ‰NeØ‹RË×xNÑäÑï3î ¯«t!Éđ4Er¹m²f!¨Ht*oQ&Àđøx¾ü9ß&!w³)ç76Ă[›đ‡É@]6Á‚ư$Næđc +ñ‡̉Çu&æRŒ¿nöi,yµ`ơ—’Ó¾A8’e[£9júC«ô0$Úɶ‰…ºØitĂgïç…³KQƒ\êW &O¡L9 _q +­¼®M~´¼¸­T|©‘́Ê₫H`¬ó^2Kđ9܃l”;e+N¼#TÀÖ₫ÇĐA¬́:!]<§»-ÉÖ×ưƠĐp@øöh¹ç̣d÷çư»w0́STFCçÛ)ó:^Äm­HºÊeƠ®̀ñ«ôKvÖç¤ÊUp(Uc%·yIR á´Å!öE¡H°€OÓyS§îOÏÛÈIÏ#¡„ÏUßĂ,‹́’bCbE“¤¢`Ù̃|Ñcđ²'EÜơ45àæuÎÓ¦ >©́‹—·¦Ötñóà=ü +j¯ùslVâ@ÉGÔH»g‚çªç?¿³R†Ü"´&¦~¨Â¥9$P1€7C„îåÓù'êèü‡ºñ^°^†ø·¾×Ÿ«lIư@¦ÇÜS¿Äœ€½år¾M;a®ñÛyV°̃¹Ie¡₫Muø–® d´N:²ưZ… ́8́Ăâ-Ó=iËP63)ÑđgdzªWÓkDOăÄØŸÆD³3äÍé¯Ă-4‚׿øe½¼P̣ñ‹µ9µ_#âu¨B̀àˆ́U¡\Q¯ñ¥Y"ùú¤ú.„dç… ]O5忺^ƯXúPU<¦3̉²‚=hÔA³âSA§D‰XK‘NªY¨ºlœ#K„Lß…çEÂƠăsía¼IÙ[c¡đ¦¸£løƒ ê©»Ï寳ÛƯ1;%¼ưí?sZÊͳU»J†ú†/é`µ£;Đó°û₫z‡đ)̃U*Db鸀*HF0ºârg[g¾Ç3é^<Lzơ€cÏ#`<úŒRa‡R™«‚+6˜*•C©Ä¯:¿â+E½ÇØÔ{-̃-Ă}7jwñçÈ×ăˆ“³Ö´‰íiœ°¦¢áPë5ÇŸo‹ô)å>û¼@3g]B́]ÛÄSpD€×¡B’Ÿz’ä=€¥I”ïÓNNÆ ™Ñuü̉¢\+²•¦Cü‚°5KóÔa|óæ[MS©÷Bx\Ó©Ăt~HÓZÙ ånÑ|₫Tʾïà-Ṽ¨Zß₫`mpÉX`‡jl¾ $ă #ÁÂbÀs:û.KEưN-pRKÀÁk÷SzLg*…?BµøZ@, !zƯˆÚ1±†=»»Aœ;ºé‘Àc“ƠC‚ĂN0Û—#>?D2­éN2Ô½_ĐÔfÑ•¯n]HÅ^̣©º4>‡§Yú$-íªƯ­rN /ºîö¥†Ù8˜–Lñ‘¼9GèM,`h]••({@o=¿¢¢]y$5–Œ‹¸Y~¸›zº÷•ÿDé°ÔiM ÷´!ô];Ç÷öD.½Ÿè¡:Ư[„÷í ¿ú²Hç[A€ÔtfuU‡ÉŸ…å̉ÛjJâù3C¦¥ÜÎfÿ¢”¡ÔDsá´e%ê>2Èđxj½6w¡7'¹%œq̣öƯM§£xp§ÑWÓ½ª»đưÂ<̀§Ü Bonw+ίu\˜[V4CäB¿K^QËÜ„®–½ƠSm#Ùj­+:íCŸ¥ư’()yU1'$ug- 7Sn俢ók÷SÍăMOƠ ¦m^ Ç}–•l7(êĐ7©’ÚíZjDv®‚g1ụ̈'£üĬ µYÓÑî±Ă=ḈÓÜlˆĩ9§Úè9!á=Yº±“¾»È ¤5¨ooѨ 3ơ[L„DyÿgÂÎƠ¨«ÂnofÓ¯@¥{D}±A™§Än ¾\.¾u?ÖTF!ÙSèîƠÙï +ªøÆÉîɆÍî(t¡…R\Ù₫gĂ0XRµ8÷¯ök¤å¡ÜuÁ¾ÑÍj4>_hÏqàx^Ù~ +‚Ó,æúf¾TT±̃Œ¬.Ü׋O =œ’¿Û† -g;P™Ơ7Ç¢_ŸÖt|:£_J•G$lÆ­åÂ’~™+¼—‘Ü·,Đ ÙëÀSßó‚Ä<ÇœÅ₫un-^ùU–áe\%цæ ]‰ "! ï6Úå€QØÓJ́Ṇب̉yǽ9óI˜̉đ1éäăK½ tèbˆíQëđn¼N·O1º…ÜnË–‚₫û̃.t€ÅlÁ3´üÍBÉ$J̉\íw*JB3 ï>®m–h̃„†ø¯Ù{±V(}‡†ÊÓ]Œ•Á]öGúo ?¡µ˜–t†˜Å\´öœºµ B³ ¦1¾5×sf ›=&đ¯I°ÀHÜÿđơ¸[¯o¶XPI\¦À‰U,¸(_ñóíó¤],|zn8îpù­&ă‚¥°-K&—HÄîÉyÍĐJk·ŒWU¸™đüÙ{…í",êi£̃~¯:˜¿@‹g̃Ê+Ñ­GĐAî~¢̉¹ï¸#́Œ„ăÁẠ̊Ư(¡`tặÈyȸ¿6J{lÙÖ³*¹’åwñó)Xpb5{Oº5¾G²˜®Æ̉Ô HX}=ƒ¬9ÿ0M̃0›V¥ăTYm¼”9J“oD»ŒêK•ư5¾y ÂöÓj"ÎăçÙô“•*v ÔPG=2̉Ç•K­v´X)¡̀³Ù ư+̃z6ß3̃a%qăƠK& 7̀éŒó2ê/ đc̀Úá_ƒL_GN#³ V˜g7sÚºÅâ!ûS †“́¡z–ökwfb́X‰ßî.Ư{ö́çßnÄFá58ˆÔ_Ÿ%GÖœ7€…d¿QüâÍŸt¹åÊ)ç­̃ +|=”]?‚ó‚oêô8»<ç0]NzC)‰s˜|™V—#?øAS-Qñ'¡².²t± Ëå³¶*§¯å·àQ”¼Æ¯ÈQËxï˜ĐđÏ̃÷rP5w»™Ưu«û®†!¤ß¸ T«²2 ÀS½~b4ô1fÔ•«2Âå\ˆ%¹¤“ÅJk7ó¦bbÄưv†4‰­îåB÷Ú̉ÁF¡sÚ{û•‡×W 'Đó¤C¡©ü¶ê(ß6Å=2÷36•–¢ëgâcô{^›óGƯ,ÆF­r¡àœ™ôl"¸́đ¹S Ùễ\PƠ‚§÷C¯¨Ơda{/Å~WyÑi<ÉDŸjpÛ´fœ.Y¯N~ *‡£˜uîÖ 7RmIÆAAVñö«¹'Ss¢³TB䯨È­f”-ß ç¤ÑâvŸ=ô æ0½)éa´[ơ79ư†ñS61|¾H3$ÅÜxí‡O–oÁ‚¿@«g=O'ä\q(8ơ/Å“æ«Æ\j.ö‡¤ƒ=Sa&}8Äo,‹¨³Æúslp–FaöƒE¦q°gŒ€U'÷GˆxƠR‰%®@¶tEŸ”Ă0”è“=ó¥(ú=øéû$¯–²6Dµ̀^‹F´ZVkPNkqBä…Î0ë§×Óq°ídb +ù¶v«5~ ‚É«°5 ƒOs”í£4₫-a[É™?j ·³,³̉%Ekü₫øH›ø€/BÊ¥çˆͶäßóØ8Ÿ–Bw2›rVđ¼#§Ơl¨ăË@ß2´®0Ưz>–B¤̃B̃e#vđ3œ^Ḯ‰u¥ÙV‡"¿§§¦†V˜E¦&l2\óC»l˜Á´9ùïGL¶„ƒ±~}÷̀M¡Ïfà‚Ơđn›0K8;‡pHz“?teNf»w(Ü[jE÷nùă¥8Øh +̉wsZøĂ°÷ßL«, ụ̂ •oíătâ) A ˆ^j½æôăûởµF ¥K?̃Í0 ‡8í‡K/Î=œÈ„)}N[z©÷SdzbúÄÅ$Í<Fü²=.j ®,àwSѹ̀Ơ¸—°û‚&“PÀÁ_̃c̀‡¡€5MÎK/ƯÏ·1q9ió±0¢ÎL: +=ÖÜñèæeƠà>A¬ù'@©Ι# b_Q́[˜·, Qx؉HRB¨óƯ¥* ú|÷g*øü³o—Xjv€[7ÓñqÂD— IÄ:<._‡o û€¹wEK”;n7ÿS¾Lj±Yé¾Üó?ç dæ[₫cM·³ÊđơÈhxV>j4~Ô ·̃¸Ä8¬âËh× Z;dªL̀bW€P[sÅÉh–L» +ÉKwđóÜ‘ËÏ›Y™•!b Ó+~Œ-vM ;*ôBF¶,eI †IÁ†¦)œ*iè̀ƒk oÍ)˜rD˜+lHI^Û¹85¾‰W°<á=—kû.Îhf<¢Kƒ“X| çp2ª¥ná̉ºÀÁÑE¸ü”ê‘–Á̉R^à³ôúô0d½YBÊߠ儵œ‘J̀V'\m|`–o‘Àơ×A{) e „ÂæúA~V'zz³’)¾w¤([ŒiV7™ä²b[@æ¥(¤Ó£rlü™ù&IXöVAl¢L!†&¬̣<Éư•'rH¸ÊØ̀4iRt]bÉ‘Ä2ç₫}jt¬!ùèlŒV°/Üb8urÉØlÅ6e„ÑSŸd`B³œê‹l%Ă'(¡TOÚ +ưXÅ₫~”k>mÿ¶Åä¬ +endstream +endobj +718 0 obj << +/Type /FontDescriptor +/FontName /ZDVWXI+NimbusRomNo9L-Medi +/Flags 4 +/FontBBox [-168 -341 1000 960] +/Ascent 690 +/CapHeight 690 +/Descent -209 +/ItalicAngle 0 +/StemV 140 +/XHeight 461 +/CharSet (/C/D/E/F/H/I/L/N/O/R/S/T/V/a/b/c/colon/d/e/eight/f/five/four/g/h/i/l/m/n/nine/o/one/p/period/q/r/s/seven/six/t/three/two/u/underscore/v/w/x/y/zero) +/FontFile 717 0 R +>> endobj +719 0 obj << +/Length1 1630 +/Length2 18441 +/Length3 0 +/Length 19294 +/Filter /FlateDecode +>> +stream +xÚ¬·ctf]·&œTl[wXAÅfŶmë+¶m;©Ø¶m'Û¶óƠó¾}úô8_÷Ÿîóc±×Ä5qÍ5Ç̃äẠ̈J´Æ@CQ ­-#@ÖÂÆĐÙQh# 䔦U41sü•³Â’“ 9˜8Ym… œL¸j&Æa#€‘““– ´ss°03wPª(ªQÑĐüøOÉ?&C·ÿĐüơt´0³Pü}q1±ÚÙ˜Ø:ư…ø¿vT218™›L-¬MBṛ²bJ1Y€˜‰­‰ƒ5@̃ÙĐÚ madbëhB0:¬ÿ}m-₫)Í‘î/–€#Ààhgbdñ×ÍÄƠÈÄîƠ€‰ƒ…£ăßw€…#À̀ÁÀÖéoœ€ [#kgăø+7₫+!;à_ ›¿º¿`̣@G'G# ;'Àߨ̣¢ÿÎÓÉÜÀéŸØƠ é_Kc ‘ó?%ưK÷æ¯ÖÉÀÂÖàdâêôO,C€±…£µÛߨÁ́,₫•†³£…­Ùfđà`bfà`lmâèøæ/ö?ƯùÏ:ÿKơvvÖnỵ̈₫Ëêæ`áähbmJËÈô7¦‘Óߨf¶°ôÿ̀„­)ÀÈđo¹±³Ưè\L₫Ơ Êf†êoÆ@[k7€±‰),½,ĐéoHåÿËtÿ}$ÿ7PüßBđ ½ÿoä₫W₫—KüÿzŸÿ+´¨³µµ¬Íßø÷ü]2¶€¿{ øgÑX8üÿ| l,¬Ư₫O^ÿƠZÍäßé₫À$œ ₫¶EÀÖ́/5 t ÿZ8Z¸Ë[8™L ¬ÿö́_r[ck [“¿Ü₫«­ZF†ÿ¢S6·0²²ư‡Ö«LlÿkéúW₫ộ‚Jr4ÿ›û/Cù¿ƒà¤́f÷7·ÿQ Đø₫º¡wă–)¤Óµæ +¦MiWØ-ưi§…I2°±ƒ)>•¡ơ`)ó%Ï1ÅÉ}×ÙsåD¼NKj¨º†Û­¼UgU!B 0Q…€¹GÈĐûEIî“$AOΦ$""®*©^?œå<ºâ§IS9Y°÷É\¬ù3¡Ă½ÜeĂR×¥̀‹j×|³O`,IƯ›ó(Ǭ. *´ƒ£®<"óíf‘!°é÷Mœp 6‘ÑcägÏÎÂèL³÷±wbñK2íÅ÷•ă˜§+›V¼¸£ˆ×£NóhäúơôaÏÍc±2™‘sW2B ^sw} …ü*%̣e¶“lĐÎñM µœøËs)3µËuăbe•vS{jDé£ÖŒ»£%`̀{$ÚËr̃—{–̃S…§™Û ~H$s>8¯x^h #x­ Œ™–Jf!ĂÂcÇ̀d̉n9¢—Â0:‰â>}”–í¦¹̀¾œáïñ¿W¢_b²Ú’á“•¤93•ƒu˃‘̣·—†¤Tø*0œuỨœdÄâ¿̃Öß„L:;¨LÚé²WÿlŸ]7Ö4ÿø§”8ƒÔN‹›|ÛPf$y Z ¬“lwĐúï|de'Ñ…ûê)‡U2)MÇíø‰'˜‹Aă4s)Çï¶Ó´$~•VÖA€6ôÊù>̣µ8TiØi’“o™–́a †û"·‹)w†TZlºàúq£Qs!è$'¼Ô Fy6¼0Đ#+ß½–tĐé°eæB¨ªºEQă*Ø–¬ë`]ô|v©ÑA¯’̉ÓAr ²QÆ«{¢zĂ2j3sn0§4Đÿœœ@CWö䥋¢4`åü¸ƒAànă‡oÚ Y·1s«¨Í85÷̀‘#¬{½°™ +Ô§*́é(U‹›ƒgbLhF¥3ù~ØG,{‡åc׃È3FÈv€Bàt¾#}f»l3= Đ„ª!¯ *ÉÚG4®́7µO‡. +ºïÍ#|E“©;…ƒÆF=÷øUV´ñ¤±NA₫ư¦½Ú‹&1êÂZØ?¦»;5đçn…°â%aZf,®O«µ³KØï­ËRøq$“°¤oYĐ©đxŸ®/3n,Úe÷kŒ2}—²̀€K`t˜¦ƯĂ.ÚÇK±ƒ¤̃­§eä̀>¶Ö–0eá̃BA_Nv¹Oè(0V̉ W¬+ü×ôÇN XÑÉWˆ)VºÉO>tÇq¨å‹›và…¼¸÷]fÉxÚŸ÷™IÅÀ¬Ï₫¬ +“É^Gá÷C₫rŸ‚Ë/3}NeC‹©ø+¿óÂ`°Ç‡É̉ơΓyÇWû„´:‘x‡́g\æºD™ÀYV8ʃ́ÿª~M¶“§fç:ç̉zđ(>”V¢«ÍAó̀º~µL ù#áx|̉w‘–ñ¼¬hè1$>íl¸¸”ÙN†§w Xµ́ú+Áp6øÚb°íñf!´¬7Ç̣£Í‹>̃mßhuT‰Ṣ”s>3âH€M–Q×PZyÄ]¸|ô¶èÑÆefoL‹j ÷ÍíºÚ䉂7qÍ+¶ñú bÉ-ο™#¤êQ¢ùÀ¡ûˆíîÂs'¦Đ/çÊ…Å“QŸa¼œ^ç<ˆÿ)Lüưä!È5‡Ÿ µXÄJ±̉’•Ü4`´S}}w÷cÊỌ̈ĂŸçø“zseäjô|‡Ó¹ù§€We# :±=\Q«àH…€1‚âq!ơûđ<ëyZ'jzQÚŒ°ÿI\l$¨„¤-o'½.™(»`M(™{.c-P~5/x&ÛÏ ü6/í$dfg9~å·JÇ Ø“~ưz-êƠo÷¡£dé¥úÁ;̣ßÊëÑsv«ë­KÓ„‰Mü૯5Uш໥° û¡OƯ£ ‘ Íâợ,|+çz’̣€Øä{›̀…Üë5̉z!}|8ùí‡n®c=èÈèâ_8˜0)é¯8LÙ~‚ÖĐUøœÇ™¨Pz“FÚÁfUbÑ‚(‡¬Mz_ØäV•ÑŸm¤rl®+¶íƒä§W&)D™ ,߇Ă&Î5ñ &’}ÀZ!EæẓÍ54}Ê&´ÜOµÑ™¢á§ÅBìúÇßb£Ÿz} #égpZÖØE²7ú×x»¾Éˆw˜Å Ú˜8Sÿ>O’i°ø§ >íIƠ¥PÚ€TXX.U7Ơ¿ZfAZ|6ö⛌…¼̀ܨ{†úơ™eLf|Ï8)­YhÔf?…,¥¨îô2ß(z¾¦Êlª.J`Ư9IàUÂ^Ÿ[Ÿâÿh¯z­÷ô)́ «˜UÅ)ÛŸ·₫‹ Ü‘0ơª[ămỠ–a€}Ç”¶9°¸#ÿ53Ç•c–äXC·©HZEă(ăKSoâ¢CC•‚´øƒlọ̈Ç—ơ9©êÇ£0Çycî{²¯…;x]ư]Ÿ×ªUà]d–IØÄÙÀ'.5\éc˜†‡Kđ« ¼hVTJ_,zNÛ́orñƯ,™›œÖu¸iă&¸ ŸXŒ\ư¤o;₫§5G33¸„ŒH^Ôtæw7ê>b–KGAˆăíéºxɯ‰R[‘!5à~è²è”̣ kø1ÙĐ:Yç,¢ÍóÑNÀl†/ÆîÑq‡&̉,5ù^¼äDZ“ư(èÆ+̃aF/Ë(©'Ê_R­·ßŸ$D₫¯Çµ8èÓ³¬ªªÙ¡= +Eơå¡ó9º¶äq‹¬?“ôG¸˜ÁS¸ív +'qB9^û#µ˜ ½Wî¹$ëƯ›¶©ß"Ú¾ 3?ưfR» Äă­¿î{à q¼l^­kâ„ÿ(b[$ÊwÁºëMÑØ¾-’sö cåâÀ\£–‡Ơ–†É!VØu‚yDåúÜY»µR/=ñ,Ôơ'4—[¾wbÜÄ€Ú ö¡¯đA®à,ú ¦³Ö!q–‚Bz”tŸ¤›[s)ij5!ĐqÈ +Y&}j$J³•ư™°V#‹Ê~¿Øª†ÄM’~¢Ê¢>.KÓXdOôú#eAp[a€'bd*c¦5…™ÙÉ0Z¨²#'B` dpeùw¹¶Ạ̊| +ä2´]ü\fWJh·Ø`HUukô¢9ÙÂG̀¸t_Üà÷Î$k†tX4à ̀)¶ ÆL¶`ØÖ‚¨H”̣°ç6ÚL4Yt§Ÿ +cëääa„êD¾VÄCN†,ÔV„Œè‘ªŒ KXO ÙQưZlå¾pËŬ/!ÍqÙ™¯—̃E·ËÙzºîƒCù¨yP¤Ñ&›Vnÿ˜XQ̣T€»lÊâç¥đ̉Üèª-ŒÀH¹âc³œƯE˜¬7"óÿq3r­fÇ +ú3Ƹơ j_I­°Ÿm¬u ñÎ'µ0× MơöºdëöbW{í@k¢רxMê«x+DîôÛ8˜‰y9“Ñ*LœùßIWa×ăæÛBüŸuc,™–Ë»œ̃'b̃jhh/éR'₫ầJŸ Gg–̀ˆ¤¿¬Ñ8dxKí£‹0Y߆DiE l«2_¾H®Íơ(¼ öKŒ+̉ïæ˜@ç€_y?>ăÅØ?I7DÚ'åwønË"¨Ú²ÊÅ[]ùr>¯–~TèW‘̉¿r}1»‚øH`\µ'̉‚Ó)̉ë¹-Nđ#5jơ,sÛÖsn¾Œˆ‚Ñ‹aꌓüTøºvơû*‰H¾D-kpdk+DÆÄ$ÀtgnnøëöËăÄix¶aƠF̣̀fIWQÓg#‡¿Ÿ“[Ăo' ªs3%…ùÆ®G`OÅôq—½ª;ƠÖç®zGù4HäḈKW¥R~Ç£Y<ÎM,u;›̉¼jœîU>Tà;v¦•đ½À fK₫¼rØS@=jÛ”ƒû³±{D‡9?Ús”ˆôrÛVeWˆ§6;|LrƵZ&₫í%m™óq|[ ^óö4m‡{Çœ[Ư¯«pª×lÇÓ̀9«¹ ª«̀óÅ~¦„²i!kdå9,²O‚[Pˆ€zœØ]â`̉†ÿl@j7[›øeH øm7hÎ ÇXƯ<ÿ»Oñ¦øjÚ–=º~±u›7× YQ"Ơ)/¡ÏÄơ3¨èĂ÷±@ơG8₫™±;₫.pŸ‰n²~mÇÓCE„ hæ3‚ƒ¸›Fí"ßâ›ÁÁ猜_X|zA ë™›Âë ¸Û†ŒSÛ¡ÑP…ơ­FưÛoÄ6*+ko8EÉ;À<Ï®Ÿ)Î0,HÏ,§Äp×ó{2*.3œ¼ƠánH_̀ø¥û£›}aY’x4œÙ®M6̣tưÙ *¦AI^¢•çXRI9ä²k©ï–ưX±¿Î:¤Û*«%˜$Z;Ê;h}Æj‰ô‡jj±ÊÀ²IïE(eđÙYÎ3˜G&"…¬Ls©˜±ÊÚ _pxÚỔA¸U14`ª¾÷Ÿ ÷ö×ZÄĂ6'Ư”ê+# }B¾âv•\ÎAŸ¬+>2ñ\J%÷`No)KU‚œ—Ơ½„#TEúŹƯ÷2̉q¨’{é¥;C'U³ÄM˜/ÛS ¡#̉̉î9îƯFĐÉtä[’»+s3W¾µŸSíf̃²¸#‹Ûœ¹Ơ:,¨Ï\PØLíî0[¿ú̀ zÙ¢Îu.‰H{.¦v ¾₫Qư£¿ÿ­G`Nv|VÄ-9Ωä”bxdaoé ’ôO½nå¡êVŸ ®¿Í‚CyŸơ­Đp«´ ;8.9ºăóâ‘M„̃·¯…Ư=Ê0ßQ`ơâ€óªá4x®·B×PLÍÇx;8(ö~3¹ˆẹ’ơ|å-ơóV´ă/4OÆ œHđÄ噀EÄ„`ÔZŒâ:ëf$‡±‡ùñtâ+_hsđ‹Q»‹hæS‚kÂÎG±ëc¤AzÑDïJjWV9SG—­?êp Y¯Êüb×óRʃ+V¢T å3˜—"u0¿¢Æô˜"ÁûC]Ù|jöœ÷^í†~ÁøĂklÅ—EbRöñ¡ÏgăB3s$5$jj™Tä:Jƒ,"Yß{L9Bbiâ.́Ï–Ô¤:²Ü7Ï[1Ӭ΅hp~'Ô}ù»Rg½LÔ+hY±z¿Å®åàK…ÄJ5¾ỤMc¬Á,™đXz5çîEöJÚy„¨ NC*̃øîmú¾”^B‰í˜~Œ¯.*n°ç©©!ơk(Ëê,$AèăéѼ×g¾½ +¿¦‡Áưcµ|ïhp¥UÆ=.èµø?è́30ü*n=à_­ßGàk}™{…W©Ú…”äç„¢ÑC6[i e¿aĂ³1g¼jÁRƠƯ¤‰TÈåjù­Å o¾?ÿḥ–’ƒtF‘ qŸûד¸S× Eº Ù+]—[)¿\ç½tuÉ%̀d9À Dª±Y¼/»Ê¶V*˜Lø9Ü“ÂüYĂLÈÜæ[œ$©­×Ă&̀.¾ñÆưY‘ûƒ‡æ¬ÄzÅY®ṭÓÑ.Ëu¹B ˆ ²äËv¾0Ê® ö]¡ƯD¢ê9'rYµVN¿û£ËùtÔ$,duGÖ-ưÜ…^"!3đ›Z‡6ºk’!uF¯e¡%§s¾Å>£`«R”óèŒy[®[wRà8bÆ‹"íLÛ²Ѥ¸¼ˆ“z9ª]\Si½-Ëó\uy€¨n¥N FE¨ƒÚ¼÷¹˜rñêj[v‹H/(ISæv½.% O—ßăIÆŸDs˜GŸï&UÁ)j®LåáåƠ +–Ïc¥g¼Ç?Uͼ¹ơEö¿ë)`]|[4ZKæ#•Yµđ¬#™ŸM }û¾¹w¯aê­3 .N‰k×|kGiÅéü’`œÇ€W"AXÀUf¡)­%sß„à’?{Éø ́ËâVqM&³—ù@ĐÄgô… +1'ñà +Ô{–i8ĂÔZ3Đ#›ªù½ +w®Zƒgóz ~”+1T&(|duĂƒÂ §ç“¬Đ"¬Pk?ˆ×­2KX{ƒ¶Y³Ô^1̣+²°’7ùx£¯u›bÏ̉qïx9̣;¤Ùå!ÅA܉˜~rœzµ$Tb”ơú½ô+¼„Aê­.Î5¸/$^ë·Np³(T}¤Ó»–im›E,û$ARE÷E4µư5°†Æ–g%ÖÔ Y{^H̀ËKÎs÷`¤C·ÛZûœ6ûø·ÍHHÊD‰¯ît‰¾HZ#MÚ¡`äÎ\Äi¶~$—ʳT’te·L²”ëü¬è„¡7E =ÀVgC–½đÈ9Úö¸¤÷st£®Y#¡`ơ3(o‹4D,ƒÅØü|‡¡1‚)ĐâtEYjÏú*M>ºƒVö{C2‰N*>¥OiG·E'ФÊÔ£Ă[E×Đ!‘Ô­:‘|,¨c¬c‡ƒkc“QI2mu)¦ y½ó\Ñ¿Ư₫ú0Ü+C€×î¤#cÎ0÷Ó’Đ|YRùĂÍÁF ß₫MF}9ö'Åf™""%lsêYƠ±¼f&q@FÍZƯ½ƯnH}ËïÉO©Ôơ"‚'1L†e›{¾úg%-.9CΑĐmđ[Mù Ú>}ZQ 2ßi¡“¦̉9̀@0‹üÑ4~Û‘̣¶DpC^,Rb¨¦¾M‰ï2rÈL±àº}%B^×Ô»l{«BX΅D„´µAO(Âèö)’†ék¨̃?µ üÖ6ĂMó0Ëßy(C­«†Ú@Ï¢h:ˆwÊ&àóQ`Ñ 4;^îùÇ„±ŸOàXñ@•n’aÇ̉,w4¢ºdx̀Î_mîçH“íÛ&…P–2¢îƯŒÅ©MÇ`¹¥™å%^ZJ4c˜ƒÈ¤:ÖóŒĐ®Qw9F,\´́“ ™;¯Æ¥*½”̣>Æ₫ĵf+tȕÆë£Œ¾ø;Èi¹ơĐ¹çrăé̀>S^TÀ¥ª Ûˆê„—Ö1t ·¾»¯È KL/`­TƠsŸn¡a4Sưb°†F¾*‚ +”Z–•4ï<×âû–Pư˜zcVo₫a6ÂoRäI6Ñ̀´Üo8—rÊ“$,KñˆX>Ă//çÛ¿Æ.FS„a•·È—“G!v¡雪™KƠ­Ï¿«|ø„˜Q"§o±"úlÂƯïsÖ€Y‰¢ßi›Os_•4R,ƒ₫ö(̣×ç(ŸÅ ‘JB7{{§œv̀&_.ߣ*( 3 çUzÜ`"â{zs­L´(:­:ôĐªHr]Ù¥ÙÍă7 IœßGŒ¨*́·FÑ|ù,‚®!¶É_¤¼¥#zƠDÁE<¿8iÈçU+PÛ'ƠzƯl½¤oë1(ƒư~^ˆYÎú]¤âg¬ư3ÄnÊc2i'³Œj +“"¦‡ÅzWN\‡?zkG±Ê®rÈ_p«00v/•¼ÚQc`56BÅSíÚO7̃tCơ¦®@‡9ß#¯û¼íĂ(gÈÅ {^SèÜ"„˜<•ü´7•Aùn³ÜúîJ"‚¤úÚ‰@HỊ̂zs#ÔØË¹d/i(³Ü/eªmUÔ±ú̀TVûḌ˧¤ è#̣àYÈ6">Ó‡ÆơƠƠÅ󳋙’ŸŒ„̀8”ÎZbA¾7Ao›Ôajµ~‘iÅjå¤Xóéß­tß©Vq­A¾ÜˆÔNƠ)*Ùv#öXƒ*Ĩ”- Ñ ”̀#z¹·]]veO$ `äijƱ‡½¢ư)ø½ïøđÂÅñ¼óçu˜Ug5’¢ĂÔ[—…É|6Tœ£qå‡=.ó†‘G'Jñ¹xWË2D…Ä¿́2¶~ ̣kØ‘03=âỮ¿ÎÉ83ÇAVß³E½́ôVåTH̃G£j tFȺ}” +ạ₫Èå H„XÖư¼/µQâïXûhÁ^Ë=­y,wj®ûCÖ91Ÿ‡!‰Öv@ ̉KÀÜdµơ`º˜©FlºeXM†Û(?uê’G%×›`à<²Mq/̀ú|pvʶ&“C:@JÔCE»·‡÷H5˜r\$Ç™¹Vf—ÿÎô gy›|­ ¦ˆ²Ôȶ̉ê%g̀Ơ@È'›‹ö‰mVG0¼€µ¸Ä̀2àƠ–ª¬̣ĂH]Z*—ÊMĂ¢ÿ±jàv~ĨôkçÂ(Ú́J6Ưág¦NÜÙ¢ưÚæsPc6h@Î6HÊ-)•Ñ“ĐibŸÄ\$æØµ˜Ơ®í,_!û—ªdwtô~ÏÎï<¨̣°µ8:ôä¿"Óreưk»¢8́÷ÀÊÓ}É(fhÚNXÓ Ÿ¾˜ơçl6k7U›ñ¯́!ç¬,±‚Ơ-™̃èHt1(ܪ—ôeúÑ)¨¢t|v»R+ó"áựÑËÜ 0Qwm¶rĐƠ˲˜î¼Ü+@¹?Ü-­¯¥Ï0˜₫uö:-¥Ô{ ¬êÊ1²Ü±&YÁf® f™#{+™Æó ƒ86•xLR¦"w S¤äü‡̃‰#¦́ˆo‰í‚©˜”Óµ¾ jû“‚©9öû8ø¶ĐN¿Tƒç¨ơËÜU’‹ ƒ(¥S£`'åă–[dDW»ừÓÈ*¨¡Îfî<ˆBë·-ăѾ”°rD º*¿/’|thQPßÇZ9™<%°7 ÄÔ·ù¹ .ö˜x_śæP¥¹‰*|~ª±û´rˆwcƠơs£â(}² Ía¬­Æ½&K-±:*‡~c5AL¡.lÖY"C[ûề3‡±V7\R‚©uƯB« … +gǦÎ(*ZÈ×î¯̀|$ËƯ¹ùÉåÀ¾vLʰƠ2Ú«]O–È÷sI®±Évù¤××}ñPë‘Ù¡›.̣$*ç>.Eéz9s(¦ö÷¦÷³„ óC»s¼é»n7>~ØƠ78wÓ%ÊÎsĐ;s°÷áp¬/Üß(î»́:₫v·¯ ­?ơ%9‘½Ó›®ú¢ÛˆRomîë´ ï +=ØĂYĐ\Ë ÓËBQH ̣₫”é[|œÂŸ’µĂ¸L5oÔ7ø›È­ñ£C.×|&[§2#₫ÚˆQ>ĂÀ%q·´¿[đmĂ _¨”Â:›{z4ˆd×!́Ï‚ 6ö[&ư•Á³²BMÈëM„“µKM¯q½FZ©¯ÙgX#SÀzU8¦‡7̣-×KY 2ïu¾‘‰p'j.·vl₫—UE´ˆD„Kå³Áø̃P®å£oN•†º|ÙOJ4µ¡næ̃ÿ÷76¥Aq#¨Œ©îT¡ß%÷ü³½MMNFµ!Ư£t§@̀>½ÂuÇÏÍá…jÑåđÚÆËàg̃èa˜d|øÚµ₫½âøVà‰k ¾”üï|1›}ÿúR’ßk+³úv̀לJœ|.íR¹4o«Gœ§íwQ[Åîu<>˜°™Ó >Ö¢¹²ä] ßWhădYđe*hŒ9™Ñü]ï…1O *»ÂÎHRrɉ³à(Ô<<Í%Éú 5kå´Ÿx¾J¿EM00ísX „[µñH>̃ù`™TwSçho&^âÚđrgOÆc39iEO<öëøh!jƒ“̀¨¡ƒ\&åÓ‰₫@|ùjÊ€Èß¾V¥ÈÏl"CüXêQJ?(Å̉x{³o¿ô¤à +”nỊ̈~ö8Rƒ̣-+ÖÅ~ï5t=["It´lÄÜ ̣ Ë=g™ W‚’†ƯÚ w}é—ƠOêiZê~È`/n›åü úMßAmŸ„XE¸€9ÀbZ‰|*‰ Q ³–ؽ„k›ÊHɪéè<ˆÈ¡0§S†DÙgsí…•­bË3T¥zw|ëU–éLë ̉¶üL¥>…0:M|aà‡̣›qƯÎd;â[Ógˆ¸®2?Dµ½§ó̉Åödµ_Q SÅn#§ÇNØøâ¡]Át 4a_=¢8h=µØ$_p!‚êĐSñ_èçb}³([̀ØLƯz̉ÄHăq'óUŒE’pR₫¥ "`×´6qJ†e«2óKní'"ɲ̉ǫ +K 8Í-9€UÙå£+8k`3|ËfŒàd”¹›¹dËE~î„uMQ0=h2„Q¯¥”d(g¸ÙN1²Ă†ƯZTˆJÏ%SJQ1BÎÊŒ¼]‹O'Ü×¢c€z‹÷Á—©¥âµư*o8n8iÙù:|£6[BÚáBŒàZöO—¥’DcdZÔ’› *ס₫ô5ØqR^}̉’ !Nẽú¶sƒ¤Kr·Ëwïøo­r|Gê9GZJ³Éo.xØ…:ŒsZMÛÈDUĂRf›}î)¡±K™£Q3¨]ùpm§…Iñ¢PÙ½¿wÄ„³₫0ôj5eô§¾áèÛÊb̃4µûá>Ư ñ}ÓâV‡®“ ‚ƯG©¯˜ Wúhpe*åđ[›öE«ơæc‹óĐpw‹‘”Â…ç Ië®_ÓuÖ›+½zo¿ÿƠä‹DwªF2à‰£̣Zd»Gt7Kø%oĐjăYV!nMXâs1@8œR)¸vö ¿‹±.Ü­°émdHŸÏrDÈ-Äö×™_sĐ’„‡›ăă˜Öư ?‹̣|á$\ç5₫mƠ–)Ă“4>Iƒñ|‚ÙBiÛZ¹K·æ‰å¹¬è\"‹¡Yÿ[Ǩ(Lµr?–„í. Äăvè̉Üw kp̉ƒ¥u‹ùGj—ï«́wú“F‚’C^:§£;?|5¥»v9Ô@Lá₫2³̃0'K +ô„¢§´u¸¹ +°̣„7¯¦-«@a¾"œk%Bññls XT®6祱 3ˆ~0IDËozêféAD’“p¼Êoå̉̃ï,f+=)is«}̃5̃v€¡p?̉]Ôá[²8dËV ›Í„Yº<ñđitBØ)CØưêU ư—ZÍSmÇ©–y\—î¹ƯÁ¤-3¶_g6F·xB¯§é¤»ÄĂ ]µF₫( MùèN ‰&Ä,ʦơv˜N₫²å•óÁƯ¡;ϽœŸsùE/‚ûÈ¡YUŸé×Çy;Ư%S˜HÖs›[^́úôg$ç+ Î휮_ƒÔ´,WUº5[Ïá#l¸¡©o+äßd¥_ªố’åPpÁ¢Á#(b0+X5 ¤±4îÜQ5ùs]đÿˆVẨ‚¢7ÿÎ,­?†x`œ}LQ—ë +ƒM¨=,:Á0¯…ư}Ä“WĐ8¶œŒ‹A÷₫ëC}Û úٷ٥P‘¯Â¾º”ê¹Ưk¸â[Ó»Päe ÅÙ=ƒá"p·¤"<7e#¿†§§ÈCX¸µz%Èoh44~ HĐqw—ÙåJis¹È\Ơ:Dïwg©̀¶—Ù7›Ëˆ;­gL_I¯,%Ȇß@+´Ê¿Ÿôˆ4Ù€qµZæ²Ñ?™QqéO+†ÀíGÄ@ÔkÚ!Ÿăs+t)tZÜßh̉KÔˆ«äWKü¤ă~hj™ccJZ+«Ç~ƒƠ0_,2†ÁƠ<’àá̃î…BdæÓirˆ1öa|ˆQ÷˜UáåÓWç_®/7uçàƒ–%.}íf%Åö7OiÔ7‘’"öđ¦áÊÜP ñöÔ µ„ Çú³­ä,èl|@:_£g¾oEKƠ¢Îå 2G#`½ơÑ^øƠV^•,ç ±§€e-ªN•Ë́g÷ "p@̉ÍîâUŒ(Ù¹Yđ^ +¦4¢¼eÜ:Úñ_4pDă^Q»å2 ¯[ØÅµ¯)\8x 6›Zä*¹"JMüjl#?^ w>=ær Wöì9ÁV¤+C¯Û}f^wô˧ª2ºb³wæ«ô>º¨[ôµû Ơ…’¶´(ä\IàûºÍ°<Öé%v-5™‰SäƯL­”D–PƯ»y,*8™Ñ›Ç2²·w„Ræ7<̉‡A¾%µ2³<˜ ưV,½â$Ârßc=U!Up»¹F9ÿÈ%VíñnC~zRÏ;ÄMƒ&‰a lwœ42;‰ \®p–)ĂO)PÑ co(¿ê°n¨÷)D¥ïèR|ÅŒE}¾a¡\Lj×,ø…[fÍ{™̃aú¬t>Æ)£ta2́‚j¾Ë›`9k9Øj*«̣,Ư¶1Ö+Å¿|B×êáX 57¬úºÁA0¦Ûyøl.µI6Ïf.m½[ŒÙ -é¨}§™[ưĐ£1êHåz›ºÅÖVAw”›~V˜í̉Ø‹đ¹¢~Ơ¶·‡ô¹-œ¦> dƯ ûWö́96ŸQ̀±ÄßNŧ„Fă6f˜AªZÉ)W„¼/ư82'ơ%ƠO. ïêMŒ›ÆT¢*®Êâ¿Yt¯Ọ́"ƒ¡ă w ăî˹ơ-̣ :{zµ\€¿só¸M]DT(ĂÚ]j)Ơ]¿1ß÷–GŸÇíÁ‘Ưù¶P妹Jí 5ăånw® ƒxÙÖy,r~½mÔ/Øđ^Pˆ`Wû4Bæ¤"1/®LN YºØ$<ñ8Qd* Oĉ̉$e[§Tï̀¼(”²^‘„¢K¾ƒCK¨A:œưî´bÀ­Q 5₫ :m^ ©ÂbÄ~JÎÜW¼tÑ” DMyè¯]†QÅ”95ÿ=ÿöÔb<ÛWû BÖ³I? Q;׺@·Zz¬'±÷U³Ó¥Ù± +Gí^&Rw»Ñº͆JđÖ_”à6ƒ´G–Ôó{U„"Îî†ÍÂ%‡”nø•¨âÔ´÷&˜̀„°Óß_]4~’(?={÷>³Đz ëđÁÓM*Å̉\q¾#Ïs"'äºVϳf£Îrup¸²N”“»ú¶„…oNÅĐ:(´ ÇKè2´)Ç`I°0HóBË££h¯Å¢ÆaeøxèLJßN't›W™ïÏñÔWkÂeë +¥/GÛMÜÔ0ØÅË›vR´z$Å~ÔÚÁE¨©™GEHCÆÓ„ƒÝScØ[VT5¸ñ—qä å<û Ă’ rÜà̉µ¶¹ pT+ßëBoI ÂP4o¤ñWđa¾,jô ªXg~¼'â +¡4§›{A₫6 ¿Ă\RóÚÅ«+„qº̃äWÇ">n₫±ơ Wºdö¾ s ;û|¢€ ²‹ªKeb/;tKGC ̉l›©`Îơk7*!Ṽ_‚–;f5Ư›¡û&æÓßb^=¹€2§ reßí½F­â–a„I²E"2’ơ¶[çÓæ&e¥|Cơ—¢C+TRµ’Æ‘O¸M´ׇ̣̀ïÑ̀2KvFÄÆOøä ư3Ø®ûîˆa™Wª‘́¶2*´]Œ__ôkbâá]œAIhÂ$̃‚¿̀Ôj{Î₫„¬G¿®tWƯœºçzfD¹«Ư„Lƒ¦B’̉“-¥o"T +ÖµzœG{îâ“¿…L9–½m#”01›Ú5ÊC”K³˜\4UY ƳRצ‹È‹¶Ơ%ÎLƯ]oRŒu ̃wJî'yïÂïǃ”́ư¤nw:2z½ÏØÔ85œ!IâÏÿơû+¿eFœ7ë7Ă»R/“åAÏ(ØôØ‚ú?Æà®µÄ́S“uÉ®âÜẁÄḉ“Ö®\¯¡khñU¹Ë]ªgÿ¶—áß₫ƒ6÷%>do .:SF6ï,–̣́?Ô‰ç4iè‘£E¿øœçäÊ/ÖE{Ư´ñở3‘¿í÷c…ó’±úakQ6â <"Đ-Ÿ>“\à#vÆ-÷:›MRôÊ>_ư ¦±"gú¶'5Vœæ¡ëß|c¨V亲Ùéƒ|Uèüăí,?æ ^Û—0)$:UE„ªïX:o0lÅâí·N˜,̣̉¢V>s›÷]÷ÑĐô*#%?[…&rp°´L|F A·ă,c.®¦’ÉÜE₫̀ÈM!½0‰+å»K­‘*ƯP¿†Øéܬyă:Ú"›‚9¥ư¨Ú9Û !¥>ŒÍ¦¾¥#ZËĂZ̉ÀB”d»ŸPB̀vHÄ&°ËX@Hẩ<¥J ßÔ&‚Mñ’’ܶ­y<ûơ@ăˆs@†øp£è×üỷ̀F>⬠+MN3±"˜|4€cŹu.Íà²0‰ÍöÀ…>™Ï] i Ưâ¯á¾h¬Ï”(°íỪ"©È]œ¡jTœo‚‹BúđUơ¥§Ơ­đÀ¤´̀ơfù´#ôÈê’TA ÊÈî ÆOÙ\¢¤Ö§¢8<>¨ß°ó̃hÆ€ć3ơ~ßx¢IJnHœơ„¯³ ó;àÓĐÂåí8S¨=¦$E¯Í)5`Xha‘́@„6”̉«Ƥ%ư¸çoMATm2!ÓE;S¾dV¶ù1°î¾¿Đs>g"u«èÙXÈíIU +BK²&„₫hlRÈ|÷‰Çđ”j;¬Ư f9"øÎ•ÊM„Tí¡TZ*,c"p<ù¡‚oidŒÄ>5†×]c +q]bdSæ!C̀à%d"B’›É²äËú0Ë‚(séÑS×2³YP}ˆ€Ê;¹û¹©(T–|’ïS?¨5.jA_477æøđ`¾Í©y„¥;ÀÊB̉Bƒ×ÿ0,L6™kqÔCëYû´4%eĐ³è!lâ²FÍ꺼[:)„„ nï>³!_5,^¥ +’Ădy•-Ơ‚g0(6Øù;ìFˆRúÆ\Ză8 ‘*¨&ÀL».¹ßˆæ wYÜO Ç̃‰t²ĂÀØd +qKơèJÙºV]3m0Fƒc¤Á¼ß¸ÑúR%›2ŸH_RñĐ=ZÉŒD?~sä6V` ëNGw'"èC7WëppƒùçªĆÏÀ0;ÁÜ”ÍÅqÇï\÷¸îß_´€ñ4̣ûŸ”!èMP¤Îr&Ăù#çÖ«}¨íơåWÙdá4ŒVJ¸™ÙỤ̂µ±X×´Ø”Ă +¿‹¹ç¬¤Zá{¹]—'đ’Ă q!Q£?¥”wlJ‘ˆ'@ÍŸûœÁ×4^«`ë+W°U)L¡7ÆÁ˜51̃*¼I_€ºzA¼r„tÓâŸLœ¯Œ_Á¬#’ùsÓ€°Fp¤1a—Á ,·́朦éfŸ})*D-v |ǃ°à’« ~2‹D¨Œ—†A„©̃ª +âgèÎK/A뽫"B~ ƠŸ2 ¢¤íj[¼¿7…¸MçljƯ­˜áŸNïx‘*w…µk°¶/]U†FGá¹²@¨#DŒÖ•¢­áÉ­Ạ́̀´S´U;j&Ă*Ăgëk4³T|”N»ǽ…ư ÄV'‰ÄÉZ#V=ྰ4NF2&eœTUd Ó°̉–:W­S—¦C8êäơ,Å;‰Y?ºü&Ñiú¨ûU,‹pÇŸă2欬ænÆ­ÏQ¬²göF†ÍÔ)èi^ă¹'l—Ù£pYŸ,¸`ÙJó̀°o.DŒç]éÚÍ<[Ù5"ÀbOØt2÷D!goQaÈ–ùs1Ç”ü{ẹN½%M8ZrºØÏ¥—)Ñđç/\äé‰O¯/cƠ<}) ¹ư~í=gnùÄc̉‹-ØNˆOTu¾x ƯfgŸ¹̣+Ä}¢.¦ƠĂQD̀ .T;YBÓ¾£×Vÿ̀X÷UņyÓ{‰ÿftă‚ă°¼.ÈÚ^@Ó-qøçy|F̉êo>~5ËéËWTf6~ÑföåW¥ØI¬÷@P]M¥Ù̃̃}`À/Cp8ˬGơ³Èđ~c½èPÈôüËœ0×ơ åËe…¹÷fq{¿JR΀¸=¯>å^FÀx(N¬k%è*„³眮–XtüN>W3‘J_+Ur,~€ëî@m +AOyôV”k£\åF¿~©=¥&Ä^€ )ŒüƯÖ%çsơ59jg:É‹û+‡K5Á‰”2硳MÚM¨̉rV€øQÄÁ̀Ưz̃éÛa„¥¨a₫́ÙF|sng +d̉èưqj¹í́ƠG ×´́<óRDLŒuđ–ܶD;]ơKs”éOçăGƒă –¤2̃ARÓ<ÆeBa.…¿ßúÉÈ̃Æ~™0?4u¥K¼ÅØ­rH²ÊDĂ¾¼””}3-BđeÛø(‡ 8éàhÁ!·­'ˆa™ÑÎ\yÔ[̃ÖK¢‹^×XY%¦WªGmUçùI®Té)Y¬ßÑ%áƒ*4À%âPêöhn öµ­zç—¦¬£QÍïK9L…º€JV•– {8ËTÛl¥”'|`ç̀<â¢]đ.ú§)•¶„~Ürgøx|]§Yb*Ø´I—¬w/(”ϼ‚iÂw/ô‰=Í<à5/*ß́ơ•tGÓV«u“J¡LH#½èƒ³è"z\©•êˆTHø»ªSë7ƒâaù©™Æƒ(kV³·Ÿv÷¯E`x6~Ă … ª̉›„Î WỆzÖîÖt­å4 +µ̉a„?¡äK`sxÂØĺ$ÖEäߘ7Aèyrñ€J?Â,)oö*«"ÓĂƯÔ\p'Ơ/<¿"₫nÆt0mØX«ñ,Dïÿ<×€‚6s¸w¹_”™À}än뼟ûy+€0vsl“½́Gâ.rÇ„Èđ-¢9Úo|­|ÖïÍxåºùÉQT¸Û½âö\}a1`³‡º/£0*’́êú£À¥K´ù„~²•́x»~‘¼Æ±LvÅiÉ]Ă’Íq„¸ÉăÜÛX¼íÄZhÖĂ,‹‘»  Ă!^Ù°)‚́~E'¯.Wbû8±c….wK’¦¨4Ïol½ø‰“×x³́‹¨„)tùV“0“{–R4H¶it5®o)Äư|®¶q’ÔùËèùîg¯Ưb¶MQ=ÓD Ÿ>|Cß`êä0‹;¸ûăÿY +¦ớ‰A;"Œ§¡ÔÓªC%DûsiQ‰î›Öÿ_3ÎÙvÓÿÊÁ²ĐSg‰Å‰›c_Nj¥{đüv¼Ô •Ñ yY°l¼,ÎvA»±&¾€ïÛ̓k׈ÇY~Z¸]£ZJŸ€÷>·\ócT’“VḥB© +ỏ':ë¨!uß³Qœ~>L|%ÖX¤‹"Œöàü7Kaµƒ$9y5(ø—軀@9[T²oê]\œ¾3ÓmÔ§›¥h~$ ¯=pe°M­̀z”ă=‘Rb°üc¥©«bIלh'EˆKüxDg7—Ü"œüTî€Àæ8t#…‚æëåSH×B;„…ˆƒ­Z¸©Ê‚˜A₫wùUÖoƒ‹>íà¡C0ˆàج2cÚÀí³¼Ñ¬|ŒĐ¼̣§w ”Ù Y¦ ¤Oxu3qñ5¤LØ£[₫I‘kJR•Í™ y,«”Á'}A’âQÑø^#›6›[ÎùôÖ¦s"³6a.?vá|M²è;L»¨ÜW±ơ;ûê0Ÿ gv»<Ás_à»VBCàhéO½›°Î4ĐÀ]¸£#W" ©3jRÏ^´¹i™¼Đ)v×ñÔÊlûA#ÂZÛiP­¯`Æ*ä„_o*[l,´TkÇ…J̃Óºäç¥EnM8ÅezîÖ ÁÈ*d́eƯ7PÍMcÇ]’Y¾ÖQ” ú–Ac ”H +FnǤîă0rûß{'ß›6r”‚üª#Íga +…iWÄó¾3 g€ÿ Á<ô‰öFZúŸ8Đ2:đel‚,$cǹ3îD¹„̃©âèÙq"é+Oa~ÙÙÀĐp¤ưbp°ßÛ¥g°¡́Yz\°Yÿ¢âj»̀ÁÈ?̉Å„ö”³°—f–8A…A>ë w†¶*Đº½¹³?a\ÁKí<:ܪ /`8”øjBUS1:ÿht@=]0ZÛu>¬ŸĐ‘ᆵ ¢ªs$9_Ñqù³¸Æ€á”‰Gµ%ªÑøÑT—±¸ +çè´ç&S%“̃ß’ö±â[ĂXúƠ«H*̀ö=.¾À¶ĐJ„¿"tÛÿ +P¥—néƒm`rM-\*Ø}(̃×Äùù̃¥ë<Đ?(§×²÷/mú •ï%–}dZ­‘¨rÍá]DXJwxí{ºÎoEex̣O¦ú½@®÷儨oñô»D9—aÅiÂÁúZ|>Æ2©‹ÄO4sôe ¯“Y9ù7-ve¢qö௾z&´̣” ÅU–¯«…8DœÏ3¬2;WK1!ăc½50èIŒÑæEí¢Dđ$K8₫ë÷̃Ø|øßë +© +´›̀èÜ?b ÷+~a æ$ +n"‚"Rô{í"”ơ¤ôØHa^!ö§[LĂ” ß'“é—„'ªùă²d̃°ñ2¹Â_̀¤«È{€,̀½ÿĐôó ± G `‚-ŒSïî́r )FJw­ĂG e´Y‹ô.̉ÄZx7YĐ¹²Üt⸡̀àWGAbѪVdĂŸcóưz̃×#~RÀ(S0ù¬„s¼såΆdnhÅ8 èƯfi bj„đjƒÖB®+ 5Í|K W™ËS§j‘†¹«¾åœZ뢟Œ~„Vøƒ²Ú æ!¯˜ZSiîçÚ³áơL§tb&G®¥†œ¯l¶2•ŸIwxnä% +ù$1Dßî<¿ƠÛ-F/Ë¿W·’Íă,a¡•½~û_s\ä´6r­Ù×Z‡«ç­’©üPù=₫uDI`³]åă8ÍL¾Ö™¹®'µ+Ñ ëGà+MpŒ₫Jp¿<–°gÓ“ă/EŸrjz €&dí]̉¥ƒ×²*¯G×¾ÆeQÖ7Tfúr¶soDpÙ^)\¿ÛĐϱŒl“Α0,vbYTÔ !ç̀‘™YbÈØÚi‹0µ?—ø YßaÆß-/&ÍÿD(Ù™xWö¼jJØ’nBđtJ°#nt¼w«bƼ}YŒSĐ{°mUº‚U}†Ç%8¬­æíIđUĂªú7‹₫{âV‚B"ùçÖô2`©fzù¨-¿Jcx`=™£ỗ¥•`LrnN 4´äa$g̀ÿ°|†oƯ%»Íic°A=̣yéơñ_æHëI"Ƹç/đ_Û¬Hµ%|̀À>5YƠVMs?ñ(‚Å@kŸŒj¬¡ ©h^O±̀§ăp×GƒÛ&Ô¸¼Dc°ªÅï~̀§D¥4( ¡ !î…‘†Û_fM®ÿơç’Mv/K¸z, ¥ÂG‚kÈ”\̃ĐJbͦï\Ѽ‘^p€Ñ@*§e†Ṛ¡3́«(J’”y¬Ve³Bßî°ös©!“: ˜Îđ¯́»¾«­Û àơe.ü0é€]? 9¬’₫Ê×T³øơ܈Öv‚°´\®l›#ú©Z.lÎ1­6Î_½ª̉ ƒEX¢½”TU°̃î¤r&¯­Ió›ÚF)Æú¾¼iŸ£Å,3±±Æ….t +ư¥ Ö̀Ä ïœ uåĐóưÂîàßL­6†f 8¦v*1ÑNđ<Ú8+{Á€·U¬%胩ĂZF!K6O0?\§Íư,G̀ûÖU臑\ơ¹ÁgñÆ?=vy&‘~°¬œ{®‘åO1.—ø,€/-ʺh²¶Ôí> endobj +721 0 obj << +/Length1 1647 +/Length2 11596 +/Length3 0 +/Length 12440 +/Filter /FlateDecode +>> +stream +xÚ­veX]Û’-îîÎÆƯ]‚Kpw‚o\6îî.Á ÁƯ%hpwww‚CĐ`snß¾ưƯ÷úO¿₫±Ö·fY£ªæ¨Y{S‘)«1‰9˜¥́]˜Ø˜YùVv&®Îªv|̣Lª@ Wc[ÀÆ…@E%î4v±r°—0ṿ´€f  )€ÀÆÇLJ@wy:YYXºh5Tµèÿeùk ÀÄóŸÈ‡§³•…=€úăĂ hë²Ú»|PüƠ€@€‹%`ne ˆ+)ëÈ(Jh¥5̉@{ ÓGÊ®&¶V¦y+S ½3`îà°ưÇ`ê`ofơWiÎ̀\¢Îc€3hjơáô0‚₫‚  “•³óÇ7ÀÊ`ádlị̈q.+{S[W³¿ø°›;üÈÉác‡ƯöA¦́à́âlêdr|DU–úG.–Æ.Åv¶ú€æ;ÍL]ÿ*éóƒæu1¶²w¸=\₫e˜Y9ƒl=?bœ¬₫NĂƠÙỄâ_0œ€ÆNf¶@gçî¿Nç_u₫KơÆ ­çß̃ïúϬ\œ¶æ̀ĺ1M]>b[XÙ#°üƠ/2öæ6ÖØÍ\AÿÄÜ€Ní_=C÷‘„±™ƒ½­'À hÀ¢èạ̀@û?S™ùOäÿ‰ÿW₫_‘÷ÿOÜ×è¿\âÿßûüïÔR®¶¶Æv đ9ø4Æö€Yü5ll +ÓÿËƠØÎÊÖó¿s₫÷ƯZÀdưœÿÿ#„¨½Å‡BLl\̀\ÿ0[9KYyÍ”­\L-æÆ¶‡÷·]Ẵ èdkeüùïóưpbeư7LỬÊÔÆ₫/5¸₫íÍ₫½†Ư₫®€ERRZJ]á¿™¶oV₫è +uOđ‘´̀₫sñ•˜˜ƒÀ›‰›ÀÄÎĂúq?®#;§ïÿ#́ßDlÿZ+»8YyôX™YYÙï>ÿZ}ù7I{S³¿úHÍÅØ̃́£ơ₫Óđlêêäô¡øßÓà£̣®ÿ¾@ ĐaeÑÁT Ä:=+Ă¥7gp\B¯·› r0T̉ ^˜PíĐ埱ÍWaôRÊÜ8ÉÿÖê¹pzƯ—¥?îÆ±¥éJ^äùRĐơä£oP·ó0±” gœjÅx_ÎËoAér³j́Œ«¨¿ÀO¶s8Á]>ĐP¸å`Q̃ƒPüLÓêă±¢5‚aÔœœR=~¸§é躆îÙ'døO%à…LàøPXW£Â;SA₫GÅä\æ ×*IgOzÉSë9m©Aæ6ÙỌ̈IA»€œü₫ÀWH +ï<ø7…x°º‹zîÊRïœûÓĂÖäb„»EŸq±Mw:}NûÆA†u’æmß̣Ú­fN«Äß”pçf¬­.¸–ü7^QØöÂö̃öJ̀îÊ‚ËLk·^‚S·ĂÚƠ^—ç¶dùÁbâ6)BRÊ?< ̣Ÿ"Oí̉­ ‹I ¢SwÚ‡Y›%¬°Qk¤—$¿̀ÀàdĂœË”95.]¸Ṕ„¢óBOuĂ€æ5Dû¹ÈZ_Å$z^¡é/áó¡a‡éÏ &çÙQđgB儤¬”5€^aêü“uM*ÇƠ†Dâ€:Áwi˜!(›vz0̀íä«^O)m^ÇY§.%ÀŸăl—/Gí¥¡ăđmNÛw¬ç3ar‚`~+`´b\<, Œ]’P‚çG ½Ø'Œ p!RDNO‹p[ËjyQØË¨™kP¢ ¤¼9Ÿlv¡åó :ÛÇiZO}îsƠÊRwW²"ÎYá±äRư³^~ÊwöHqgÁ.†=˜a½gÙÔ ±Ä!z”êgpTBÊi Ă–;#MâÇv¯’·™f$’H11,£œMÑL,Ú¤=TW¥YÎɆLz¨n› +¯}”øÍhN·>"Wøđ&uƠ~DCr¦_¹5øK©ï<º$$WƠç„£ư·¡/Ơ;QgÚ_²nñ7 + /Iªƒ"Ùđ̉½O¾sêÓ ‰æ|Vk„æY&ßSº̃î ÅŸ%¹‡MÇĐ9ÎAÉ_‚[’âƠ.W tÍ́ϾƯج‡Ï÷x3ê ‚«̀½µ¦̀„nRƯê"´°Ÿè7m@ƒWÀ µÓÜ`—×v´yƒÿlom4tú̀Çߘ*Đª‹±¡²lëX;c£’«ë¿±‡Öœkg|ï ‘H{óô.Tö}שּׁº•!x\°o•…Y4ÇätS29Å ÉÅàŒ80NÙts¤—ù\ựƒ…¥¥F․Ù&Ú’.¿l›̉Æ!eU„\ë ï*ß₫“̉F@µ¥m˜^}fCëí¢»#Q ׉7E+¥åÇ•ÑƯ=Ä’3.¢ß½³‡º›9˜GA77c8™œ­*ổïđ?Ä1“ª,±Uq±Ly7?Éó‚1í’ZĐ—œ]»ùyÈ‚¸„T²¸÷ÆĐ7îM.†·Ec(¿P ™±é$µÖ{Ẻ̀ÁÊ.ccÑD ˜Q”‘»T^”Ïg¢4—K Ă$=!$Yɤ[… ¥PIfxèC̣ª¥»àsÏü™7$đ&$ú^JƯ¸̃“®±}Ë|†{€óÎ/XÖ嵤 *×Tqe#Α¡…øƒ^çîî8 ¢€â‡̃RÆŸto›{_uúTÚ"L­·`˜Ó¶¢P ́͸e¿I‘F> 6|ÛD)¬¼Ăy ¯Ă?†̣ÏBD…”„ơ,Ư­>ï0ĂạMtˆß­SŒrNªKBTŒüb‰Hèư _L?µZYH|P9ª—̉fœ’XXˆ4ƒ̀ôĐ B’Tö¼Ænú6%ù¥¯QÀ|ïÀ"ÇôÏŸÓ‚Ï´]TŒ2ˤ(…W<{ ­DinÆZn<¼Äçó5áǤ?Z† 0­Éă®º[@lÏdj›‹­óz‡q?ªDråÊœÎ́†Fö«NưD  Ñ~ÇJrë‰Qău_<|Â~Œs7bƯ’¸ÙµRchwJNXgAdÁ₫&ôW-M4¾¬LÜU[À Ë{™JÛ̃)²µ™y‰‡ơÙ†çR•ˆ†O¸¬ó¯Uöˆ·ä…­%48ïymA¥q@T¤ax×sTơåÿŸzÂ1.'&ñû&yCœ$/}ÿÄq­´ơ’‡®i‡Áx5ï-@õ߫HI¿'œă÷÷²6 ·Å—µ:ˆQPÖÏỴ̈₫gÏo3ƒ (È”LË-bÂd +a`‹cÿ¸Ă’7\‰Ö¸̉%1í§¤>H|€é +œµ|HBÀçưJÍ»‰ +#îƠùH$ËÈöÇ_)2¯—éH²‹-ơZùq¨JÜè80c”¦'8jiKâ8ƯƠ‘,Ê~¾,bn;Öi¤¾( ¾oçñ0ƯxƠŦi‡ "¿°—­t™̉¨Úƒåpúè‡ a˜C¼ú©Áí ©…ÁŸé¹{©…˜~ÿi¤cJÏJçA»ùs¨H†,Q̉¡r4›L[=~Ơ‚ :É@7̉÷Ă£É̉]—èå¨ÈÉơUkͪGÄ:ßÈưè_àÁÜcEÉæ!„îBT½­̉,¨[=q_ïuVÆû÷[+%荒YÆÍVawÚ¼Đa¯Êṃ—Å’Wv Ü +©<Å€WC·5œĂe4,qÜ8_¡î–“Ä@À/yMÙw§]jO¼“ß?Ăá³›¹ûØD-ªß;³ïxùǘMZ +›vSC)4Ú³'§œÆ‘ŒvÑv+zÓÁ¨g̉‡˜Ùfæ†<-¾IÎQĐ¿k·kFØ¥’é~ä%'́PÔcî‹o#´3$âBác­ªV•iXƯ%¤Qx̃®ÆÑD|×ôÂr— „tÂëï0Œ–AofÎơ4ÈûÎ8“9+«í5̣U^,¼Î_³Æl*°\`E˜p;Ǿ€ w-ñÛÉĐVØvéĂf°‡MØØÜÅîưxbm ưîh£Ơ){#ó‚NíŒ'»¼tçöª°Í,Mk4 ¸“~ÜFcp¥R[^~¢̀18¹1cu¬È;ss}wi[u#ƠÓ'́Àd?X/‘Ô†¶̣ƯƠâ…ÍÓR»S±’3î ‘°ßp +BQû̀‘ +₫§<)¢aw±È¼́^ ;FIG9*°)˜đÉ2nÉëyubKÊo—6åĸ;„Q™sY<´9)Dâ}íc—Édgïœêđ‹î¾ä©”Bø˜³è„=©çœn´SΧR]’Ñÿ>ß­-¯H@èXÔGxYVNïàÈ;ṂäZ“sü¥i„Çûæ„„²éđ%…ræ8öA'3Í`ƒ£á qé&¢Ö8†t^DtÎ×¶o &•î‰äF/‰SË+’1%GP•²Æ̀Áê}éä0âƠ<^x>9ï •ázÑ<ÄçÑ“¢€s )[0¼§H”Í̃̃»ăí:zƒTáÉ»B6'\ÔƠ6m̃ºœÎÜ&c$jO»-Đ&à!Qnd|éªQÜZ§÷Ê#S Ä$ø¤wa€»Ă¡½›½lz”*(P7"øMó=‡‡(èM(̀<ߥ9غ Ûj­êÎÖ¹í É¾ ;F‡\ß´Öy“\…xÀ ZiÉY^ëúÓWplcܨ¸ô¦k 1ù¨‹ƯV=jÛ–&QèÓÍŸ&Ö¡<u `ÙeÇŒÙ>iÉ-æÀöËZÓ¾Ơ?b¢f«̃PÔ"V/å » Nü†í@D̀sm̉óóLzø§̀Ơ4Æ)î̃9Ă‘l&²Î÷ƒŸ]8Ṇ̃“¢Vöø«ăÁï›~J»¦BŸzÂ*răơNÔúhª}ÀÁÁ²7Å›Á“}fˆä6{#ÏFؤ:z­~0¤MÂïàÅKªßÅ̉p=ïMl2-̉çö¿DàPÊök  WŸnÆâĐ.€¶îó¼*xµ/`F¼ûº%ôÙl̀-˜ïLd„&ÔÅ"Acƒ½ è"̃¶îĂÇo»£÷¿u%#[cqùB°Íe§x´)Q¶“l¨NMđÈ)̀%"›>¦|y{÷úQ}‰„óuöüL“V¦¬̣–¶¸^„ µ[,úŸăMæm̃(¢ê]¥ot¦´-s©ưa+ç¼Ơå‹`¨âçöăælâ4«‡×e½N–¤É¢QîLÛt­<++bư£ÎBî׸­†Â_²¸0ä+~o‹Ë@u3›…̀OWØBHö&y&ƠúïH…nü57VdÔVƠƒYÀQß\°ŸƯ´2 ¾‚˜ñ&”/wηĐe ± ± +f]Üym̀‰±Ư^G j^†ˆ‡–ñụ̂! +\Ơz¯ S„ê£/©Ë:ơm2sg~]Dóx (rĐÆÿVêúÉû»f1Ä̀“Oµ…®­dŒPyOa3§Bº<=¦×<Ù}îÍæn¾™‰“h£ÉMG-”6²I‚§p2AÿÎzªđ”TÑççe;øKđj̃G¶ÚOÎP¢åÛB̉“v滩Å1tZÊ] 'uÀ)¸åveÇwÄÂWÁÚ‰ù- –é7„ €l{j£Û€~¦_Á]5“‡ê‚‡_ú́¥æh!ỗûFfG‘Ö+M#F)ß@₫Ú:=̀¹¶a¬̀ {-iÙËóg%˜|BzP¥Ë¶öT•û°éçP=×å×&™ØăZíµ3ªTGÏTS,Iöđ ÎYNL’bvăƯ"µÂ xédï[æÇú@a¡@Ö=>ă7`C²uŒ6²đøïëê½Ï¤¦j§Ư4sIzsL‘d™~:”Ơ@·%/.59Ós9Ë`: Q4ä%!WêüƯ’ɽ —ßP\!“D°è;A‹Êˆ +2x«¹&̃ E,;{&!?&¿ !3y$đ{V́₫±T€øL̀Y¯uoÍÀ8¡ŸĂ÷̣"jØ@aÖ­!|>y/%˜ùê‚̣WïoycöHÊϦ’s9—(uÈ™=>··gKÓ¯vĂĐÓĐ¯S̃H8èí”ôú°̃a¤r$O5zTƒ.ö]éö8ÿ_­ /ñäåđDđ­‡#̃âH¢È8Éé­9§ÀưæäTđ2Ơ$iI™3.‘¨’/E§v ?à<÷›q’”¶fP̃«ñŸÈ9'!Ó¬geGøíH›3åëÅ~ä;} +¹t;3¨Ó•o÷—W÷jט§$«7án1à?O`Ă_W£&f,÷QóĂÁÆlÊh¾l¢jÍÏQ¦aH“„Çï»(— ê«ÉŸoߟ>L&đ+‚„U‹`Êä`D0§¿Êb2¼`£IÀ́‰ê™k;s%u8/êr(؇½`RGƒàGA₫QꬓXƠZ"¨É÷:q́¨,M”j‚ö€~$]ÏhàÜíäù4“‚Jz\êN¥æ lĂm ÓÁ=!ÿî˜ÄÉŸ²°Íæ¿>éSÂÇöô<Ó²Œ+7Ÿ„°pk›º¡î”÷¡JăJÁÏÚ¶¶Y:Új^Œˆ] µkaGAy­º;iec„âvê&¬æÇM©àâúÉl* v°¦É¯]gÿDµu<7“øOĂ’î™Ö +–h ßG\N Ù1Pkơ|Ú¦«sÀ9MÿđÙ́mÊá…&™Ü`9²€áî£å[̀S₫ª$1œâ6ªà₫úº·Ä]'ÙU\¾?âàNº7çsó́ăú…PˆF ‡¯₫ŒñwC@ó}øúHË­îg»Ơúư;À0W9Qú ‡±ÉbL@ăœNáÔVïFœ?r¯üûVo_ëÜú©ÈèéXí(úô•Ú³đǿ1Ơ…u $´Öă%¬—âëÏá¥ưnØĂºÓ́·Nº¯Æ.çÇvë_BÙÙuûcˆO`́’qFüưаKlVZ;NëÉ‘3IéOkv¯ËƠé¡ ëYjâH€̣pŸ†.ĐŒ^œü`Ë­L äIú́r„¤Ơq±Tˆ†¥¦¡#Ưm°ZviûÙ‹–ô]æë8èk—Æå{Èùe“ çm +Ê_ùz7ëœ;.AđÙ]&¤vñâ%ÔJa-ëâÇ('O¿qʸ ²ưOÔÉé6°ég¾±:âQ1ÛS†0V£{±ơ‹;B!HÙS'± +åMŸL­ºô¤äÁpu³ºü <¼X“ú{³±dJ¯lpɵJÁį\„Đ'9ÿÉå€;k2…Î%!ª,ôh;/e”Ö–^ºb=^¨ÚQÑ:ÄIƯM°UKˆ¯`»eàṣQ¦gb»Æ4”Ư¬3—HZ¶ñ:ù₫·óƯ~NÜó(̣Ù*ăôBçë§“¸Ñâ“j˜ËCwOfðm³]*§b§œDƠûµT‹¬µ>x}÷M˺ˆB NóÍp=ö“0Z¡ËExëưChY¬Iđƒ¿ưŒ"ø2ÿÚ-H‚h$— #(øjV«UgV<ˆËŒM;.†àĐ”ä +‹­À“c%=¨ïTȨu娬Ø&cD=å đÚ\ܪúIÔL ­é p–Äh4ç¡Lzó–Çù`tudá ×̃F¤iŒỔ^Ñ4 h fSFÆ`»\>ơ%¤¬ÚÜQ%gumÚ'Œ₫–dÊU&9%ä\H.ù6u؃Phå9Óäy¾í4‰»ÇƯER“ÑØL])‚²{‹8 ɇồj́–¹0u[₫”ŒQqÁÓ)Q¾/M¦dĐ‚\»9 Ä HkÂ-ĂKŸqÈnh*‰Æ=Ôóu8 +J₫·đ̃ÛŸo ¼èªÎâSĂÙËÓV*É+5{æM¿A‹ZƯ¥’’N.̣Ư!é•´èMk­À>dL!V(Ö«](¹‡öîóÔÛ-Ø'_º4–ÍsV!“½oÄ®=›=‡¶Ÿ’`ÎM¾²TÚRQ§á~e·€å̉P*>½Û§”®y–qPq¬…Ê%¡‡/ +»¸Ÿ‘¥í#UEº>-üù¥r¿ª7đV˜Ă(3À{ +Ư3ÿđs3€nxs#₫Û±q¾'%yTä¶™~?.Å’\yªÛEk›ÈÀlUưS“Ø ˜Ó1Ø}f†‘¾>3vlåü +˜âoa^•lü/Z₫z—pu“£Ùœ~PP¤QM +º/N(̃=¬¼À|L2œ·ù™ø÷³ÁgÖH¼îØ«“¢¥írÂơOdc“̀‘„ẹx|¦åKVÏkr!Ef¤qû)mÔ)»ăÂFàÇqŸl]o¿TCªÅ§ °3œvëHc̀I?Ï—âP;e%(ñ-R¾Lø§”›‹8 Û€H{ñ ĂcL˜̣V#§râđ̃Ø(邦“Ÿ¹á%´Gu¢UêvONô±§€®́·¨è×­+mK }8 +†>§|;C̣}UC›¥ẃôQdéÈê•y2ÀüúT´P¯;jX>Íß7³gÔ?Ifâ)×Ă²­pưóÜd!÷ç˜4*nR›®|{—àØ¢JNRn±ˆ»CsÁPÇyƒD@˜Wé:ßo[̉¥÷²̃7û°í«·g9Ö¼ÑF¶Ă|n»Y^M¨¨Ú”{ƒ¼©U4·l<¾ONâ«â¹¬ÅƯ³W!̃:ô~ºI£:·Íé€LW¼np²ˆG*úæ:^lRqdä’#ị¹Í*w±¿¾X¥KO“ ̣ÑĐQ(æ"h̃fñ–è=\Of„5µ!KÁïøÎ 8HVùNy‡!ߥëDÖ`¸ÉcC—p‡ ¼f­¨7f&Í¥‰NóqöÂ[» jé̀ßüíÉ)tûÑƠ1,’ ¸% ’̉%‚-½5 +»kÚ‰‰©ƒg̉đ[‹Ùô]ëÑơÔG×6h•gh¤" º[ùw0œbkh0Ưÿx! +Xܳ>E¶ÜHÙÇ[„újëNRåiW/ +Äï%B"i}vĂTŸơN₫¹v©‚í`oÇEÈ"Ÿ¬jÉpá·-Çb’vmàgïư]̀~íN¦AÏ8M]ƯÙäíÎË¡Yµ̀‰ĂóP ÎtaG^?=R·ûè"‘̀Îd„1×ëC}A™f©ĂÓƒNÅ+~(?@ih“")AÛơ…vÚĂé6₫ܘ¨µIfG$O†É.Á +Œ/köáGNJ¨³ö]”´L[èI/­qÀ»^”`ëôø!̀û0„×s—₫Íp×ú&}ú25ù0DËè;}ﳇeÉ‹ñaăcŸViư{̃ÑƯ ôđ;—"O&FÚäHÉ­àO½Æ’q1¼^É«ëc¨¡Îbéc3•¿ê¡¤ $­/ +q‚;îÇ4‚Z€$ +ƒË6K´¶$€TQ₫–†‘ă¦Ó1Gø»Ù1 ¨ÓÚỹl \8D7¼ḉÆùánÑ€̀‰BAz·ÄÎ(]ßG6«C×½,ê–wÑîJxF‘¸j5"|5†üxtˆ-c>©ƯĐ +ê§idĐ½"Daª¢–tÔ¡ï5ĐĂ‚ŸX +/́uKVg`>®¡ŒL›`ô†}ơËYèơ¶#¿pÏ­6w™)P&‹Ï}É(´́ÿÉƠ ĂG³‡Á 6/Y.÷Ë[oNÊÖ2 F]êÈ)uƠ¿̣Ïß̣œ8Á¬%ɰQÔƒ„dvjÍtœ®̃7Ê?₫Äç¥pnp2¦ù˜%dø³Ÿeœ´RËÓ…ăä°̀¸q;ô=DmÔ 3üÆŸ ?iwZ®øCÚ,"+̣€]†²—¦2_­Ç]´^Nv9e(#ó>ÛLÂ(»ÙÓ•d.VVƒq†ọ̈戶̣ÉÛ«—‹R.¸/¹äăÎGzQ£ábo…’aHî†máCÁˆ ;g<°à:œ{̀¢“£:ă·ïÂRÉQöß*i!íWIĂhV_Ûér¢¥X@˜–Øë¹ẉ¼¾ṇ́¡¶!M5P£o¢Ÿ<×¥;̣&q™B«Â'ûXs›C/w4nĐ[đl‰Ë¡?“î' Ô-„7›đ'Özä‰X±c×iûT£:dĂFçë‹Ï ôăRÑﯭ]V+°F^#¥Lb9ù"z,ÈüGní`x°Ằ̀¯‘-â’°ÓeϹñr°m÷¼EË„»0^|%Æ—¯l0ƒAÛ+í¦x}8·*YMÍÁ“ăáÑă¥1•#UÛ`+ôºh8bE¡ºí’nƠH ƒ ¬aUmÔ¬ „Tj·ÂdJJ<Ư]„ˆ´“¿eXAdùÊåml,˜ +ï}.¾‘‰Œ‹4å–EuîHđû9ê=JG,iÇâ9ñ˜jsÓ:EH;Ü›¥̃æ7§, +BU²ü¤̃ËæßÇ÷¼‚…­3©VỷàÈ|͆ÎqxœĂ ̃ˆÈüªÏÈ’Üj±6ÿ:ÎØ¤mW|Z­–&™;ÂQ …LÈÚËcê¦-ämƯÊ¥s>ˆk-¹P §ơ4’FkdÛW)Z¨t ’mêjOÚ+]h©‰gÙ뛓Afw*ù„à}w lđ¶éÁ’wÚΨY9¼½ÙcYOHÙÎ‚í¯¿¢ƒÔ”hSˆbØd~Â(}Íô‚/<̀GÔw’]€WÏâ²™ª©VŒÅ˜Û§¾TDØI‡N†¿ ¾!¹wÖ®1‚2fU¨Ḯ­q0‰̣éÛ₫˜ÜÙÔ"(0» ûÍXÓ¢ù:ºLÇc$Ơœ=æjœø¶°́‹†Înú¢¿[TS†̀à+P€aådž̉-À>‚"È5aÓxÔ9ÿH~~@ NäF‘‹YS8i¿‹Ạ́÷Z Äל¼’µP©}r„ù₫̃}Ă¹W°{ƒ;µ]²14:sÉ?óRß©úĂñ5‡„ ûÊM™XÜÿs¡>–NNÂPU‰cIVư¦ë'üïÇ#m”+¦ăŸ«·ª!ξBĂ[ÅÈǻT­¨¹9<åj`¿CX̉•ë¶yl<M˜&<«M,1̃ ÓC¥1̉ö…†«5û®âK4n)7›^á\¿N†,ÜÖÎ-¿ü¾῭è£öÍ…Đ=c'rlfƯÜơw§Y_2́k±ÏnÚƒSñelƯW[¹W¼Ô§å’¦¾g‰ú2Y`3Z·X)u×´ù́Ø'l@È2¬đ=đ%iÁ +â(à¡ Ơ!vöj8ơå!Ä~}f £2y`‰¶ÜƯ­-́\l»JdаƯ˜,€sˆL¡Dí³7› è8Ú,êS›ˆ›ḥ_‹gù„y¯7F)^B›DBJí…L0%U{ShđkÅ]QϬ9áxl1Y^4BYÈWεP¥$_ö0X#‰™#›? !~¡K̀̀%”–ŸƠ§…£â¤#ê }—=[ÿơe,U½)́ToEz¯r¯$ÿdœ́ơ#¸ûº>@{âP­Ï€uß6¹å Ÿw¹2ª>À=U‚½˜xu˜ÈXWWó ¯RÅ#Sus¸ê¦ưD¦p2Ä|é µß©{¦;C¢_¦ñ¬‹WÜ»Đ4—9ǿ¶®²ù„¤n‰€TÖ͢ǵ—^ ¢,Æ­ëz‰, z‰úƯ^CH½¥ư:m«8zû Îs›´¼m‚DÚ›°¼Ç^Œ̉s̀ÎNẰÄ̉p¾"aÔ½}]9–Ïn#,çZ·mN¸K¨W]Đʲ|YÊgI¶­äy`…I{Ó4²\sÂw7œh"ÈĂđ3¤IYN›ÊÓQôúщ® ̀„7Ú$m^Ó…Üi”Æ7Sx;O«Åmg¨ráEưï:ßøØi÷Èû'>¦̣I7å꽟Oux,zI)§R42nYÖỌ×́ö©˜^ Ï?bÁÅ-®Ó¡îŒ/k©–¼ŸkßîĐÑ8]Đ^DF‡ư‘“¥endË’½c•8&öP£W©½f›É ……GnĂ©+ßwpXäŒ{µ|qå§5sÆ=ĐúÉ r6ưOÓ`;Åöç9Ư.£6’Ê₫ôØơ/q:—¤¨Ö ÷o«¢́[ªÁ̀_sœƒ̃đ'(„ͨ̃7¨¨ưÏËÈLûwT*‹ZÈ<ówZnöO¼yŸí•ëåĂÍmزQ#ïֻňª1¸đO×UD,"+t6HĂz³N{ßKÅ$Ä …¾'ΡlbWĆ5Ï‘)7v¾âó¿¶£Ëc )™ô¨æf Wt)²ă,"w˜è¾%ïñ*6©ªßZ„ô­8e(hJëfëN“¤ÿdvn;M1rǼÂÁØ­œrk€Đ´Ç÷¡¬óÑ)ë’°^ßAd¿Ÿ ¼zê7„ÏZđ?·Lyê ,ăËwsn³e•̉34£xºrĐ-±“sf¯ồ + +r̀ Ṭ¹mÎÍf¤Y:Y[È®±!̀>t×î¿Å$/…C‘øjÙ„ú‡«egHê”JIôœ½‡M8†iŒ‘́’.¸ÍƯ »’n]íúR̃ÂËŒ·~ƒ—oúµ©Y€]T.>­Ư’ê5å^…ăưɱ(–ùB~Ç( «,,ÈbJê tI<úæ—;Ÿ»Ơ8$̃øuư¸®dJÅæ̣$c÷@Đ/ḾÁ6C/géf¨²ÅÜ:?0 ¾ôso +*&82₫b°ÈFêcđ½ÅP™t ¿¾30˜WÙ$}í¨•2 +ăvií:Fß ³$[wBDg$0™Ă$: C¶ç W·Fæ"§™¶ơl±ZcB×Ñ©ÅKzæh` ¯:1XOw{˜ëj–ƒÊ²´Lê|MơºèKƯ5~F°æ₫óàư§ûg(3Ë>T¾̉q+dêéAí̃â°ÄóAŸ/ôÄCù¯0OE£ÄA8ÓÉ6›úų¨½Đḍ¸:kṾ˜Ô§ƠÏ^%²î3H¶Ä/¿J­ă¹nỤ́_ç/¾ƠWîI-ÀYYc P\îOjr4á}cY¬ÜÛö¢ÑJVße¢7NÙ~Qlf ä#ÁGæ§Đ\£¬T®wªÊ«pÑÜÜ4ªđ]dWJ~ér<ʼnUœWÑÈÁËơƒsW®$d^ÉÏ$Ê qÎ m*à }­^‰ís`‚ µ¶₫µÍ(”SF±úiŸŸkyÖ·µbe—¾zHú<₫43?\ësÖINƒ8ư`˜®Ơx媾L~¤Èï{ûYâd`e´5ød1Î^·zÅX66eQ "ƒ~ÈBJéÅ—{qÚÜXº©gp°ªzß&̉¬Ó¼V_§)ë¹,GŸQbGtSÔ¦&,φŸø ©(â\TÏ̃µmn^@}Èÿ˜-Trđ_ ̉œƯ ‚$å‘ơ©NØ|Å¡°ØÇ0W_îFè2T…üKéđÇĐ)ˆÁí‡a3¯s‡{¯ˆ™Ṕ°QHªù<¬Ÿ0J´çÎc̀ü à}!6dܰüê ØLÂ/Qªév\µ¯Đ)ñn4Ç’₫ è—¸`Œ›úê°῭… + +cƠ)'¾GY!–8•RơI¹0›2Ï/>o7wê—˜iœwmpÙ[µkZº=uÙø¶³Äµ̃¿ŸÛ ï ×ûpÖ–·†»->yƠ.æ„iÔÏßDÄÀx3°-ƒ¨”D`è×Z>¤À2|mÓ­!é,Æ_PQH,Q/:„RốD»F¯DøêB¸éôm‹˜Î?Hj6µ¸G«±̉M‡2†gĂ Ç¾I¹br™ÊƠĐÙî‚÷fù¹"ÀKƒÔmSüæi¸ë̀Dñ•œ»†W^OsÜÉC†ÓĐË Ç_›ºO·ÚỢ¹ÓÚú7Ä>x&H´ÚæôŒ!t¬f"yQNÔäeÿë¹FB*¨»íl™OX:¤.˜ÇLO?A}:̣¼¤Å]ª¡; v?1Üă²¦ïQ|¬ôY±]̃ÑÄP€-âvZn÷XpŸ´îBđµ?Vw†¢ü >g₫ê7å×ëĂŸÚ Úq¿ªCê Î7°GỈ^êVèù$̣’ ¨̉ñăl}ÏiT‚8Ơ)¥s¥r‚Ç̃ˆ–Gˆ‚›¥2Û‰ó6û¸Ù–¼néÈß… hơ¶p +Ñ¿6Ư®cîsm>|–Ö­ÜØL ]z‹™'R“é8̃ªÿ& ²Mq»̀†q„.[ÚW¬í'/WZ‹×ªĐø½] Ë¤èÅ}ê²¼qÛ¡SâºaGKú'anđ4Xb«8a_û†#0;c̀ˆ¡ê—âưjy&5IE‘BVµqh(̃/ æ ¾rüü£µ-sµ^̀bö¸̃B–›;b½µ¤}AÜj2)Isî̃ Gi;6?è÷vhdQ`”§úµ^—>ruffLă±"ö« 5Ă%”„lë/t£ÅLĐÿ̉„Ëéừ “¯¬́^°b +:Ñú?Ͷ; +endstream +endobj +722 0 obj << +/Type /FontDescriptor +/FontName /EEGFTS+NimbusRomNo9L-ReguItal +/Flags 4 +/FontBBox [-169 -270 1010 924] +/Ascent 668 +/CapHeight 668 +/Descent -193 +/ItalicAngle -15 +/StemV 78 +/XHeight 441 +/CharSet (/C/E/F/G/I/S/a/b/c/comma/d/e/eight/f/fi/g/h/hyphen/i/k/l/m/n/o/p/parenleft/parenright/period/r/s/t/three/two/u/v/w/x/y/z) +/FontFile 721 0 R +>> endobj +671 0 obj << +/Type /Encoding +/Differences [2/fi/fl 33/exclam/quotedbl/numbersign 39/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon 61/equal 65/A/B/C/D/E/F/G/H/I/J 76/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y 91/bracketleft 93/bracketright 95/underscore 97/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft 125/braceright 149/bullet 169/copyright 174/registered] +>> endobj +317 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /YQJSDJ+CMEX10 +/FontDescriptor 690 0 R +/FirstChar 88 +/LastChar 88 +/Widths 676 0 R +>> endobj +313 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /CVGKQU+CMMI10 +/FontDescriptor 692 0 R +/FirstChar 62 +/LastChar 120 +/Widths 680 0 R +>> endobj +316 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /EFXCJE+CMMI7 +/FontDescriptor 694 0 R +/FirstChar 59 +/LastChar 107 +/Widths 677 0 R +>> endobj +315 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /JVDJDJ+CMR10 +/FontDescriptor 696 0 R +/FirstChar 43 +/LastChar 61 +/Widths 678 0 R +>> endobj +314 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /XLWYJF+CMR7 +/FontDescriptor 698 0 R +/FirstChar 49 +/LastChar 61 +/Widths 679 0 R +>> endobj +318 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /EMXNQD+CMSY10 +/FontDescriptor 700 0 R +/FirstChar 1 +/LastChar 106 +/Widths 675 0 R +>> endobj +499 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /DJYPXZ+CMSY6 +/FontDescriptor 702 0 R +/FirstChar 94 +/LastChar 94 +/Widths 673 0 R +>> endobj +312 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /LAJUWJ+CMSY7 +/FontDescriptor 704 0 R +/FirstChar 94 +/LastChar 94 +/Widths 681 0 R +>> endobj +239 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /YDPBQZ+NimbusMonL-Regu +/FontDescriptor 706 0 R +/FirstChar 34 +/LastChar 121 +/Widths 684 0 R +/Encoding 671 0 R +>> endobj +227 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /IPRZVI+NimbusSanL-Bold +/FontDescriptor 708 0 R +/FirstChar 40 +/LastChar 174 +/Widths 688 0 R +/Encoding 671 0 R +>> endobj +309 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /CIYFZS+NimbusSanL-BoldCond +/FontDescriptor 710 0 R +/FirstChar 40 +/LastChar 121 +/Widths 682 0 R +/Encoding 671 0 R +>> endobj +228 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /NYWZOF+NimbusSanL-BoldItal +/FontDescriptor 712 0 R +/FirstChar 44 +/LastChar 114 +/Widths 687 0 R +/Encoding 671 0 R +>> endobj +529 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /KFEQLI+NimbusSanL-BoldCondItal +/FontDescriptor 714 0 R +/FirstChar 44 +/LastChar 119 +/Widths 672 0 R +/Encoding 671 0 R +>> endobj +306 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /IXMTHF+NimbusSanL-Regu +/FontDescriptor 716 0 R +/FirstChar 49 +/LastChar 89 +/Widths 683 0 R +/Encoding 671 0 R +>> endobj +237 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /ZDVWXI+NimbusRomNo9L-Medi +/FontDescriptor 718 0 R +/FirstChar 46 +/LastChar 121 +/Widths 686 0 R +/Encoding 671 0 R +>> endobj +238 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /IPABSO+NimbusRomNo9L-Regu +/FontDescriptor 720 0 R +/FirstChar 2 +/LastChar 174 +/Widths 685 0 R +/Encoding 671 0 R +>> endobj +498 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /EEGFTS+NimbusRomNo9L-ReguItal +/FontDescriptor 722 0 R +/FirstChar 2 +/LastChar 122 +/Widths 674 0 R +/Encoding 671 0 R +>> endobj +229 0 obj << +/Type /Pages +/Count 6 +/Parent 723 0 R +/Kids [222 0 R 235 0 R 274 0 R 298 0 R 303 0 R 323 0 R] +>> endobj +364 0 obj << +/Type /Pages +/Count 6 +/Parent 723 0 R +/Kids [358 0 R 366 0 R 432 0 R 460 0 R 475 0 R 494 0 R] +>> endobj +519 0 obj << +/Type /Pages +/Count 6 +/Parent 723 0 R +/Kids [516 0 R 526 0 R 538 0 R 545 0 R 553 0 R 559 0 R] +>> endobj +572 0 obj << +/Type /Pages +/Count 6 +/Parent 723 0 R +/Kids [567 0 R 576 0 R 582 0 R 590 0 R 598 0 R 604 0 R] +>> endobj +616 0 obj << +/Type /Pages +/Count 6 +/Parent 723 0 R +/Kids [611 0 R 618 0 R 626 0 R 633 0 R 641 0 R 651 0 R] +>> endobj +663 0 obj << +/Type /Pages +/Count 2 +/Parent 723 0 R +/Kids [658 0 R 666 0 R] +>> endobj +723 0 obj << +/Type /Pages +/Count 32 +/Kids [229 0 R 364 0 R 519 0 R 572 0 R 616 0 R 663 0 R] +>> endobj +724 0 obj << +/Type /Outlines +/First 7 0 R +/Last 51 0 R +/Count 5 +>> endobj +219 0 obj << +/Title 220 0 R +/A 217 0 R +/Parent 215 0 R +>> endobj +215 0 obj << +/Title 216 0 R +/A 213 0 R +/Parent 51 0 R +/Prev 183 0 R +/First 219 0 R +/Last 219 0 R +/Count -1 +>> endobj +211 0 obj << +/Title 212 0 R +/A 209 0 R +/Parent 191 0 R +/Prev 207 0 R +>> endobj +207 0 obj << +/Title 208 0 R +/A 205 0 R +/Parent 191 0 R +/Prev 203 0 R +/Next 211 0 R +>> endobj +203 0 obj << +/Title 204 0 R +/A 201 0 R +/Parent 191 0 R +/Prev 199 0 R +/Next 207 0 R +>> endobj +199 0 obj << +/Title 200 0 R +/A 197 0 R +/Parent 191 0 R +/Prev 195 0 R +/Next 203 0 R +>> endobj +195 0 obj << +/Title 196 0 R +/A 193 0 R +/Parent 191 0 R +/Next 199 0 R +>> endobj +191 0 obj << +/Title 192 0 R +/A 189 0 R +/Parent 183 0 R +/Prev 187 0 R +/First 195 0 R +/Last 211 0 R +/Count -5 +>> endobj +187 0 obj << +/Title 188 0 R +/A 185 0 R +/Parent 183 0 R +/Next 191 0 R +>> endobj +183 0 obj << +/Title 184 0 R +/A 181 0 R +/Parent 51 0 R +/Prev 55 0 R +/Next 215 0 R +/First 187 0 R +/Last 191 0 R +/Count -2 +>> endobj +179 0 obj << +/Title 180 0 R +/A 177 0 R +/Parent 63 0 R +/Prev 175 0 R +>> endobj +175 0 obj << +/Title 176 0 R +/A 173 0 R +/Parent 63 0 R +/Prev 171 0 R +/Next 179 0 R +>> endobj +171 0 obj << +/Title 172 0 R +/A 169 0 R +/Parent 63 0 R +/Prev 167 0 R +/Next 175 0 R +>> endobj +167 0 obj << +/Title 168 0 R +/A 165 0 R +/Parent 63 0 R +/Prev 163 0 R +/Next 171 0 R +>> endobj +163 0 obj << +/Title 164 0 R +/A 161 0 R +/Parent 63 0 R +/Prev 159 0 R +/Next 167 0 R +>> endobj +159 0 obj << +/Title 160 0 R +/A 157 0 R +/Parent 63 0 R +/Prev 155 0 R +/Next 163 0 R +>> endobj +155 0 obj << +/Title 156 0 R +/A 153 0 R +/Parent 63 0 R +/Prev 151 0 R +/Next 159 0 R +>> endobj +151 0 obj << +/Title 152 0 R +/A 149 0 R +/Parent 63 0 R +/Prev 147 0 R +/Next 155 0 R +>> endobj +147 0 obj << +/Title 148 0 R +/A 145 0 R +/Parent 63 0 R +/Prev 143 0 R +/Next 151 0 R +>> endobj +143 0 obj << +/Title 144 0 R +/A 141 0 R +/Parent 63 0 R +/Prev 139 0 R +/Next 147 0 R +>> endobj +139 0 obj << +/Title 140 0 R +/A 137 0 R +/Parent 63 0 R +/Prev 135 0 R +/Next 143 0 R +>> endobj +135 0 obj << +/Title 136 0 R +/A 133 0 R +/Parent 63 0 R +/Prev 131 0 R +/Next 139 0 R +>> endobj +131 0 obj << +/Title 132 0 R +/A 129 0 R +/Parent 63 0 R +/Prev 127 0 R +/Next 135 0 R +>> endobj +127 0 obj << +/Title 128 0 R +/A 125 0 R +/Parent 63 0 R +/Prev 123 0 R +/Next 131 0 R +>> endobj +123 0 obj << +/Title 124 0 R +/A 121 0 R +/Parent 63 0 R +/Prev 119 0 R +/Next 127 0 R +>> endobj +119 0 obj << +/Title 120 0 R +/A 117 0 R +/Parent 63 0 R +/Prev 115 0 R +/Next 123 0 R +>> endobj +115 0 obj << +/Title 116 0 R +/A 113 0 R +/Parent 63 0 R +/Prev 111 0 R +/Next 119 0 R +>> endobj +111 0 obj << +/Title 112 0 R +/A 109 0 R +/Parent 63 0 R +/Prev 107 0 R +/Next 115 0 R +>> endobj +107 0 obj << +/Title 108 0 R +/A 105 0 R +/Parent 63 0 R +/Prev 103 0 R +/Next 111 0 R +>> endobj +103 0 obj << +/Title 104 0 R +/A 101 0 R +/Parent 63 0 R +/Prev 99 0 R +/Next 107 0 R +>> endobj +99 0 obj << +/Title 100 0 R +/A 97 0 R +/Parent 63 0 R +/Prev 95 0 R +/Next 103 0 R +>> endobj +95 0 obj << +/Title 96 0 R +/A 93 0 R +/Parent 63 0 R +/Prev 91 0 R +/Next 99 0 R +>> endobj +91 0 obj << +/Title 92 0 R +/A 89 0 R +/Parent 63 0 R +/Prev 87 0 R +/Next 95 0 R +>> endobj +87 0 obj << +/Title 88 0 R +/A 85 0 R +/Parent 63 0 R +/Prev 83 0 R +/Next 91 0 R +>> endobj +83 0 obj << +/Title 84 0 R +/A 81 0 R +/Parent 63 0 R +/Prev 79 0 R +/Next 87 0 R +>> endobj +79 0 obj << +/Title 80 0 R +/A 77 0 R +/Parent 63 0 R +/Prev 75 0 R +/Next 83 0 R +>> endobj +75 0 obj << +/Title 76 0 R +/A 73 0 R +/Parent 63 0 R +/Prev 71 0 R +/Next 79 0 R +>> endobj +71 0 obj << +/Title 72 0 R +/A 69 0 R +/Parent 63 0 R +/Prev 67 0 R +/Next 75 0 R +>> endobj +67 0 obj << +/Title 68 0 R +/A 65 0 R +/Parent 63 0 R +/Next 71 0 R +>> endobj +63 0 obj << +/Title 64 0 R +/A 61 0 R +/Parent 55 0 R +/Prev 59 0 R +/First 67 0 R +/Last 179 0 R +/Count -29 +>> endobj +59 0 obj << +/Title 60 0 R +/A 57 0 R +/Parent 55 0 R +/Next 63 0 R +>> endobj +55 0 obj << +/Title 56 0 R +/A 53 0 R +/Parent 51 0 R +/Next 183 0 R +/First 59 0 R +/Last 63 0 R +/Count -2 +>> endobj +51 0 obj << +/Title 52 0 R +/A 49 0 R +/Parent 724 0 R +/Prev 43 0 R +/First 55 0 R +/Last 215 0 R +/Count -3 +>> endobj +47 0 obj << +/Title 48 0 R +/A 45 0 R +/Parent 43 0 R +>> endobj +43 0 obj << +/Title 44 0 R +/A 41 0 R +/Parent 724 0 R +/Prev 39 0 R +/Next 51 0 R +/First 47 0 R +/Last 47 0 R +/Count -1 +>> endobj +39 0 obj << +/Title 40 0 R +/A 37 0 R +/Parent 724 0 R +/Prev 27 0 R +/Next 43 0 R +>> endobj +35 0 obj << +/Title 36 0 R +/A 33 0 R +/Parent 27 0 R +/Prev 31 0 R +>> endobj +31 0 obj << +/Title 32 0 R +/A 29 0 R +/Parent 27 0 R +/Next 35 0 R +>> endobj +27 0 obj << +/Title 28 0 R +/A 25 0 R +/Parent 724 0 R +/Prev 7 0 R +/Next 39 0 R +/First 31 0 R +/Last 35 0 R +/Count -2 +>> endobj +23 0 obj << +/Title 24 0 R +/A 21 0 R +/Parent 7 0 R +/Prev 19 0 R +>> endobj +19 0 obj << +/Title 20 0 R +/A 17 0 R +/Parent 7 0 R +/Prev 15 0 R +/Next 23 0 R +>> endobj +15 0 obj << +/Title 16 0 R +/A 13 0 R +/Parent 7 0 R +/Prev 11 0 R +/Next 19 0 R +>> endobj +11 0 obj << +/Title 12 0 R +/A 9 0 R +/Parent 7 0 R +/Next 15 0 R +>> endobj +7 0 obj << +/Title 8 0 R +/A 5 0 R +/Parent 724 0 R +/Next 27 0 R +/First 11 0 R +/Last 23 0 R +/Count -4 +>> endobj +725 0 obj << +/Names [(Doc-Start) 226 0 R (chapter.1) 6 0 R (chapter.2) 26 0 R (chapter.3) 38 0 R (chapter.4) 42 0 R (chapter.5) 50 0 R] +/Limits [(Doc-Start) (chapter.5)] +>> endobj +726 0 obj << +/Names [(erasure__code_8h) 478 0 R (erasure__code_8h_a06a563b718c6269c8df0fe7647e5bb49) 379 0 R (erasure__code_8h_a12f59be6d348fea6ad2464a20af22fd3) 380 0 R (erasure__code_8h_a17799d49d9b83861322ebf314a55f77f) 386 0 R (erasure__code_8h_a17c6ccf6470796b756841e160dc8697c) 374 0 R (erasure__code_8h_a1fb1d6d463ac00ae196501c75d2036d2) 388 0 R] +/Limits [(erasure__code_8h) (erasure__code_8h_a1fb1d6d463ac00ae196501c75d2036d2)] +>> endobj +727 0 obj << +/Names [(erasure__code_8h_a1ff835062a19d6516f2d59d9c37ddb48) 372 0 R (erasure__code_8h_a21d5e25b4ac64062996149fea71aede8) 382 0 R (erasure__code_8h_a22b53cd4103da9ed88c351e7045ff313) 381 0 R (erasure__code_8h_a2688b38c18e93c95c525c0d5bf9e221a) 393 0 R (erasure__code_8h_a26c2200ad3bf04b1c858eb239b7ff940) 376 0 R (erasure__code_8h_a2fb7662ba4e1df4bb72659c57efeaad6) 394 0 R] +/Limits [(erasure__code_8h_a1ff835062a19d6516f2d59d9c37ddb48) (erasure__code_8h_a2fb7662ba4e1df4bb72659c57efeaad6)] +>> endobj +728 0 obj << +/Names [(erasure__code_8h_a484460566a8c888fda3d769324461345) 521 0 R (erasure__code_8h_a4f880c4b9fe6700e040b9f4ef4e45918) 373 0 R (erasure__code_8h_a590b5c35075aeea1243a9e4ef73a49d4) 320 0 R (erasure__code_8h_a6ce05684e168d73773847a3c2c13c175) 387 0 R (erasure__code_8h_a81be18ea979e8a32f384e1a7856badcf) 531 0 R (erasure__code_8h_aa486278c409735df8001096ac2b487dd) 384 0 R] +/Limits [(erasure__code_8h_a484460566a8c888fda3d769324461345) (erasure__code_8h_aa486278c409735df8001096ac2b487dd)] +>> endobj +729 0 obj << +/Names [(erasure__code_8h_aacd489f45babdbfe6a41f1bac2885ab6) 389 0 R (erasure__code_8h_abb7a991b4c0fb9ced373680ef36bae08) 375 0 R (erasure__code_8h_ac64153e1aef3cdc4b69d375ec762fa33) 392 0 R (erasure__code_8h_ac6468d7eb3c28116439abb4a7c5eca05) 396 0 R (erasure__code_8h_ac73ea8358bc3155c7f3a6c078a7d6d35) 520 0 R (erasure__code_8h_ad0eca329291d751df6ffb3aa3eb83610) 390 0 R] +/Limits [(erasure__code_8h_aacd489f45babdbfe6a41f1bac2885ab6) (erasure__code_8h_ad0eca329291d751df6ffb3aa3eb83610)] +>> endobj +730 0 obj << +/Names [(erasure__code_8h_ad808efb2e8af3803571c0a6c7c9faf39) 533 0 R (erasure__code_8h_ae1e4c9eb9a26a3a7852166d54d2a27f8) 377 0 R (erasure__code_8h_af88a7da05f46e1a0fe17d032a2cf78bf) 378 0 R (erasure__code_8h_af88c501e0c5138ec9c88f58c182945e8) 395 0 R (erasure__code_8h_afd549f435ee28276b5a9408a3a6256b1) 532 0 R (erasure__code_8h_afeefb3612c92a0bc87182f6e11030b11) 391 0 R] +/Limits [(erasure__code_8h_ad808efb2e8af3803571c0a6c7c9faf39) (erasure__code_8h_afeefb3612c92a0bc87182f6e11030b11)] +>> endobj +731 0 obj << +/Names [(gf__vect__mul_8h) 479 0 R (gf__vect__mul_8h_a15d42d058c64dec106d9e3e9fc2e1136) 369 0 R (gf__vect__mul_8h_a7a1f65b032f03494dbc68411f5614bb1) 371 0 R (gf__vect__mul_8h_a84eb9ca31c934f05a8e3fa7a02fa71dc) 370 0 R (gf__vect__mul_8h_a8f3e57729c3382514325612c54e20eaa) 385 0 R (gf__vect__mul_8h_aa7a737b69a0a77dc29aa28d0f17421a1) 383 0 R] +/Limits [(gf__vect__mul_8h) (gf__vect__mul_8h_aa7a737b69a0a77dc29aa28d0f17421a1)] +>> endobj +732 0 obj << +/Names [(index) 307 0 R (index_about_sec) 308 0 R (index_ec_sec) 311 0 R (index_intro_sec) 310 0 R (index_sys_reg_sec) 319 0 R (page.1) 305 0 R] +/Limits [(index) (page.1)] +>> endobj +733 0 obj << +/Names [(page.10) 528 0 R (page.11) 540 0 R (page.12) 547 0 R (page.13) 555 0 R (page.14) 561 0 R (page.15) 569 0 R] +/Limits [(page.10) (page.15)] +>> endobj +734 0 obj << +/Names [(page.16) 578 0 R (page.17) 584 0 R (page.18) 592 0 R (page.19) 600 0 R (page.2) 325 0 R (page.20) 606 0 R] +/Limits [(page.16) (page.20)] +>> endobj +735 0 obj << +/Names [(page.21) 613 0 R (page.22) 620 0 R (page.23) 628 0 R (page.24) 635 0 R (page.25) 643 0 R (page.26) 653 0 R] +/Limits [(page.21) (page.26)] +>> endobj +736 0 obj << +/Names [(page.27) 660 0 R (page.28) 668 0 R (page.3) 360 0 R (page.4) 368 0 R (page.5) 434 0 R (page.6) 462 0 R] +/Limits [(page.27) (page.6)] +>> endobj +737 0 obj << +/Names [(page.7) 477 0 R (page.8) 496 0 R (page.9) 518 0 R (requires) 327 0 R (requires__requires000001) 435 0 R (requires__requires000002) 465 0 R] +/Limits [(page.7) (requires__requires000002)] +>> endobj +738 0 obj << +/Names [(requires__requires000003) 463 0 R (requires__requires000004) 464 0 R (requires__requires000005) 438 0 R (requires__requires000006) 436 0 R (requires__requires000007) 437 0 R (requires__requires000008) 441 0 R] +/Limits [(requires__requires000003) (requires__requires000008)] +>> endobj +739 0 obj << +/Names [(requires__requires000009) 439 0 R (requires__requires000010) 440 0 R (requires__requires000011) 444 0 R (requires__requires000012) 442 0 R (requires__requires000013) 443 0 R (requires__requires000014) 447 0 R] +/Limits [(requires__requires000009) (requires__requires000014)] +>> endobj +740 0 obj << +/Names [(requires__requires000015) 445 0 R (requires__requires000016) 446 0 R (requires__requires000017) 450 0 R (requires__requires000018) 448 0 R (requires__requires000019) 449 0 R (requires__requires000020) 467 0 R] +/Limits [(requires__requires000015) (requires__requires000020)] +>> endobj +741 0 obj << +/Names [(requires__requires000021) 466 0 R (section*.1) 497 0 R (section*.2) 654 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R] +/Limits [(requires__requires000021) (section.1.3)] +>> endobj +742 0 obj << +/Names [(section.1.4) 22 0 R (section.2.1) 30 0 R (section.2.2) 34 0 R (section.4.1) 46 0 R (section.5.1) 54 0 R (section.5.2) 182 0 R] +/Limits [(section.1.4) (section.5.2)] +>> endobj +743 0 obj << +/Names [(section.5.3) 214 0 R (subsection.5.1.1) 58 0 R (subsection.5.1.2) 62 0 R (subsection.5.2.1) 186 0 R (subsection.5.2.2) 190 0 R (subsection.5.3.1) 218 0 R] +/Limits [(section.5.3) (subsection.5.3.1)] +>> endobj +744 0 obj << +/Names [(subsubsection.5.1.2.1) 66 0 R (subsubsection.5.1.2.10) 102 0 R (subsubsection.5.1.2.11) 106 0 R (subsubsection.5.1.2.12) 110 0 R (subsubsection.5.1.2.13) 114 0 R (subsubsection.5.1.2.14) 118 0 R] +/Limits [(subsubsection.5.1.2.1) (subsubsection.5.1.2.14)] +>> endobj +745 0 obj << +/Names [(subsubsection.5.1.2.15) 122 0 R (subsubsection.5.1.2.16) 126 0 R (subsubsection.5.1.2.17) 130 0 R (subsubsection.5.1.2.18) 134 0 R (subsubsection.5.1.2.19) 138 0 R (subsubsection.5.1.2.2) 70 0 R] +/Limits [(subsubsection.5.1.2.15) (subsubsection.5.1.2.2)] +>> endobj +746 0 obj << +/Names [(subsubsection.5.1.2.20) 142 0 R (subsubsection.5.1.2.21) 146 0 R (subsubsection.5.1.2.22) 150 0 R (subsubsection.5.1.2.23) 154 0 R (subsubsection.5.1.2.24) 158 0 R (subsubsection.5.1.2.25) 162 0 R] +/Limits [(subsubsection.5.1.2.20) (subsubsection.5.1.2.25)] +>> endobj +747 0 obj << +/Names [(subsubsection.5.1.2.26) 166 0 R (subsubsection.5.1.2.27) 170 0 R (subsubsection.5.1.2.28) 174 0 R (subsubsection.5.1.2.29) 178 0 R (subsubsection.5.1.2.3) 74 0 R (subsubsection.5.1.2.4) 78 0 R] +/Limits [(subsubsection.5.1.2.26) (subsubsection.5.1.2.4)] +>> endobj +748 0 obj << +/Names [(subsubsection.5.1.2.5) 82 0 R (subsubsection.5.1.2.6) 86 0 R (subsubsection.5.1.2.7) 90 0 R (subsubsection.5.1.2.8) 94 0 R (subsubsection.5.1.2.9) 98 0 R (subsubsection.5.2.2.1) 194 0 R] +/Limits [(subsubsection.5.1.2.5) (subsubsection.5.2.2.1)] +>> endobj +749 0 obj << +/Names [(subsubsection.5.2.2.2) 198 0 R (subsubsection.5.2.2.3) 202 0 R (subsubsection.5.2.2.4) 206 0 R (subsubsection.5.2.2.5) 210 0 R (table.5.1) 530 0 R (table.5.10) 571 0 R] +/Limits [(subsubsection.5.2.2.2) (table.5.10)] +>> endobj +750 0 obj << +/Names [(table.5.11) 579 0 R (table.5.12) 585 0 R (table.5.13) 586 0 R (table.5.14) 593 0 R (table.5.15) 594 0 R (table.5.16) 601 0 R] +/Limits [(table.5.11) (table.5.16)] +>> endobj +751 0 obj << +/Names [(table.5.17) 607 0 R (table.5.18) 608 0 R (table.5.19) 614 0 R (table.5.2) 541 0 R (table.5.20) 615 0 R (table.5.21) 621 0 R] +/Limits [(table.5.17) (table.5.21)] +>> endobj +752 0 obj << +/Names [(table.5.22) 622 0 R (table.5.23) 623 0 R (table.5.24) 629 0 R (table.5.25) 630 0 R (table.5.26) 636 0 R (table.5.27) 637 0 R] +/Limits [(table.5.22) (table.5.27)] +>> endobj +753 0 obj << +/Names [(table.5.28) 644 0 R (table.5.29) 645 0 R (table.5.3) 542 0 R (table.5.30) 655 0 R (table.5.31) 661 0 R (table.5.32) 662 0 R] +/Limits [(table.5.28) (table.5.32)] +>> endobj +754 0 obj << +/Names [(table.5.33) 669 0 R (table.5.34) 670 0 R (table.5.4) 548 0 R (table.5.5) 549 0 R (table.5.6) 556 0 R (table.5.7) 562 0 R] +/Limits [(table.5.33) (table.5.7)] +>> endobj +755 0 obj << +/Names [(table.5.8) 563 0 R (table.5.9) 570 0 R (types_8h) 480 0 R (version) 361 0 R (version_test) 362 0 R (version_test2) 363 0 R] +/Limits [(table.5.8) (version_test2)] +>> endobj +756 0 obj << +/Kids [725 0 R 726 0 R 727 0 R 728 0 R 729 0 R 730 0 R] +/Limits [(Doc-Start) (erasure__code_8h_afeefb3612c92a0bc87182f6e11030b11)] +>> endobj +757 0 obj << +/Kids [731 0 R 732 0 R 733 0 R 734 0 R 735 0 R 736 0 R] +/Limits [(gf__vect__mul_8h) (page.6)] +>> endobj +758 0 obj << +/Kids [737 0 R 738 0 R 739 0 R 740 0 R 741 0 R 742 0 R] +/Limits [(page.7) (section.5.2)] +>> endobj +759 0 obj << +/Kids [743 0 R 744 0 R 745 0 R 746 0 R 747 0 R 748 0 R] +/Limits [(section.5.3) (subsubsection.5.2.2.1)] +>> endobj +760 0 obj << +/Kids [749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R] +/Limits [(subsubsection.5.2.2.2) (table.5.7)] +>> endobj +761 0 obj << +/Kids [755 0 R] +/Limits [(table.5.8) (version_test2)] +>> endobj +762 0 obj << +/Kids [756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R] +/Limits [(Doc-Start) (version_test2)] +>> endobj +763 0 obj << +/Dests 762 0 R +>> endobj +764 0 obj << +/Type /Catalog +/Pages 723 0 R +/Outlines 724 0 R +/Names 763 0 R +/PageMode/UseOutlines/PageLabels << /Nums [0 << /S /D >> 1 << /S /D >> 2 << /S /r >> 4 << /S /D >> ] >> +/OpenAction 221 0 R +>> endobj +765 0 obj << +/Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.3)/Keywords() +/CreationDate (D:20140408225608-07'00') +/ModDate (D:20140408225608-07'00') +/Trapped /False +/PTEX.Fullbanner (This is pdfTeX using libpoppler, Version 3.141592-1.40.3-2.2 (Web2C 7.5.6) kpathsea version 3.5.6) +>> endobj +xref +0 766 +0000000001 65535 f +0000000002 00000 f +0000000003 00000 f +0000000004 00000 f +0000000397 00000 f +0000000015 00000 n +0000029129 00000 n +0000248311 00000 n +0000000060 00000 n +0000000164 00000 n +0000029306 00000 n +0000248239 00000 n +0000000211 00000 n +0000000339 00000 n +0000029424 00000 n +0000248153 00000 n +0000000387 00000 n +0000000454 00000 n +0000029541 00000 n +0000248067 00000 n +0000000502 00000 n +0000000645 00000 n +0000031891 00000 n +0000247994 00000 n +0000000693 00000 n +0000000818 00000 n +0000032878 00000 n +0000247870 00000 n +0000000864 00000 n +0000001017 00000 n +0000033056 00000 n +0000247796 00000 n +0000001065 00000 n +0000001218 00000 n +0000033174 00000 n +0000247722 00000 n +0000001266 00000 n +0000001457 00000 n +0000045007 00000 n +0000247634 00000 n +0000001503 00000 n +0000001676 00000 n +0000050083 00000 n +0000247509 00000 n +0000001722 00000 n +0000001802 00000 n +0000050139 00000 n +0000247448 00000 n +0000001850 00000 n +0000001925 00000 n +0000054175 00000 n +0000247335 00000 n +0000001971 00000 n +0000002091 00000 n +0000054292 00000 n +0000247223 00000 n +0000002139 00000 n +0000002320 00000 n +0000062532 00000 n +0000247149 00000 n +0000002373 00000 n +0000002503 00000 n +0000062588 00000 n +0000247036 00000 n +0000002556 00000 n +0000002696 00000 n +0000062701 00000 n +0000246962 00000 n +0000002754 00000 n +0000002857 00000 n +0000065938 00000 n +0000246875 00000 n +0000002915 00000 n +0000003046 00000 n +0000066108 00000 n +0000246788 00000 n +0000003104 00000 n +0000003230 00000 n +0000069083 00000 n +0000246701 00000 n +0000003288 00000 n +0000003391 00000 n +0000069252 00000 n +0000246614 00000 n +0000003449 00000 n +0000003593 00000 n +0000071916 00000 n +0000246527 00000 n +0000003651 00000 n +0000003800 00000 n +0000072086 00000 n +0000246440 00000 n +0000003858 00000 n +0000004002 00000 n +0000074788 00000 n +0000246353 00000 n +0000004060 00000 n +0000004204 00000 n +0000074958 00000 n +0000246264 00000 n +0000004262 00000 n +0000004412 00000 n +0000077736 00000 n +0000246173 00000 n +0000004472 00000 n +0000004617 00000 n +0000080387 00000 n +0000246081 00000 n +0000004677 00000 n +0000004822 00000 n +0000080558 00000 n +0000245989 00000 n +0000004882 00000 n +0000005032 00000 n +0000083234 00000 n +0000245897 00000 n +0000005092 00000 n +0000005237 00000 n +0000083405 00000 n +0000245805 00000 n +0000005297 00000 n +0000005442 00000 n +0000086187 00000 n +0000245713 00000 n +0000005502 00000 n +0000005652 00000 n +0000089050 00000 n +0000245621 00000 n +0000005712 00000 n +0000005857 00000 n +0000089221 00000 n +0000245529 00000 n +0000005917 00000 n +0000006062 00000 n +0000091925 00000 n +0000245437 00000 n +0000006122 00000 n +0000006272 00000 n +0000092096 00000 n +0000245345 00000 n +0000006332 00000 n +0000006477 00000 n +0000095033 00000 n +0000245253 00000 n +0000006537 00000 n +0000006679 00000 n +0000095203 00000 n +0000245161 00000 n +0000006739 00000 n +0000006856 00000 n +0000097392 00000 n +0000245069 00000 n +0000006916 00000 n +0000006977 00000 n +0000097563 00000 n +0000244977 00000 n +0000007037 00000 n +0000007151 00000 n +0000097734 00000 n +0000244885 00000 n +0000007211 00000 n +0000007272 00000 n +0000100342 00000 n +0000244793 00000 n +0000007332 00000 n +0000007449 00000 n +0000100513 00000 n +0000244701 00000 n +0000007509 00000 n +0000007649 00000 n +0000103118 00000 n +0000244609 00000 n +0000007709 00000 n +0000007854 00000 n +0000103289 00000 n +0000244517 00000 n +0000007914 00000 n +0000008059 00000 n +0000106077 00000 n +0000244439 00000 n +0000008119 00000 n +0000008259 00000 n +0000106248 00000 n +0000244309 00000 n +0000008308 00000 n +0000008488 00000 n +0000109728 00000 n +0000244230 00000 n +0000008542 00000 n +0000008673 00000 n +0000109784 00000 n +0000244112 00000 n +0000008727 00000 n +0000008868 00000 n +0000109898 00000 n +0000244033 00000 n +0000008927 00000 n +0000009016 00000 n +0000110069 00000 n +0000243940 00000 n +0000009075 00000 n +0000009187 00000 n +0000112732 00000 n +0000243847 00000 n +0000009246 00000 n +0000009363 00000 n +0000112903 00000 n +0000243754 00000 n +0000009422 00000 n +0000009539 00000 n +0000115203 00000 n +0000243675 00000 n +0000009598 00000 n +0000009710 00000 n +0000115374 00000 n +0000243558 00000 n +0000009759 00000 n +0000009903 00000 n +0000115431 00000 n +0000243493 00000 n +0000009957 00000 n +0000010088 00000 n +0000010605 00000 n +0000010717 00000 n +0000012711 00000 n +0000010140 00000 n +0000012654 00000 n +0000241253 00000 n +0000241599 00000 n +0000242647 00000 n +0000012333 00000 n +0000012585 00000 n +0000012632 00000 n +0000014877 00000 n +0000015067 00000 n +0000014745 00000 n +0000012824 00000 n +0000242123 00000 n +0000242297 00000 n +0000241082 00000 n +0000016450 00000 n +0000016600 00000 n +0000016753 00000 n +0000016906 00000 n +0000017059 00000 n +0000017212 00000 n +0000017362 00000 n +0000017515 00000 n +0000017667 00000 n +0000017818 00000 n +0000017969 00000 n +0000018121 00000 n +0000018272 00000 n +0000018424 00000 n +0000018583 00000 n +0000018741 00000 n +0000018905 00000 n +0000019069 00000 n +0000019233 00000 n +0000019397 00000 n +0000019560 00000 n +0000019724 00000 n +0000019887 00000 n +0000020051 00000 n +0000020214 00000 n +0000020379 00000 n +0000020544 00000 n +0000020708 00000 n +0000020873 00000 n +0000021037 00000 n +0000021202 00000 n +0000021366 00000 n +0000022687 00000 n +0000021531 00000 n +0000016070 00000 n +0000015165 00000 n +0000022852 00000 n +0000023016 00000 n +0000023181 00000 n +0000023345 00000 n +0000023510 00000 n +0000023674 00000 n +0000023838 00000 n +0000024003 00000 n +0000024167 00000 n +0000024332 00000 n +0000024496 00000 n +0000024661 00000 n +0000024814 00000 n +0000024973 00000 n +0000025132 00000 n +0000025296 00000 n +0000025460 00000 n +0000025624 00000 n +0000025788 00000 n +0000025952 00000 n +0000026105 00000 n +0000026264 00000 n +0000022387 00000 n +0000021616 00000 n +0000028880 00000 n +0000031270 00000 n +0000029659 00000 n +0000028748 00000 n +0000026349 00000 n +0000029072 00000 n +0000241953 00000 n +0000029184 00000 n +0000029245 00000 n +0000241424 00000 n +0000029362 00000 n +0000029480 00000 n +0000240940 00000 n +0000240085 00000 n +0000240514 00000 n +0000240372 00000 n +0000240229 00000 n +0000239942 00000 n +0000240655 00000 n +0000029597 00000 n +0000062644 00000 n +0000031420 00000 n +0000031947 00000 n +0000031122 00000 n +0000029845 00000 n +0000031834 00000 n +0000031628 00000 n +0000045063 00000 n +0000035239 00000 n +0000035430 00000 n +0000035621 00000 n +0000035812 00000 n +0000036003 00000 n +0000036194 00000 n +0000036384 00000 n +0000036575 00000 n +0000036765 00000 n +0000036956 00000 n +0000037146 00000 n +0000037337 00000 n +0000037528 00000 n +0000037719 00000 n +0000037910 00000 n +0000038101 00000 n +0000038292 00000 n +0000038483 00000 n +0000038674 00000 n +0000038865 00000 n +0000039056 00000 n +0000039247 00000 n +0000039438 00000 n +0000039628 00000 n +0000039819 00000 n +0000040009 00000 n +0000040200 00000 n +0000040390 00000 n +0000040581 00000 n +0000033229 00000 n +0000032709 00000 n +0000032058 00000 n +0000032821 00000 n +0000032934 00000 n +0000032995 00000 n +0000033112 00000 n +0000242764 00000 n +0000040829 00000 n +0000034883 00000 n +0000033340 00000 n +0000040772 00000 n +0000115146 00000 n +0000112846 00000 n +0000110012 00000 n +0000106020 00000 n +0000100456 00000 n +0000072029 00000 n +0000077679 00000 n +0000080501 00000 n +0000080330 00000 n +0000083177 00000 n +0000088993 00000 n +0000092039 00000 n +0000069026 00000 n +0000066051 00000 n +0000109841 00000 n +0000062814 00000 n +0000112675 00000 n +0000103232 00000 n +0000100285 00000 n +0000103061 00000 n +0000069196 00000 n +0000074731 00000 n +0000083348 00000 n +0000089164 00000 n +0000071859 00000 n +0000074901 00000 n +0000086130 00000 n +0000091868 00000 n +0000000399 00000 f +0000041881 00000 n +0000000401 00000 f +0000042073 00000 n +0000000403 00000 f +0000042265 00000 n +0000000405 00000 f +0000042456 00000 n +0000000407 00000 f +0000042648 00000 n +0000000409 00000 f +0000042840 00000 n +0000000411 00000 f +0000043032 00000 n +0000000413 00000 f +0000043224 00000 n +0000000415 00000 f +0000043415 00000 n +0000000417 00000 f +0000043607 00000 n +0000000419 00000 f +0000043799 00000 n +0000000421 00000 f +0000043991 00000 n +0000000423 00000 f +0000044182 00000 n +0000000425 00000 f +0000044374 00000 n +0000000427 00000 f +0000044566 00000 n +0000000429 00000 f +0000044758 00000 n +0000000451 00000 f +0000046866 00000 n +0000046034 00000 n +0000041629 00000 n +0000040927 00000 n +0000044950 00000 n +0000045124 00000 n +0000045181 00000 n +0000045238 00000 n +0000045295 00000 n +0000045352 00000 n +0000045409 00000 n +0000045465 00000 n +0000045522 00000 n +0000045579 00000 n +0000045636 00000 n +0000045693 00000 n +0000045750 00000 n +0000045807 00000 n +0000045864 00000 n +0000045921 00000 n +0000045977 00000 n +0000000453 00000 f +0000047057 00000 n +0000000455 00000 f +0000047249 00000 n +0000000457 00000 f +0000047441 00000 n +0000000000 00000 f +0000047633 00000 n +0000048165 00000 n +0000046702 00000 n +0000046132 00000 n +0000047825 00000 n +0000047882 00000 n +0000047939 00000 n +0000047995 00000 n +0000048051 00000 n +0000048108 00000 n +0000049099 00000 n +0000049257 00000 n +0000049411 00000 n +0000049569 00000 n +0000049723 00000 n +0000049873 00000 n +0000050195 00000 n +0000048927 00000 n +0000048263 00000 n +0000050026 00000 n +0000054231 00000 n +0000106191 00000 n +0000115317 00000 n +0000052001 00000 n +0000052194 00000 n +0000052387 00000 n +0000052580 00000 n +0000052772 00000 n +0000052963 00000 n +0000053156 00000 n +0000053348 00000 n +0000053541 00000 n +0000053733 00000 n +0000053926 00000 n +0000055873 00000 n +0000054404 00000 n +0000051789 00000 n +0000050306 00000 n +0000054118 00000 n +0000054348 00000 n +0000242470 00000 n +0000240798 00000 n +0000056064 00000 n +0000056257 00000 n +0000056450 00000 n +0000056642 00000 n +0000056835 00000 n +0000057028 00000 n +0000057219 00000 n +0000057411 00000 n +0000057604 00000 n +0000057796 00000 n +0000057989 00000 n +0000058181 00000 n +0000058374 00000 n +0000058567 00000 n +0000061704 00000 n +0000058817 00000 n +0000055629 00000 n +0000054554 00000 n +0000058760 00000 n +0000242881 00000 n +0000097677 00000 n +0000097335 00000 n +0000061896 00000 n +0000062089 00000 n +0000062282 00000 n +0000062871 00000 n +0000061548 00000 n +0000058941 00000 n +0000062475 00000 n +0000241774 00000 n +0000062757 00000 n +0000095147 00000 n +0000094976 00000 n +0000097506 00000 n +0000065329 00000 n +0000065522 00000 n +0000065688 00000 n +0000066221 00000 n +0000065181 00000 n +0000063034 00000 n +0000065881 00000 n +0000065994 00000 n +0000066164 00000 n +0000068803 00000 n +0000069365 00000 n +0000068671 00000 n +0000066371 00000 n +0000068969 00000 n +0000069139 00000 n +0000069308 00000 n +0000071472 00000 n +0000071638 00000 n +0000072142 00000 n +0000071332 00000 n +0000069528 00000 n +0000071802 00000 n +0000071972 00000 n +0000074451 00000 n +0000075014 00000 n +0000074319 00000 n +0000072305 00000 n +0000074617 00000 n +0000074674 00000 n +0000074844 00000 n +0000077234 00000 n +0000077400 00000 n +0000077850 00000 n +0000077094 00000 n +0000075177 00000 n +0000077566 00000 n +0000077623 00000 n +0000077793 00000 n +0000242998 00000 n +0000079943 00000 n +0000080109 00000 n +0000080615 00000 n +0000079803 00000 n +0000078013 00000 n +0000080273 00000 n +0000080444 00000 n +0000082897 00000 n +0000083462 00000 n +0000082765 00000 n +0000080778 00000 n +0000083063 00000 n +0000083120 00000 n +0000083291 00000 n +0000085685 00000 n +0000085851 00000 n +0000086301 00000 n +0000085545 00000 n +0000083625 00000 n +0000086017 00000 n +0000086074 00000 n +0000086244 00000 n +0000088606 00000 n +0000088772 00000 n +0000089278 00000 n +0000088466 00000 n +0000086464 00000 n +0000088936 00000 n +0000089107 00000 n +0000091588 00000 n +0000092153 00000 n +0000091456 00000 n +0000089441 00000 n +0000091754 00000 n +0000091811 00000 n +0000091982 00000 n +0000094697 00000 n +0000095260 00000 n +0000094565 00000 n +0000092316 00000 n +0000094863 00000 n +0000094920 00000 n +0000095090 00000 n +0000243115 00000 n +0000097791 00000 n +0000097109 00000 n +0000095423 00000 n +0000097221 00000 n +0000097278 00000 n +0000097449 00000 n +0000097620 00000 n +0000100006 00000 n +0000100570 00000 n +0000099874 00000 n +0000097954 00000 n +0000100171 00000 n +0000100228 00000 n +0000100399 00000 n +0000102781 00000 n +0000103346 00000 n +0000102649 00000 n +0000100733 00000 n +0000102947 00000 n +0000103004 00000 n +0000103175 00000 n +0000105740 00000 n +0000108653 00000 n +0000106301 00000 n +0000105608 00000 n +0000103509 00000 n +0000105906 00000 n +0000105963 00000 n +0000106134 00000 n +0000108845 00000 n +0000109038 00000 n +0000109231 00000 n +0000109422 00000 n +0000110126 00000 n +0000108489 00000 n +0000106464 00000 n +0000109615 00000 n +0000109672 00000 n +0000109955 00000 n +0000112396 00000 n +0000112960 00000 n +0000112264 00000 n +0000110289 00000 n +0000112561 00000 n +0000112618 00000 n +0000112789 00000 n +0000243232 00000 n +0000114866 00000 n +0000115488 00000 n +0000114734 00000 n +0000113110 00000 n +0000115032 00000 n +0000115089 00000 n +0000115260 00000 n +0000239481 00000 n +0000115638 00000 n +0000115961 00000 n +0000115986 00000 n +0000116461 00000 n +0000117073 00000 n +0000117099 00000 n +0000117412 00000 n +0000117523 00000 n +0000117618 00000 n +0000117979 00000 n +0000118004 00000 n +0000118351 00000 n +0000118535 00000 n +0000118906 00000 n +0000119568 00000 n +0000119892 00000 n +0000120195 00000 n +0000120735 00000 n +0000122499 00000 n +0000122732 00000 n +0000125260 00000 n +0000125496 00000 n +0000127821 00000 n +0000128050 00000 n +0000129970 00000 n +0000130203 00000 n +0000132711 00000 n +0000132958 00000 n +0000134482 00000 n +0000134734 00000 n +0000135998 00000 n +0000136227 00000 n +0000137496 00000 n +0000137726 00000 n +0000151595 00000 n +0000151990 00000 n +0000160014 00000 n +0000160352 00000 n +0000171728 00000 n +0000172110 00000 n +0000178885 00000 n +0000179160 00000 n +0000186548 00000 n +0000186829 00000 n +0000192223 00000 n +0000192519 00000 n +0000206190 00000 n +0000206568 00000 n +0000225983 00000 n +0000226563 00000 n +0000239124 00000 n +0000243317 00000 n +0000243419 00000 n +0000248420 00000 n +0000248600 00000 n +0000249046 00000 n +0000249560 00000 n +0000250074 00000 n +0000250588 00000 n +0000251102 00000 n +0000251548 00000 n +0000251743 00000 n +0000251913 00000 n +0000252082 00000 n +0000252252 00000 n +0000252417 00000 n +0000252635 00000 n +0000252941 00000 n +0000253247 00000 n +0000253553 00000 n +0000253776 00000 n +0000253973 00000 n +0000254203 00000 n +0000254490 00000 n +0000254777 00000 n +0000255067 00000 n +0000255352 00000 n +0000255629 00000 n +0000255877 00000 n +0000256071 00000 n +0000256264 00000 n +0000256458 00000 n +0000256651 00000 n +0000256840 00000 n +0000257034 00000 n +0000257188 00000 n +0000257305 00000 n +0000257417 00000 n +0000257544 00000 n +0000257669 00000 n +0000257746 00000 n +0000257863 00000 n +0000257901 00000 n +0000258111 00000 n +trailer +<< /Size 766 +/Root 764 0 R +/Info 765 0 R +/ID [<07BF1BFF8396560A3D29CED1E32BB73D> <07BF1BFF8396560A3D29CED1E32BB73D>] >> +startxref +258442 +%%EOF diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/docs/isa-l_open_src_2.13.pdf b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/docs/isa-l_open_src_2.13.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7ae862f99f63a7930c99db5ea893828ab796bc28 GIT binary patch literal 270361 zcma&NV|XS_*DjpN#I|uI6Wg|J+qOBG*tTsunb@|iiESre?)!cAx8J>=``GW(KkDf2 zI;*a$yH>4pt+T3$<%C42>1mjuh^OZVmZ2B`bO2ie3n(rwC|V_VJ7WN?tbv81lQk5r z41k`F4vJR9+`-Waz{bE1MJr`&W9noEpr>bK0{ngaRcqyB>;Rw@vC?-k7BV)pH8O_c z;em2=axm7nhH_h-NS3x;6F~^Nd_i@TqIsA+V?_WVJ82?AXyC)W`x8!89{Ow5fw)!r z!+T3VKanh!BK620oOWq_Bh~aElYpE=FsmY$Z#`{iK>=(Bx^a=SuM)QkWl7N zB&q%lOOz0qo-|irh-8iuZr&e?e0E5642DElH!)0+5YQ?rD|H-)t3xRa_8w-eUhxMJ zG3}S`KMCZ0nFMg%*EQ(Galsu4fm~;Q+2+WY)D8wM$0I&(*y;YUXUCBu)E46+$Zo=oTf=dM*ng4P#BuJD!!PR)ylGbCVVR!&7-v2h@=T8)|zg-UL)NdmNuv5B>p%%J_+Yp$A41i9Z3(3`D(vT@@ zl6Nyh2Nj?7hyV^w+l7Fot1STupZFEtnU=%i)lVLR-pBv~C6cgxG=crQv+y+g;PTMP zTdfC`ted0h?b^Xs%n?Z@gn*!V7#pdZ%?UR;G^+tkYyu(v15U+9*-1RWeR5iz& zwiVTASG~h!wjjxQ=Lr6Zxdz(&fR0TU?KkeT%6GL%?!*w)Kr0=zq~I&9@Vjj2l`^)U z>kl8At?#NkDGUC~6JF5czoD?>wwU{w=P#Wzlfauk6lh~!Gvm+Mww38Gvc1J~aobWqsFuI@Du*GP-M$v<*ey3RHbge1RK zvZWEWmL~7C`0nY`j?E$66?7{FXK@}hML7qM4%7~SZ^Ic{VoEhFY{nWr?mrtZ3E~>B z!}7_1*L1MZ;A3Y0wqL1tJO*rRue)zwoKE?fv$FZ%wHWJG+2K_s-wZFWEFd!KVBMy# zlE5Z(iaPES1YS8)51WY5-(4tO+^M9YzO5Yi-;S-84K3OI;P10M7JODy_l$jkUm3w0 z6dbWUe{g*6T>kS`&KY$MB1^=}wdTd9&`Js&P1!?G% zHtjvmH{l^xv>mW2PWHnW*wVlQvVbqF)Cz0%L0!(z!7I0|pWqM&|$K-u~sj7+G2V%XgX)Y=pV%Z6PL;?!Z11lB|k{a}e zA$1@ckj~)-MV5=x3MSE_BG6h|Ko1cq*>YvU3|%#+=P-mxS4>Vqu;FV0kVonw+vw%U zP%X}jU^&iX&I4$X9Yp#e>SLG@R-9MRN|oUsk|CkelM&#lug%}oL>m<7%V*}Lm?M)E z{~jSMzVj%Sxosy4C*j0BDN{@eULvv7m`c`#sBH*Pho#>W(%9US6Q`Zi>|N+OjyG?2 zx?bMlYDeW(Q^-yanW4L!$^LQtGe1-=2tVs*NOM0$k(WmW3jg`YhS7VfEdJrfW4Xa$ zbiP@bMM(P;1#M=1ooCeN=6qNL;E~gR&1s&%wXZibdAF1Q6gIFj9=#K9vD?&=!%uE- z0tsoUvWnP2===u=lAtqqJ4Q~Br1_Gg$AY6=0yTJtoZZkPta5)f?LQ49<9{2-|KcgN zFQPIwbb_K)bT)AMo4G`69lm($ukvpMJru2+lCT=h7e^V(=vx~D$Y^NIZJdm)beRlw zzqpOY&d7xPUl=)kQ)3xtYlAN?`(Mq(ZA@&1%nh9Yj7)T2Kdt~pD!6h#tds!@j4u4l=UTYCt!jO{yzF`C|o^4GumGeld?rc6pyZM^1SuL z9qh!PxC-M0*IO^0ow{9bDt*m9wA&>ek3@UHT{M=|9+U)+SmEwZKT8u!Mg(opw66ri z$r}M9h8H=Ok$GrLhU(=z&ie|6WqKBaVNtli>we>(`K<;+`g(a9khU2+ zGtA(Mp-F-&1M=)<=Y>>^3VA4qGeVo!-W+5cdTD5qRmdo1< z21r(RZ@|!?%e6T>+j+TIIi^o(c}_2G7*tj!SG9W9ez5ZW>BMf-$UhhxyN^UEbeFQx zCq+7A!v`BNkFAF#YSF^rWx4Ow3WF3J5)=?ZMBuB~;&iCU=Efce_7{m!N^2LV6-2zg z8(&Ws2%8TR*5zM4J2O8~l;)w8WKpm*EQ6YqO?%w4tSiQ=%|UoF(p3P5Q$MEo8k4jW zKt^#<_!Vqrf9tH`tqMCKF7I*dRYi0<4jKAGciC5BZe>;u{sRq`MujDV@dq{JgXt> z)(SGQ#5<;ah9fhR*axQnO>gO86>WsZKnbs`iZHf*Lh5rUY!Aye9&(%8&QfiC>e@}z z(>pP_R1qr#YWp<9(B^pv_s1(2w)SxhMQ}?Y4~g`WU%)0mA+(n5^B@XVL-~3{eh+saH5v5%tzJnm z>Ew|Kj7TZA4#CeSEMfQ;1&1hHeJdDN(c+a3V5~&)7W2>2#sSQkUgPp*Qv*c8Fo^R( z7bhR%BKEZv)*U5nm>gpmymiZzWnl3hFPB5m?Z`dk_@gz|# zQoA9`cTzQEibsyb#=RqId>*fYQ8P`)nitf3kXOv)9uumGfLVK$TfOCOBD*BCzR7rc zP7^sLh<(+dHi=r&AI1r*cE{cO^jb$KIw{^i#9HL?&*?qWTdm2Ik{{<)53&ZQ+}Mc| zD|_ox^$*Xr>lmax56%!yo|iEYm}YWmN7WxY^j?sR6+eJq7YDJdfrr34&;@zXU-l?j2NN7jNRE$% zxve8~7bfkrMRZl1PB%X4;oJ(7FkW^WID+Cs^cymu9bn%6>{1;Uof`bq7w&ye$ETcr zSMcdB;>BSPRepVp&uI$~XkGCY2+;gZKgPDd8;gTdSI+%_GJ4B?6XebHiPi%rZPJ_y!C@NqU`&&lJd=C;fF9p1B%#bvwWqh0>%M7|xhJWg^#I4Lx#DRU;10Qc< zGJTxs?kAmbiBYAei*@^enSqr2(mhobb!9PMW;H8P%Lf?0K4uDs2iWzX*VOnAmObyP z7}FwN4c8{dtYc*vx-Iyi z6Q+NN3h3Fsy!?Nd)D)`8JLZeP{G6)RyC`glN9g`_-uX-y+RD)c-Eu6w1|Gpm&ke)V zJyForIV)j_Jmkul$#Y&+kl49EO0AQ=T5n?Us9L1|Q2D{f82Qod$c4e}%GS_;HNPb% zTyyGk{*j`!vFU4O6v4GN7e_jA-WFsY$z;pM0G5@v(SI%A?K8CPD!d$sAqLiqTFro}YWKM-okbmf=ZwmgPxTP`uvk z2KVgyfEV5qX?3(dgEE>po#&oG-A(*5V8)AokLu3f9Y<@9;>j8llpb712!+t=Nc{!2 z2yW7okpU-qt~DdD2gGG{lJD~=br2xqfp(@%L(e8L9f^Y|$N-y{bqXwnIp?zdHk)NN z=;-pJXKGuIa-G>k)hmkl>8cxjO=RbtDbyW5`f&z>OKQ^~Uuy3x<=8hL8|ICbSB+#t z@wd|`eNkT>?X}*0DEPEOlW5b2pcIr0mHAN1Jr5Lc5&E4gLq|@y>PLc*c3M@NO`!|U z(67`Uu@|F+>mfTd0}8n}wtb3l^qy+|ewo4B5zvR_#tqhcag5h``zM6CIJFwlVh6s` zKZt`@{5LY;Ls`asK@fBAm%G&Mq1dkwVmvgg@6dUllm0gWz(f1%f;njXjnDa=sX_@CxpMInJa?2qbeHyIjn`w$cXR6erN>!+<$GW-=OB znD%&(C|a=S3}*g^Q6@c*H+{$}%{7JLPmOPdRUfJR!sr^NdB8HEE^jWW4WOq(kE$~R zzz}09D0)n1r)_u2(w*HV+S{Wu_0}3Z;Xz8)!iM$e>L0=8tLm!<$|I`{>(fTMs_BA@ zasH8JbsSr+=NiUa{%JcU)}6@9pwn2i?roKDR!S*+D9=B?d}B)$0eYAvrbjgxzYR5B%U zKuiSghn}A-KVc}iwhnLv?zSvDC}1s2!yJ2c1!vI*QoRA!6~*7ExDI5XmWqD1fCGva zC2stu#-C4!lfi_b$O_}Me9N>(&0a$W3&>}K)6u>A;G~l#Fjbc3H7rWlM0at6oA5a4 zL|m6VD{-1Oya7JBbPCHr>D6#j`@5)$T)BB?<@z&d6sW6@-UssV9wKYSxDKmZD^EN+ zZYBX=PfwI26{ufS>LZv;~`Mu`jkZaN8eA=yb3ou;`SwD`m zlCM~%@2}Q&u+5hhZ9Pe}3+c)v5_Sz^a}LfJZV=Ee6XpLjaGfnOHDfdulikL|lbYGL zT&l;`f48BF#{Oml%J&N&FZz-Q2Kd=vC=4g2_nyeYeXE|`o1R+=^)jAZ6>+HoG!I$= zkE$X)*Iegiy=C%h5OewBUb8Nna^OVv4W;Pu5?y-Y=ity;&27p(j+GlgLom(}HooPdAGfr0o(3!8eA^(AZ*_gg^p#P;h{wpnKV`2M` z)AI8)ZP_(CjKIrh)J`dyxPh&Q{lVmvX%hZMY$joIO8}CzS{%dEqoX|ptc*ZC;c}W5 zF|~tLmgDB*vM-R9FA&Zp=>Gkf(d8VXJ`iFyG+fUgBs-827_WZzl<}Ux`fQRwiLmu| z_UE!8P#`}mW;bU?7poviU50*@{O{ZJM~);DdPg2~5Wt7+V)aK7t$2C9j##qwWS(UB zW@x|=eLsN;Kjh%7GNY=c4-pC9ekpGAA4y7#^?dBLdz4MhIjN_plP=lYT)@q)IOO^i zz5vtQO{MI$;VqnQR6@tzOk_i{?^aS&TFIeH)EITAQ4xu8>`%O5^U!nXWrEA0Uv zxpTGHQK;;r8ckMLZ+bm$Z|Bq?sV9_)e=GDziI{C~#VA18dn2Ho?O-Nqwf*H_&4GR)n^O?p7TKc& zirbPLp|djqI@+E~qhNy2tEt462*J)JT|D^i7GT%Xn2Dq#S{trt9qUC$BaSnwidloLjg5r@ zFfN++GHsNtfwHCh>BWo^cSkF~eM(q>4;IA9mzVigU6Gbxg($z1*DpbvdZZufCS!M4 zaGRbe7*nK@m-F(oX!NxJRW> z0?Fz~nmvr;B#xhAZpb_S_9vu&`r*TB3gb)5h z0gI5twAz}s{bjvL(wL@qt-S<2u$R8bCTI<{BN1Vn-z1%3M@p!4ih8R+5UjL|fMpoM z=uV99F>*1fhA(pg=z-PHOIpvMCoymUY7<*%c#YZ5SBWFNDWdo7Meb0T_3|-58mxW;dyhlnG&>GS=MN?h)gbLhSi2B9WpCA& z#L4Kh)yN*^Q29f)py-#h0#Rd2%LAHtDAOneal}n8QXar*y4TFeJiH6dNKi&`my0wb zDkR@7>y&thokax17<@1$gkonk{0L?jfHYJfBmq~8rhyF>!Yy5h8$Wh9M!w zHeU-CD)jxk$*RNcBJ?>#Vvl$mkU>c?_je9Ja0ZZr9v}E0jBiK3GGNr$-xB+@H|@|D z0IXIp9Dlgug=M|;z>Yk&A0SjSPFoav7|3j3k3vn=fwxBbfzcfa^VpEsL;<8lqc945 z2>yTpy%JFkd-nMW>U{3JjJ=#@Fo!U)97+;mezUW!OgJ@#@(Lc(v>5KZ+J_&siD{oo*{>fu>_C`btDdc3FY1}o$A#dXBeWBX1QMU_z&JVc*w6;nRz{>yJPj;cfB(^CuNbT^byAT0F=88j*@bVFDS!18 z%vd-N4)?LWEu}bljq^6bKhhK9e_|7e2wpF`;s}Q(y>eu;BJBTc-iEtyMVm9~Yd*r- ziMC~ooIqV#BvYcpYS1x0tMV@B#8OkV;O(%wY_Qmndz-7z(2>q`+Vn$Ij!)56hO58q;( z%vn)hsdIZ#*sW~^n<cb$2zcK9=C%*v{fN6lEu zk4unKNM7CYCvcfL+Tq%58>*2qQUM->bG=yY7xggz5u?Tmv<&AaXQ!q}G*pZ8sxrzdr>1)uys-H4n;Qe> zQn?I9qxc`2<5h>~b5o{kEyqS$(h{AfFo7gpYde=YfU)N|$xHI*z2cK|d(a~P-QvDS zfvtqih0kPNALJg0%lvtgkYfu5_O8-qcx;HKbsh`kz*Pe}2>EgJ61BIRx&6;=gx1|2 zW*`2-BA7V%=rM_m-U`pxJT`J(4r*(oO9NMq%x@=5K2gRr@M+`w{=2~| z21+yxNgT8vnm8!7cDaE(hl?|XiqbL^nINS^E2jXzh$vnm(RNSIc}^W|m2Rrd$l_00 z7grYt=mDFbd|`XLhxy+>Y_*ja-rDk>p04x9P2&4joarf&_u%IY7^);%1})@A%TGM8 zrSOlZvdgYN^SWT&r}8?tFORN;{X}2IuFN_$t}^1g?0rI=anm`9IGUW#PL`MKOZL=; zn6s*{y&?}SxpeoQv8I;XItOq6>lV62yWCzN7VW%S?jSU?PRX@EHzU%t{kbC)wIZq0ieRRG>w5^1hceQsPC8^p%IRua{)~;2=QEl(M5P<_9*J zAs+#8WHTfte2I&esXNBRD{{nRF>f~k+f+!Pxdw}gOURn@ z|9yxEtkaHr<~I_++CVr+Fx`XxPz!Ay{E7pOvfsyBYGJ+z7%UrT{`iWTa$VBVX>2ip(!? zbZwKtpbX$<5#d4&z1AvDXJj~efa?;W>4i(5mexp8tL-ruiGk6N%3IX}7yGE@Zl1do zw(}dkPeErI0~ngbI0kp|>l#InvgOy|LO~pb0m42eoFkh$vEoZQ`2L4!1<&&KwVwP{ zP1&$18j{rhTFmj)%t8!6jpqTOz~vbxgsHu)`g{G0CJQ|8&G7|!D#%fSY^<0LeQa;z zbtU4UyQv!hOc6_bGO9RhqXYK{Gfx2 zGI-CO-AikHs83!(?($gGx~oT8S8md7eNfsh zR>1|3coVU7sZeiMz`;Isz?iYku{;(Zt^u#m`Y$$I_9pEqfHm7vDp9QrZb@FysE)k4)EySleYwo$H--kGM(}-4(s(qZNFW(16nzT?Bfx5|}gVur?Oj^`9&I;g4u^zu| zGzbn*8Jn~>)Men@q(rH<1zos)&$5U1<{qSxSQ6t?su{n$*|?LLTj&q-i7@29gw@HW zwep}U=dBq;?l(krEi>2`ab|{9+OaFr{n(u=K@T)NsqIu9e9|I%NpT6Hz#Y?J`=Y=H8_wJWt=MHQ(UsuMkl zwT}f9rH>)cMF4f81lG5(uY>A{>D&>l@L;Wuq>FAWuW6K@%m~m_A$m-4_jUGwAX| z6J0_1bM?)Nd5mJ$^wzy8?V#RazF-pGgZqpOEFX6grSD!B#`>(Rzm$7fEiiJ=xYkwG zNqG)-xN4=Yh)_xOcwYjyN;>{`^hHXv8SrlKC{D>h1=;z7AP5h_@S=~IVL%Su_v%C5 zhEJdjB=OIGnBjjfss3LI03$2?e?G&NMr?ZN5IPPi4^nW>Jant5!$*C~Vz32DBw!*z z65^a*UuDEt6`U2}OB53Omhq-;$2~_4Yk!D| zh;nn?%wy{VGW}8YGK!NZ#T--mNlp72IHiV0m~e&8RHJ=ov#_QR4ZyWg2JkFcBdhW` z#(uGSo1FyuTcJu9!8mZ?&$n#$Y+NitCD>ym(?w0{rmrn5Ri2^IDz36BIt-L1;?=N@ zPRy00LA^N%w9HfKjGHz?F4+&4t(=&!Q;yXvQA>q5(G)?>MBoyVUBW+cp!W{Wa?8(} z;Do5md%y-bo;3a>Q8OSAbSMv&CObA30I~5HU|=ejPYJeGGrdfCh{Cm7>>}JnPlMp+ z{#djYC#$AJ%tbDPP9U^xI0|4`LrX7f(P&Sm5ser!oA8WfTTR`hUqd|Koc0YNgtS<9ZXK z&ysGB=;pjA@*B{I%S{eZ+)0G#nOK?(r%PH-EE}#No;$I7(n1$c+cGFT7ky~PLukLj zx3fd|Hi!;z+B+K>fmhgGwf*ckI2%s^l;ltS{>cuR?<2ElKJk2 zZ3j`PKid>{Y7sx7;$`Oz&(qfX`_23N!np;maVxC~@5bkLr7;eQ`AMaIWdzc0TbnL% z?&rmW18VTc1nPB{_wD)l{y7EgyU)&Oc=>DirxrvE$6Y|Oa8`tT-8$tXI{r_n4yYsE zoEqT^Zmg<~?_<)g zIQ%VSkC(3Zd_G&Q`}WmqGs9-^?%tV3I*2F?aV^G2z9RgHlB=<3L-ISSF7%Oiau4?+ zw|`pZ?iiicuI-5hbnm6u?=}RhA6|cZ0|YjrJc!?ZS}seNC|V2iZty=^RJ0`pYrfb- zTZhi~*f_Y@DcX80@Kzd~fR{U`8GU5(X#U~>y$_(%VLpj8N|)j|5mpzO{qdZ883nFA zqjxJ*e;`N1CXlM{YDH#GM$ePQWKK z9bY#iwX5-#^OB7r*VYh3Mm3XWV0ePek1pT}SY4A(oB7bs@E_tWf}%cE0GzTT*#bF-)eUVCG1X(=*c2F`8YaU~n$U*6p?~mXoRa zc=44q&R)c_cDZnSM6bJ*R}hTzM>Y)JTHlq2F9AWySPs zeoc1P`il+i&;|X=__#fQZ{0LV21%F91rxSZIT0twQTH_krDbCH!)$v3-DrlyPrzDz z<3Hd89?yJ>$hCLC3G+->Yfhu2g(;mlV>o>$S$&@k6{Rq$KP^B{nT#5yzN!^v)XE< zSVHL(onty0CKlvW45Tef+M5%A44zi~h;ZbE+Y^yDb*uxFq*+;huf62t>37k)?!Z*6 zxf~Anor9S8%_^1br}B`l1M`;qM}J2uFJ*W{kb6GutlA5=a_j{s zW?BYNXd=SeT`@r;S~D-lNFdyu`BO_oPX@9&Hql^F;8QnRxB|URALJz}s#!oXX8&3! zC9ifC&aGO`*`3n7)G|M74Wjh~GukUkCI|#m95*b|jrPcxhc@mQvf~n0<3=Y~c|2Zk zEJ9d4ACcM=_H`$MhC2CVidf%a_T^Up~c}k znBJFI*~@VTS!>G7JDux+Z{~kv>QDb-+7F-5Bh(lk9mH6l0&5A;AvIYT2cWK3#@pH~ zZRI+>4mFEVowCLY$4N7=^m`mfm>d4ZYVK!JJBBAef2 zjpw~J)dpqeiU2LThOG7&VCB6g1mmL(6$fnN^-VnyRGs8QsAQax31p6qYm4fPXchpQ zJ0Idlw7 zINHek<~1vEEDLpHy`EfcY{x%Fg99yLJii+HrBKW-ObARo$R>dwExg_g7^k#s)unpY zM9?H1)J7!<#kWSR?+GM7R}Cb@O~KDkL1qdU6_(toeybFPAq2eJS;+M{PlBH#QGkzD zz|~n(BT`eyHfUIVQ4(4O(?8Kme|L-tA@?bNJehXPtHKwThvFDvLj7YWM7y9$XJw57 zE{=}Z=fpsdjyuEplQNLFwiGwJ11#}@SikRWeUvc2GVCCQO}S5IL&-dO4}_JbdVqrF z=i#M9#a*HM@Ys73xX6t&X$ICyhBv6b;IyP^vlf~7d7r-Mbc^c+xCoPM z4;=ISf?wVVfzRfWX|;4+Gw~xUmUOK<;p677wQ@n>E=!imE26wHUCx$fYRByg%hX^$ zCF?dA=#xe_#n*eWH0G8q2PX53(VaFa&kzh_?Q*ttmD8QpfO%4vOaYNZw6OC+e+p5y zgOo07vBGQd;Ui}HLeQ(h8yD12Q&HE0_CAA_WZv_t4i3p)m|o_|nS@ps;5m`yM6ky3 zk}RhsX$4sh5TXOT<8o&G@IW)>)5QhRxroQ{4KkL-+gKFmNL9Y@-Q4cvC88s8~N zrl9**kv={wmYcQfsU)plF1!y^V+nQy{6l!f@(FF#8UwZnH zJeUfMuy{g39z0}>bp5$Yb8UFhG8L41o}q#Bb(|87&(;ogtQM*840vDPn%%*8s^HEx zO?S^e@Q;jsaXh_*KTL&Jvh{f(-@lDjQ)%ncOfH4TKhi1Z#UWu;H1o>p4Wa9HZrU;aQJYk^Q7@*qyuUBX9u@)1TVVB%+^=?QF29{19zK;J^A zPhktO4#A`lN1Wf-9aF_&qWk3cqz>QiIXmgr{q|{Hqw&T98ELdS??dxk0kexjOis-6 zN+oKZDq9y#pH(0WmHZJq|8306j~I?HE}tQHaYcFSig={gb2CD@Eh3HxuGvtRlIKnV zUVK?u*5#)vH6+|+vOO9@n^SePiXVJ_gJ%D-Xqc;wx|AWqsY8Y9Vp)c3qoGUQ9{1(o zB1f=}(g1#lXN_qJ4Gn-XP1?X1IVAbs=admiJxh0IYq!?F}e5x^zeQCehjgyvv zg+##*v0ieJ=6<$zBW`3Ynhu|=!mLt|dXceQzQ{(_3S1^Fc*!(hd^@jh2VA`1E!kE(`&P>Y1EcJ|@$r((G zMR7bJ(TU_~EL9!@tD150obCF8pA4(vxh4v5y>R#~tGL|4itw5pdtnO}C@>S>7nb=P z@Y0tUS~(;khy*0CK57j))PSXGD;A{o$JngOrN_=j7X!dV1oB{2ZD#8~!7;w~OrG5_ z66$#hb>plPqao52wf5NgK|~aV9Q9r3Mqxt|0Ryw+o5~wBkdVnqNQ!DL)hZ@@$mb+O z*XXephmmdF?rcUrCHAbuw7PYAMtxuWCK^%E|hRuu!MPW9~YMQ>DEN zbn`{sRi0j)egqk1ZvFIAru6-IBvenc)wEG4wp9L)>%=I?Qgrm1e!$UPq#1%MX~jks z7up@|aLwu!M4wHAZIkUi{kQ!gz#1M$=ak z!4_S%I|1Kj0-U?sZeyDxOB*-e!w-}2+8+@o3ms^pJ_*Tv1e_28oDAGZi0$f(dyn_e zav64hs}>k1IvsdNK=iUa9i`AsDYm#({PrH>s^}0j=@|b;a_n)95I91R)*^_aqiW*! zi<~_o&&0)rv*Clf&QdG8(eh=+eh66`*Q9bPTSb-CCD^vLukDWwhNi3CUi&$CZpLPB z1%W?%p1fzBCdV{vADFA;UB+fXx(#6nw42;L+?*_>)0Hpldl*Bu9P*663}tCgdj$09 z^%8$=Yp^QbEbzXXq}{hlzO$97-z`zo9S?hW!n&`Ahqak?wQ&w-Ug~?%hl@`$ky}0B znIEk#?g~FiFW*grz;4x#Qh{pyB^EBqG$TfExge1`o@1emL{K_yKKDdVwnUC#3jf^) zGJk1)|0V=7v;J$N-hZ%vKTt_BK8+8d^Oo`e0(>x4-{e;x-fq%`#X_3U%AcA>aFqGd zU40<>gQa5oX|~0xomu#o(~p;LAl3-{vS{p*Qd}p`A$n8ET7C(H5M*WB_oUSavWs+e zV1|f*6GIVD(HSiJ3w>IM7!+Vfa=C;Y*4OLjv1T(SSFHnZ7RSwea);6YAOimDS|cs+ zC|%R&nLnpeq8}I&=;($IFAN}U-!=1xUyS7eG6=#vg0rW?pk|4hwwEBp+u1H&eL%P} z^6a||K&iQb_wQxqBpi*%hb96-><=wQ+Ke$80XRqW($V@SEeQw)(T@XV^2XoRF%X>D zYUf6C=c{NZS9o+EI+2eZ7kW}&$@+7R>dN^M8iEC7PmtmX<>8QB%HzB<_(}NBoOLS} zO|%L%R*uAip*X1GjOv)Qg)(+K@mGM|LrW~8CH?Z)$RuSd$QG)Zf z@;swvZ}`K9Apy05q1qPUMqqGVjj<(>7B44I8kz%<6fCSbF3PPEr@t#+KE|s&PqYJD zrj#zQ63cnb9gcetdj|(ost0kkBHL^s>@ZY3&82!}AZNaMRR0}W&x9|v=K=1?^*m^t zxHz$GoXu=e8rH&rBSc_=LxG-))JI3@E$+n*3&8VsgnJ!cy+f?nms0@(x_7p2`N3J4doG5RG4-POK4++F7+~HE+D>d-N!*t#9{=A*^;nx0IA=?|Hjx(bg{_&IXli}@}2y-7BT!5s1 zlU~J8a;)7qub;{yep$aUp(2=2Sfcx7PR|9|pP8`sT8ohnIWNtGT=ZY}a@sxMB=e{z zy`wnLoFx2*AUNvw_*5;$CKGcZWCam#5DdXqKR@q?nD@up-Q|KOrB z&h}u#5^!~uk3t;ynt^qbee&{r+c+PhSHFP}nVSxp<`FdXRh`#TddJ6vDcvAwh4lZO{} zpec0EOC)e8x)mkV!l2pTpg{*x@?;FicISjwdoqM;=(wc z&)2DV&g#Hjv?6v#QF3$;^VuvYn$3MIxL3aVD(Y5GoA%PJY@?Fg%P!Qt9~hIZG0O@s zeh2VfG^0IGaA!F9)~*7y*dujFMDDuHeH@9+z!xS%LpErS0jIAUk<@lau0?(fU2zh? zrU8BDYiQfA!?|C1!&h= z)QYg(2w#}czcGYL8=~hNh}SM>(D^lkcl_q_jRGldUN*aV_^U%;DIm9?~Wa&L3WzqbKW8`MQ{vv5@#DX(Dm3A;AG8@xo z@KIr7@n$3?A&vBE7UcVLfs_$nZ;J*6@5wGJd^X35lxnos&7`a`0@PqNrdDWAc3=Cg&JAs)o4WW7LSgmnffB$9CTK4TpjHe_uCVkqF&?M?mQV$7uaA=W8s2 zF@1wE=F=NHd!NpD`m7?{)H-WnzpU4MJbz6Use;?I}xURas=EmJ;tWv|2M3@B5BNU zdfsBtwvZ94sQQQOW?rscy+J;Q26*R^h;sv^95LF&ycNmfP)+H61g9kfc2VIMs4my8 z&7j!h!#Vb{Q4v=fsKTWz-;M*>(y(P-Vbp1`!Qs!BX*{cHQo5A>uz=|JDml6nWb9H| zvqSIctt{A$c?^HEeGLOPlq;o6NqiT<-D+;s>M!=+g4%Ssp`Z+Q7Tm@HhG~C6aG+dm zTJ6o;r5HRgMa}6%T}!6YrvI#B&@?76P~US${d9p97mt z(hEON8dQ)iJL=9Vg4qeV=H;9P`duea8WFHmFM z@B%RAt17b`vp_MZOaMJXzY-J&3R`?mpKqa_)R?cN#gUkvB7Qz!oEHpD+$3<0s48SoA|5Nn1IiG;M&id5md>h2WwN)0g4&&Vl;&s z*aw)90)0J;d_EQlL0%b|gLs}nrc~cz1#O#TUgauL>=&0VBnlRL2j5DaEHTzSEd|E} zCpD8UT~HB6Ws9J1Vmq^31gj0GYEB8NXgGMot|NHs1W5Gv&czJ3;oOA5=yuU0Z;$D* z0neB;l$&lMj!1OBXmZqc>LMuaK7Z6({?fW?rc1q8@+|36;>*^EuT?pkCSUylDMVsB zh_Gq;@zTD5u68+mk+ZRWBo9!Cfwwg%aRWCpG?FV|a{W+$v-N1>?-ZcrA#kgI7r z)SvBdKcCMfv1rl8@Pj6--NfVa*j-5wooW}3pkvEKn0so9cShoCybzOoe!pB(P<27; zuCG_V^V;}$J7Y2{{1JOIetJ0t{m4dC*fGn=wv4J8N|{wFkseAg?Jh8bHlvtf_JbNw zkjW7@`ITT5ZQ&Tdo>z!$Hj7DTAF5VYgQq6ksYaca#iyA14N2UIbHqZvoH9+s z(wT$A6MwG0d~EHy$+X4>lb8H$8+}>#Y7ZTw#p|bcqdPs2kQ&eDg}T}YTYDR9HIG;I zVR?4Yz>VfGHjS;Vp8SBV>m94A>r(oTNyG4-s1I&awd$5u2lU=6ni{xe1iD-2@4=4c z&DEdlVhgZYC!Cdr*O4w;8n%|UYn|4m&E8&nn+KZ`wvEl&I;S@p$x9D6UX~lp^O_gd z7nOG^o|+z(9hDvDHzi~FG||7gPX4cxHm-}Cma#pW=>Oy7MrX79mPXymoqi|rGSYz@ z3;XzvSaYgc#4g3auiV)-A^c!@)Je=5Oe~d<<;`DyPy|~sO$NCblTO~hmKHo8hLt7@ zIP~jX!raaEkfE2+HzLzb)C^e89bMda$kUYStz~t(Uc+d%8yE|AT_(z;^TifjYIF6W z!JD#~d~K?1cyY?$oBO-ol#?t|Bh1UMZ^0qYhL?#CKTN}WjackN>( ziE&c42rhp})k*m|f6@YVy1+SZf~=mPA68*uZdW@z*&lZTa)LX@35xsb=Z3It!Ci)Z;i2Zh>I!1B!M54bv?0KBE;1<=S$H_)t82E#0aZ;uDsPRTK3m&Ctw zzyDY>UW%t4OC9+OXuOa=J_Bc=lLo`>{U47DuoH8Q*w{=rR6jX_(NF$vKMfKi{ve&E zz(XH}Q_GoRGxwj|N_phDagpQ>Mn2h}Ze0+ai$Cw0qR7!Zg%i&KpLU0kBRGhR#r-WC z4{(9NonG_3QaXu}7$88-ckn1=$#5_;*b6V;T$@KlU~qvzy>y$ODqa4FJ3+pI4#(sU zhCWGoT%!kXIz&1vu}ROH3sL9n+|PXGChu$$6Ii48GboX)3rTyTv$!h6%OcMxVjLFz zK}+Tx+9$!HgQ!6=6;RekNlr^3VD_jC5z_mZSRC~VgPeqptKUZ8y~Tgm(Ui1tu?&EX=WFnPi9I2-XY@Aj5)apa zrTKfIc}yldgg#V;FMubw0N}iBDPXXW8<^o{4oqxlqRfjI#yRhMBGP6$Z?6^rna|B; z2A5?v{ydR(b3KxiIaE479|VlE2wmJ-bq@EH!J(mJD;}N2dp1-byBQJY(bqfEQ8UdP0F6KEMMY zb+KRp)#pJgF_vD{SQF+c-B~xEK@M|-50kSi+u^j`D>Tw=oSSie-B+;m>-NfRw;Frn ztf9%ugj70pXOvF>O^(dqn{@>yRe{Yu0?_EJ_?&({#IJU5U%pMe=7QeGMYLT({5@Veotn8!xtCUoC(Z{-jD0YmIJa$w}$3YU%Ys-6LtZbz>_%Keop?ECB7Y zE5Dd5V7p4W^5qHQDoT}HtBJY42!Aa+?wp`HTsvW>fKmD-9j5pVrD6=`?mB5bx{_aP zIQ$?k`w4Nxchkh56XQlTmpkoOY_ODsiri(;FiaFbnM!#d&sXg5103q)!yMR^^&I~Q ziB_Fg<7Jq3Ys_-hcC~u9ru$4y=gGgybzW7vdUecyrWZHp>)bq>C(czP=BtoO)rqC+ zgj4iFDZ62mywHp8sYTEJdBGdK=#g3!pc=7Wh19H0Y*i<`s25uPUE_aWC~Z`G!N$|8 z8@Pp`tXrp>Yp^E*ShUY6bVf&i?Qcg%`|osP^Ks7CT(etlp{*g{N}Fzk@iuLRK^8fa zoAaz6HYo}E@)|HzcOQ$mjKGr%ue)M_8&A~ z1JnQ(bc@DK=gl=*#mzSJ2s~fYF%rZx>wT(X}pj(1nW8RX$pMe+2hhOdbs_YPL|mnTfn~!4dFWU1W5Nk z5t-FmMgIAw&BpN`7+!Xcee<3&(h-U1pHHyJ(jg-e)56>n@o^DB*l+O3KBpkY`{@Mk;4H~$E4v%)Kr_AM8`uC z`1VX~r>}M5<~S`{)=IULgrVBvvwf#%lHcY0)SGMzdOxnOc-+b380oA72OZ4@)MmeU zXb9|n+?3Jc&7>nLOx3nATrp#jB~6-xlpwdm>hZd zhoQu28K{S#_`z7z#&muDObF64`^mhP^`>RP&~eLZ50nbgSRQxgp+mPQ)336v@;2n9 z$>7#$)~2jAKDMq$bJllX3N-m1FM__8)a5Y>KE>v|;*1=lMMu6*f|e?xkp>?AezXG4 zI(AE9;bj$&Ke~v_JZ2qkGOKfrj6TQ+mQiWM`G`+(VDSvjJ_ho`=G99uZ?hyKRFU3gdi0<>9=%JGiz70lFC85^Vwgl9DFZ?BuvD_-MukrroR?367-cf zf_bM09Fg0>h5rnAb|$WW^2l7w{}0;cjGb?7Gt$V;o%%C!$==JwUEPRXkv2um22nP7 zGrEx=wv`Nr0pRmpS2Cc4jF#Bik|HlB2R|P$vvT4LhRfW)4Q8a|R4AxP-qrvCpDNA+ zX(PPErCP($U&ZL*S&k1nL1tmH$0eeo!!;7Kj2CNWn4i0-*UR^e#jgDj)>K>e*L;s> zIRT^%vk&L~cOn)CFSlKI4R_S~$;#eb_`!3q8%qqK)|7&4K}WILo$no|jRZdU6yq~C zkeo21ff{phQ6TqnCye|w*m?4YF00$sDxhl#UF4v=%LK5yUO&^vdmTbKfF#dEL@%U8s>!>U`lN+$z#`n@`YMln=!yzNzN-Z^w(# z|DzzYFr+(p*g@|KaLZctkNs7==P?_<@SrER^y@ANLJU^PdtmCvkKeKIU0#4xdj6gB4|X$`Ll0S_j%PBbQk zaR1VE)1O|KsrCde2(bK(RB^va-3;BaiSJtSQBnZpS}wVjdUR8;s0#cyjfU>ZF#V|Q zK$clg%@!3)kI+Rd54IFWs8_Glre%M_Jht?}nMBzo{B=M_MoV zf8RngSeix@y1U^QI*M;Xki?b^)Q^D!HN%p6RG1$KTNp579+GIn065-6M&-vQsnWE; zyExg1DejMR&6APC4*er7$HoS98Cp`O!mXcOLb4Ry%AVj(2fk<4;|AQ?B3vj~Ug|fW z0pLUvBZU|3eG;Pt`Pe23=4lE<*-@>b4=Jr(tSOMR(DiGmJu(_jE*PJX zd;y9kDNEceR%PUV1-I#w&7u6wqc{%anj3?hRuNzkU zI`TP>`I9F1FMA3FW*i4G?-iA~A#T74=7h(GB@c}(;!_1E5kj zEGSpEgN6F;FbSAtK6GZGt4zhF+bvH#i0xv|oL|PDKABu-)6v>C>yIS+0y%IKSkt3r zKorrMEbptBV^T+>StlGs5=p_KNgpR;E6>x%`^QM!#)Ny{OQ%G_d@M$W+FSeGV6cQi zc^qL^ZDek5XfBf=y`I6zRGa#echVn73Hk=GObI=;j&t12OAstit+lDcky0Om6F;)0c zy=1~p@*VAQy<~UcJxPTj7c_@e;%_(i&_@kCY-z)vX zk&Eaov4%>G0A!*_rZpgFgFk+fMp&Rxglk0GX9oNjYySB^tz4ftw_PXVm@NiD|89Th zDM$}hI!n5#X%8gHXh@=JX(_8UIqpeXERYOa+$sN=y%i?zETlynqjN1ZvD3mZ+RN6N zyaG2Kl#4Zp$u|x#Y-#&L$=K5LCx@B-7KIE==NhH?S)oDHIL5MrH0txG<~MMWXLE6D za)yvWL+Sw8M`B|-NDX}&1mkSwdL|m#O-4h6 zGF`BmVbSb?&|_?Bq7GsarrcOz`Kg(%0wre!2dTqu_rning3}LjcyO(G?_G+KeOle#9CbA2<;Cr9m=SxC7?@2o}Zu=sA z!TQUW6tC1JamzHmJvc(S9sE9hY)qsKH4`|}mrWLRF>|_O8gqDn)XqctR#*9%`(@=& zdbocBpF&`UmK+~;MP>GIHTwf*A+~-dIOqgLJRWV=0r_6?P!Cc|dTfjSH1QD&>0WX_ z4)aQB^DY8n92ga`FsSNu1{U$Bd>Kc+ubcDR($}XgZELT`-SOqe6d;|j<>~EY=ksVv z-`>vO^Qk4iRUdNl;Cc$+zx{dqsII^8xp(~dRNSrKqo$iI(NT*aav;qQOH!kQCf=*T z|7O$v;ne=|u%+%k0XUhM8Qyrk9Nf5hb?rPqaDAy;N!>Tu2)j?2z*Dt~*K~?4oW?R& z`1<|+e!}tmMO{A%S>@3p<*AyV(XSTLC)LDcm!mZUHLhoSudHQ+gTp+NdFs_fR`Yj{ z#_&NiY_mBk@4>cY`p0dWbuu0!JRGp~b%Qd#Z_30Rbxl;gNI{KR-X!+v%qs@8g>f4T zq>C_Dp)QsWvP#otQQsgIQ?Z(bpp&|Kxn-E4Zgl|LZB--n~h+ihS#j zRe5E%SQT3u0l8(I%9&G>=E{DfEK={^v!sB}YJ2O)cU>)nFz#7%XyA5Pt7u#p+pF|q zxh@AKGFnldGKZSmHJ5#j%!bJu?O#-hy?43g#?W z%)A2&9kyiX#Avm@iLnpIc~wu2EF#s+N>a!wnlTo^T|}wg>a85vR6<&L21n%ELrr=F7Jli0oz8< zKydR+C}KxVO=@qwvWG9qCbLgAD7V=;acQNd&L`U^_pcmP+k0cxltEoe=w`mAaJ8yf z<3t!cv`oxN>q+JNWH(js%2UiC;Iyx;R*P3uSOHHVo#l8}E1euQ(|R695x%JHo;QZN z#{sK*jW=ivE=MUx{)EslhQZauG)bS~w|ny|0A za8yD*)IgpNVnu^4aV54-`zukoMFl6-umYQ7G!KK@enDJxuN#kcEK4K5udKezVY%7S z4yK_;^>Bm#u7zr~n{62wL+$MWoA_`^Z2pH$gfFwraeYSN4)N&Atiy<|f;L3N;W9uKAkOtlIdHoE6`pKx{(v(>-gx z^Nj=wqn1;&#h{GDW(bcLG<*+*Bd>nkpCJYgJ7r7i2}E`3g^fL1ZPWZ#hAwQ%^ z9wq!hU$=1LWOY6A&R`&Aw^5$HZb^o5INRb)vF5GhdRQtrWg2zbJp{BV#!P;2U|oyN zhmE!9fCge?p(RNLR}k~ybQwGC=JFLt5JfG&7*O-r(j3mzeXc#j>$e=$<^Dknh!_d-m)FH95wPtYj4Pr!yKAtV5B}g#}jsZbtzgEuwVjSCu zZWTmlJ<>IqDVp#G7v1}X)A{xIOeqEKK1~1!Kc9brW9v;4eeK^K54P_3-5EUny_|aU zJypl<0Q!0)s9Q~&+IL>DI1n#!$_3&Ql`Tns-kI^&wbglZay}kN9FSY4C<^BX5 zt-S+NBiT<^7|VxSTbNgu{9U#OTRkuJ{tumVU&`NT`DFT(cLiMja{gA-BenzHb-Hcm z{>~Hg_l+oSs8#5ZJ*>F2I94J%j-8P13c#V>qZr6Z)dTM+ivg_4^&t$&>1q*aUKH>r zj@o|A?4(G%=E2eR9{Nw@l>px)I`B^_m$XbpCR|fkCf9KlluwbleAjzXwvmadUxGOq z=Y7TvP#MyDjgzD_Q%G<3hilejz)7W2YcMFNhXs0Z7=Qoxs2>v}^{LS2JlW0(CJ)f! z1RH6^udGf3KWg$XJo0+kuPRNGf2J$8)|)n~4jJ?NQT)&yO9tastrN?Bj? zHT*!qk{z0+>Bp;qvRJezT)`j}0c&9BbcB_o*WVO3(+-}~Y|vd#xMgtIa^f=hFaq&fvBI}xM;FU%22Q{zTDEoHrf!?fY`(Ab#yaB zCUu}dFZJbxp7a)U11x zyEv^c_ON^qjxiE_gcms>8wJ(!m;ue1X`tATZJDqBd4;-2dW>Yeo~2q2Fi;=<3#<;5 ze1%>4Dg+a%k?P@PFXA){_Xi8MSb+(Z- zGbn}~r+6MX+d3q#ksHHVH2JwxRT}8CsvS6N_dV{U`G|mWMOaqrEfshl+IZs(41FZ^w7|aFBAl8t<`;hly&s22t0)+Dlpp{YV+h!|?G%1%AF| zPeE*&#*p@tg*~*{yBA)j*v#hH4We7^;dIHz99{C{%pMM?%bH6=ZiZ5ia0*p{F(zO8 z3w4yA(S{dIDKPq{*BtZXdiU=Ls{bl|o!{d!xKGT>i#Nm&X@WUG1AA^{X5*+SdCeR! zieEFcZYmI&kmnzFk(_>}*=Yj4bpP`9k_oba>IMz6Aio;gBrZL(E(T^IO>vP_ZPq+J*n})_n3I;n5p<`t>umD?jY5$EwTss4E(vpOjF!lbkRvpd|cyv+Hf?F4^NF z+3(|%PuL?+viqCl95U!?V=xYphyUWRK6y|cfrsn6urMh9g+H%ML{doRDT;|D%c^OrW1ufBG|z0WI_5F)oz&&%3WVK339*B4}-V2 zt5_FOBZ2wrEfI3NZ}dF${s=#rtAuPEy3}0ti;Wgu+|$*) zAp%nsE#swQMp;Yua+F)dJ8K3)NTVRk^XtCWI^fzl|Y@p&q+_@(;`!dnOfY_lR^No%@2x>e-2#V zEn(s0!hdq-pxx!?%bsbNKac>no6O{#6mpGf5iqB!=saao*={kCj%76mVBDEwmY=w-F4na9ti!h?S#?lF` z++kHYnore3bW%Y=f6`hJQ!;1;mwyt8O#<928g_@SDi#H?Zgn2T*j~GuJe11rO5EgW zV5>HxR4Xvfg|xG<7XhrN6)`P~c5*nuW}6miskD3_nvFjfX~xIryPFy~a#DT~emq`V zscEzF%_Prlp7Oc#A|&g%ug00{*APxQR$jcOJy}@(Vum_}ugcHzWGKy(s;Li3c$c5Y|vlC?u^pYuDM7C+}Kmn=UXS1;!?$E(h|wS9u&< zv9~s2m;su&Ly6f-LM&R&Zm;@Y%oc38BJA2g?pzPUN0vOpTvg@2BoFpZYEp>PffNkK zJd{y5X)7GyzO{N72D&`IfIYskn1ALXK!?4bXxRd4WSVa`2Hg%76dK(~O9a;N2F)Qv zgF7fhatd=dou{(AUf$(ZK!vnz`buf=LHT0e8m;yUS3q}5QXM}u-_C<$1$6e5Xh zHF*@L#^a`m zP07)#vGdypEtaCc9s;frC_aMm2Q5U525oy2WvDWk)|=1%nHxrzRB*H?B@t7RsDmWz zZVqu7nj|q&I>cALT!SL}f&o#f3y0VA0-i?cKd@lTAUtx>q3DR4{0sv3#B@_^5Nv3`%MO9sabH z#I?xLv9{`zp9~;pih>#Ak(-**(o_y)H=I9}3|C`9#|!f2k(rEl3*ZJ42M$=5rZuUTl+~9_hE~p91jJuU~!$_F+&E~Yxo)@E& zdjs`$#IALV-By3u+Mj^>C76aoX9dz*^~BiwQ`s83NQ(4A@RQAdk4IGS-VnDCG+!Muwi{)n7%0ZcXw{C!HcD#3fd~~mZ1>29m0v3-+4rb6_ zMl6}!JOXdOZb7R{VmAImRI>jEY-M6)`LEUVfD9Su4fbzreMQf>7oJvu+6IfawE8vO zBz0c-i?q0qZ2VZVOh?Iy`{O|ui3onaNOs(A-pdJjXvi2d+CCi?$t4oXi-lwf6;<9d z1nM{u1tw40N^TA!izjP(C&n)$MlVk~)*=Ku6+{k05-P5JSyC!8G|7Tlf-q=Bp!?O; z$%!CNvjh~|FRM%JAVa8A&={*Kqy9sF#*hDZuAk4>YrMYvww&;|5+9Y{IQ3UZ&tR>D=tpp)IGArbZwy|yX+)2X<8;bOxbEqHT$1z=|)ZGeiW$B*? zn8{EhGb+aB7;ue|YFCs62U%!hp$@62E%I)Acyt)lS<_)lam1_;F63q<@5P^%X-f@; zEqT8TLSU}ZIit>YS+z?acRV|welXHanJ+h36*4G@g&5({ludRWNT%Nfe+zs?#bY^Eim}MWOKX%`Wy%+m*+$}== z{*4ebpQls;J>ag%uML>=0KfEeY|q#(YXsbTwGOB=T5QwInzlj9oCh5rVduoD4t&YjZD7U~m~eL3m6P<=IGpSrc-*&@fR zYOG{O{w za<_Y0p?0XYT%y2c?v1J^ol7`lz}$#d1*R#*??gf_F)XLP8_l4)7TDzqONgk74>fG+Ojpbn4h{6Oh`&b8mpIfP>2?4xg08h2)M-kS{uuLN8^!=yS!d6Hykf>Tl11t zqvmG_?^5eagcIDwtAE7kThS#z1e1g;36$GR29ik|){Vo>$(VPuuOf}Q`u;}0CN7E7 zOrO{;@wDRF^>y_tmRjW)WFvNMhL3S!OfsSXFK3Zf{=;5r#O= zmQ%CtWve8L7vaYflCL#Wk%s~E#; zxji$PngjPSCqm1_5Yjp@p4R35F*8AA)T%U2q@@l;P>s>g#ICkU@LetHRLH9M7U{YR z^)9`d6etnFYOQ;m<(6iqd>~DXxm;|brH?^e=n_484%h~pJ@tiY^--;;(9V1=arJQ- zWOATi&CmEzilwGY9ao3cI|`Jlixt*bCo8s67-&6us@h_lv#o4ZO_%|6{Bj&<{O2@8 zYF}$%Qa=)Y!kFA&Tn((g+b~LCt#3UWcbwWm>zDbS^{J-mOELAfgt<}erRo0G)Fx-~ zRP*fwq-r{%7G$%<8piWcFheifB`XI)ZU2F&s~Oug6@eO*LRDo^9SjteFr+WY#dKPF zXb`k)gpJYWd7iM9EHwVBDpuOBktAb$0mHehj{ zPd6xAfuP#c@liP~2%ZH5=~;fcqlO{^iZg6ZUb>L;6g2zbTewgGUhA$vJjri$KE|u&e$f!l25P}xAyz7 z^-c(%JF`y>1Pqa$`{Vmv{KmA6+k^vKktWNzs(CbAeOo(NH3-;bnnEf%=G)e zR}jx?`E+ZInlSjq3%i?3HK*9O#G7>{B-AoU-ChknbsUz`sWrF56<&OpHpF@K!?>`l zbOJBMpq#C&xbT4#=>p+66@Phfj$#5eb3hN)V9Bui_5r3AR!@vC7F5`cluKkA#whU| zL&6E;h2g|^Mm*ix$_PI~so3?=eBX(ZI&E$cwAab!NRtUm`&Gi08W5>HClLX-{%ZGp z@%ZOr{P}bZtoQPEBQ#f^AL#Si`1+Iuvcy_9yD^cBRt%C!+!L+F?7lTg?EG-W$`ugw z20X(ffLuaR2ozFNSwlb0V~Nnuaofm0S6g1p*ma$J`|GWLrd`u8Gm<{ERev|SLqbR^ zo^xKpyEE)ek_DvefdFMsmK8&pFiEEmof{5i$011=wER;1YF~{Re zFe54}u0WivH9h;Kw>k!zrsA$))cUYl9{eGCt=$^36sa@$G>QWCsqO?7Y(DWk&zv@$DS6M6bLNPQ9pYg5De zDl|2wTyu1iFh{SqZGvkG&$G4+O~45{4h&E^EKpBXl^YFEL1mTMRWxecimJ)dc(R7= z1=x9|^SdbY>>~8C>d0Pvl*SmIsvbmuINLdWz>AoYj*iDCr2Bs%$+MaAP zCeC?C?IU|#cV#ZQWpHyzAA=M_PU2bmIrMP8`D;aiK{E;9mqY-Wj9VGq;=q!U!ANwI zp$e2M&Z1l{r}&epr88h-HQXOn*mUH+YWb|3OY|2P_mm?>n*AVb>%~K*iy}eMPlDXr zHp+%Q*;f&l*Wv|2`zkXDbP^u)TmPTL>E%LYp8_6rv;rm+0^Bc-REqgBo}==fF5?GN zDt{@tRVcVS)Co@lu;byfPgw8w;^DaNn!{Q@689K(hRBcq2{)YoAFJYjtzj~;aQydg zmsv9Q8=OcZSD$FSr9{q+z4F6=7Yx@woSq5? z<+bo$7EyI*QXN)1H{Lp@1@PnK#62|XiV$eA`Q7+^4NXEG5kLK=ldjgvCB89d2f7{b zp2$G`8OFjG%2J;uZ3s;t;)Fl5#}crv4PGnHlxEY>m$c@A_V%9iUfUqP8jMEn*>+VW zmtIARU;A3TRwdk4$AwW+D$Yr7c7&8o%*%!6$vF$!ZNLWX_jQmHdzmj^AL z`SphS20sSK!?ta@v+C4kI$G<3gHNSIQo%Nncl&RWf1ACZXoy5wLx9&hdYNc6n3%6S z(di^Yoa>`1#kS{v~xatx{G#B0mJw$2@R%n0*jA*6*)}vn-)PC*f zDFSX01zjc0GLT^npbFUKsfLt`uw%-u7nT>`zrCzRE6xPE>MR zaZMPrGdIvLoh`*Q%?cVj4hqc5(Oz8p&=a7+z(7gG_aX&qWTV7}6Gz77EN#z<$~Cfdg$ z+IKdle_9DexupKS$_wTuCQ`T$Tfu=Yyc@w45cXE5-RjPXCN9?_T6NWS%=s8fMX>!+6?qvC-ya`8 z&ZXaoYzop^dZDs^p|O9t-}}Ga)uFuJBrkk0RK?X(ky`eS%~S0e>E9zl{Y(v1@e?x` zk{rlnN+QA#?5;qP+O(bW5=ip6sVd7?L6=HXGF|tb;dW8Rm-fgLZ-OfAKwwP4Te?M& z9ubDtV@*T&I?7=Avd!c8NI&=j5}zY-_$OqubN#zi>i;53;pF@`SqdW)+kY)f(b}lp zYC-lD_?D$Sie-y9nQ?y0QZU=-W=#7$ZS#z-(|)yOj-hezNATGWgU_P&t)9~gOl!?DdLdk7Mpqo6A>Lu9gaZoh8#BA9{ULc z{X;_BJed3^$t^-&_9~Bu1M?LYZ{oA~Pr;E`R5_}4$Eedbrh<~gVQhWVp;72oBrK}| zI+Z}kCz&vc*%Ak`14rddW&*e$gYB2LQ_$O{9HP+@Pu6Y)4yI;=={K=$49wzGpDOLL zc*?>fKGeHtF;f+XxTaaF=3>~5hd?Pza^ix6{0c*{OiD`3+!^rsTIgA#*B))b5dykl zH42nrs0Q6ik*7o*DbbJ^+--tT&lG>1108)w4-t^uM4uHL{1HXaSJAd>k>DJPV2Vf} zJU|rGP>g;eqlEh6wbiy2t1hTa63&QF5ZR$S8zz2SGHZqvqZelrajL*_Ul0>gfXc?i z5WxT|l|55|JDHQ5Qju~>AU~pUax=CrOw|^sFACfd!P|vjQ$$6;4}lPk12ZD|LFJ;@ z5%6`i`>^pL!{L_+D5UqkKiESNy6?*ZJ=`C~3;4O;t(jjn%UC{U>ovnVPCFd4@u+1% zBfBiouj%Z&`rwV{0JwXqxjVh<)=l$Z^+(dFW^!r|L^dapVJ|B27j(v5eKZnTe#F$R z4H-F4uH1+%ubp!DV40eA#v!g*idS~pQCPC~#KkM;ko5#!-E1vjE)+{F95FdHo}2(M z;}dZcP99;$CFNUmch%GD^0$`kU!%{)TwY$QMi!1XJ{O|TmI8J@PxSHiX?LEoC(^OH z1blCNXyBh;rjBMlUbZI8n+0~9{yxs-d%YRH>|g#mi`4`w)}MT`UDw{$-rCrTbK_YDShN;f~+*b_97Ysy{Mjs^3aOvU#D*G{r~do$^K zJKrAd24p|V1hn&deU|O*&vnmRkFHuLKosff=A}d;T{Wyt57jWy0un&Jmd*E7+L)#& zgDIz=$nQ*2Pq5+#@VT^rTNCs|w5<|!Dy};gN7+;?e+`NyX0vDjeLJ2s9Lb7a3AL#R za#$#0fhSfhDaXS3l-OhK{IvvpAno)tkjJ&E(z zNLQH-$8~*_mM>z7VjCTv42|b@uU;%Mm4XVXcM&c`P)Ws23vTk@UXS6`%+Zqu(h|Z? z#^%~(+*CsGL&0o-kS6}Y-eSgPX>HBF)4sOQEMb?INYG%0cH)CXJGuyC$J$0;TKj{+ zifk2yJ292a7p%S<+kzkoD{a%}g>jwNt6VIc$aKht?@{><2{5K?dFInZJQ*S_761(a zWfnL?hA(HN#k8XZeYgDs{(4`f)8q(2PXpl6CItiY&bJw2l)Gp~eHHfh(boOJ;pgN1 zHj^%3=YU>F(?vomF1hBUO|wWaXHeKx>%zZD>g>dqJ_rXm05c4m>2^&+0~LZ1vNs296(-|rm_vKJVUak_5fLGO{9t0UvLZ>Hvr3>@WJ*m!Tc#T?cPuI z=ujuxHQ#vxj?Oj3d@#FujM~|Kk+>13A4Pl|$6iCzImu#~&n6>U_>FQ6%fkTN=DB$8 z7IKSw_m+f;Suz#wbGYGzx1CwhLf56AT5)LWI7vty=L&he5%vV2_jAARG56RR?%o<= zyuyxqf*Wx%BfoQKvYkLK-ndOp$86(63PJ+33YY$1m(z2^> zwB5DP(3o3{-TMIj%-ZQz%7LyiL6dRy-EEoPTRxTSqo~@pnqK;d9}-n>+-6GaSghZ- zt6=WtsJxm91x>>Q)At6s6ao#&gj-|rmxmJWx5Yd!YYJ%Ze{OpCGT#l--n)2(b?kq` z=?o;$IJwZoTE#{a4Th!}X*(-c`NDUE=@g0byPuu4T1>IUpleo>$$_BoCRNKIo-nZQ{31_OpG&~Xx}%h^-ZkH4 z$B4yga>ivIhRI5Mg@I7mdpD4jH2i#=6JaDh0ddh7j748!td+S0%HF%6v`K9i8KIM# zMhv6uaBL1Y2r$YhJdY#jNNKRp?we`|C<~vH(w20LbhXeNIh#ZJuvwrPB7mPmR4e2jNNj7MZ;R=+;jUN{_qGdIsItXF|S?;AU& zhCk@UDS+pby#C(Y&4&k7RWoY{O#v&Tl`5S|sV0L91%1s2=&D`YKD_V>XzV@d+GDeO z`y7PyN$xW|s4MIvE8(DWX!kcg5}~ZWL~FfBY5t!NS{tuV@6X+ap9ULL^#HV0Hy9fp z@D^X*jgiKG9U7f0ZdxcmOtA%idT6BhMVY&(oW^b^Chv7wIYL|0LFIEM$P-NsO1pd( zp@H#0cWb3Ys49B%=iO05X(OgmrRpIco7Q7qTV#5_K)uUhvmKegs)3Om)jviA+XCi^ zP?SVXESY5Vj5Ne!ic9a-9GxD%ShyZV{tQZ2d^@93k`bXb2QEej8amWbJJM45f<2l! zG+3ANVX-&(XwU%HrIh)~?WQY6abZ&`>otMgp~$Pbjjb_ZWM5{hXK^&Z4Lf8^`~Yo& zV}ktrNd#+raUO85l@b1z(=&dmbyKMx7KIHR&C1zHM-l1aI?o!hmV=06_XuoAzk&YR zwNypw#it9JZL}a&(&iB!Lf|Juc(ZbA;I$lcbv61esL6JLLU?syYv^119;~MTS!}_e z<6T{^bG~$r+)=W(rP;<0`cEsr9Ag)fL+?7hxdmAzdB5Ply(*~&|AATN{ExO=jI95) zOC~@|JAR!L%lAb6nMrc!;O)qfCN=T31z)9x6+nUm7YkD;W3c}D_7Q_$DYP)I6ciRwumRB@^0OAXUx%h}x3Yu@P0rA3X0dZ)_+0*=44yo?#t6n0LXxE< zW+)40@vQhw)M(v?NeYDnfPQD0ob|_bL274jrhj`{oIYl|JrEZ5c9BiMZJT{ms=x3J zWXz3gqEWYSUN@qSt2gnqx|orz_X_XU%CBPY{Lv`t2*Uxu8(Q`z>K9Bx*} zc#>r>_KhnvG|IqWWvmvI4Lr>X9Au+HaZwa1W$DsA5a9&d5NpkT!BA?ywDV#Snl_bs z+#{!UjI_D0`eebe3u?`c*TOQG(EGS?pTrm?I0uNe@c^LJc83w8+X0Mo(Q7YMixx`^ z57%gL-T%7@Ix>uPVVEjaGvuitdBlL!G1i!oyE)o7?pI_#-wCrsA6^|VOYU&8?#w&E zK1D|9q|Q!`Bk?}zB(ycs5!^^S)iN^Hv>>4$CIg*&lDjA$)Zy!D@v@WYm_4SDCohN$gP+jasRBs z7AJaeGnGw~4vW$a=cQsb`UBl7pcwB<4`q1l8O0C^mHrsgkSk@0WO6JulGXc##d8~Z zKd=*{3mbd*5Y40+{aY*M!|YUme3+gn--IsT>cs{6x^bdN0E$2rHjkRYkp_m~hB>fq zn!)2V6FidhOe>0RB4fFc7J>KhBovOZ~gwRP5%eC-)2C+eRfY zm}s6$8J#!P5rbZv(g36R?bvJLk=&lb?@B(d%Hzi*w)jkO0@1Xbn)_Zqgg-%uy4$%J z*GL(1jaTU7J>GwnhW1#MRl!`PN~^1%JvOe7W`~6($kLSU@x$n!z|$fH!an7x0@gT=1x~qmBIjT9jX*0yd4cRG*wB5#IjLDzoag zHyUSbx;CFFY;AX2bQ-1%pq+w-}#v*0QDuFF)+IG?~-2d@j!rn3Kwv2%V0QIbOQo8CWsFijy z`cnh;4LG+($g(2<*@JVwdB(?IgO~T5R^XI3HEuk0=xjQl+#WHLnt6dWH0V@^dhD4k zWuPsu71_Nch<<%48Auo|{`Oo6?4h#ZbCF9Cb)e9<1eN~4O5Q~CJA2IU%;P|Vv#`nu}ryWHH9sf3G?R6;xlobcgFuF^VH!pQoS~h5XAhO38y|8~2ES4q% z(k9y*cfcGGgsQ|VoQUoiH4)Df*t1~^Z}21>_E0_YNlys532GA}_THQ`US2%sz1C*6 z$KF~|6poBwXhKIvynZt2_#>5s79v4Wkt(~Mi$c5?JWk2sYlsrNRb81+yu6~iI#>v^;zQY!0#|ZKj%&q4(=ECab;3!F*XW8ox~sY$rzjbo%?s# z(0Vaw7g5SUb)M14SsOPdwn8ggfuDF{@@kZ-l9ax&aH;1JOomf%k_vjeC0#||Lsy_XW9*`5QwPo&brF3Mz@LSDb6&YWTrZEIX;aPg(R{;)M7{Acc4J+*6bv6Ymu zl!UZq$3A)_MA`+hVJ%LzVKp^0l5m>0QR^B&L*@%pz3{v3vYV4;B7lb)c33n~BnHO0 zkD+L zc`}_l;(?dlh4&dZeEh3zzn6#GsKfO+j)Mpxse)L)3+E+EbS<05W?PykOG23jc9gDO z)ed95%it>47F8*&%d^hyz}*J5N88Z8xihnqxJMLw7jyeZMR7<|W@FrgnPMOY!Y+AX z8nh3T5Ae#=A|qgZfF5GVR7iad193_Ng?!qanpaWAsLLa(S0I!q#j86VGaXS)BO*PT z0Sdf$ik) zVRSaVHt)wEJkF?AHkn;(f}biH$J?6h5p$2}77J=mM$JL>bykrH>qWD*jAFwyNJ4Rv znCllzkkT26utFMXTVST4#L+gJ>?LndjDw_=iPjVm;x^gW7i51(#q;wWxY7DPB~rl; z(^)@Pn8!2=AV7)fYnfoQq`Ow2d7dPY6Gs^J%Ze<%=z_bzxIzH3_x(F;*`t8^li$C+ z`n6I3cJMZ%Qa2tvIU0TDOsIoU^m742Tde_ra)mJLpOMhG7P@xO%q0nI5mF8q3g?5* zXGAoR>TsRuTpEf^1ovwtr=+bgHML?(=fYcUaZ>YsRoiCGTN&J$RV`1@yJ*;fqc@*8 z{9QHUSzt4IsjaK2A+x1%ZPLqyq{$d=z0B~fN4>HQj|#}GzOlSa@(0~*tplN9>8$;A zdJUemITr&60h?=TNB=zGUu*&50o3kl%Q!Tne%L^^UJwf1_<6zI|Lb$0ChR&8h=KQD zOKB$XC6x3)J^y=nKf1J>94Q#;3?-(QsG3qV92h*40*#;wWk-Q(Sd$M}8pU2EmC0o< zw;~Oc!6nUie#z+hpu{-)P%bI>lS_|&c%+8s3om2rbDD96Yst{vLXhjCshcWUzN{Y_ z#q|IQihUawX+5 zy=~JyCGWtNMZm=7Z^Xrm$92r*fBtIE)k$Pu%_ZwVOhjhlY(gf3*$6a?Sg#yDCN(`* z))sy0y&~P#-Gay@k&bF$GhYG*Fa&`eRpuQIH5O@C?1=L8+@fCgKqXF^It=4<#ehu*o6W z)>S=A4fv_3co~@6SJy3lWh>zeRT=#ye<&xUi(dqTeqSxpPii#w2#z72B%7LgTYBaDQO5VS zv?$bS4sX@T)sF*;`TfuR}{Ss|w+*1E@E%2T5N*r_thw?c6?N0-~V_7!Zk+3DMHw7Q9_Q!ZB zo+yVD^543%Dqu$R&4&?&iuHoKYR-CwGhI!l z^!pk>SqD<}RngPA+60*%VE42b!sHmfmRG@eganrK&1LR8$8?mOb_kgEQQYqf54+cX zV72~Q$d1weuyGpxthE3(CV+6_1FTt?L?iV8%LVcx{3`UY;^e>n(%twgciOgOgV(Yo zsW<%s*wAV?bN5eqbrmMiz((v{{Q1THGW5YpHg9SE_r8MpM?ggJ$*cwpmwo#4GazDf z4@`hZ``IV{TCBm~n(DnPLL}SjJ29ZT6F|-=us2{>vzJ2vIJ{(#)?s)$F#L*@RI-o$ zmc5X1O;!_tWM{72M=~#k*nu%X(A75h`=sUQF zwDzQ=9sHQur#1~_u<1xLI~5&$&k&t!R)F1R{>S`AJ&g3tK*amFCltUKoMRS+`0}v` z3#yRfAgOoDivF7gC9pt1J3+U4z+cq&9XH=PoKpl^vItj`R1*8lop#2NaW?aQ!MN=^ zm^fxAh)Tew4hE^A?#g`-a@n^!SQTR_EuXD0W}Z+DBAKGgm#$3~D;*%1fN@I&e&?%`Un0$adaJyJo&X?1|sgX7j z*&+3Fp={L#zXRbJb|T9w+{fICUjODp!0)qbdfYvqUvVi5i5O(zDFf?q$ck~zNvwcq zjW3S|Er_P0yBzvX^Nn10K~IaSX-Ry;3BeL1ttUidpG#q{^@h^mzEw1uj7Hd*bPbP5 z`xN1YZ%f>I*Yy;<)XqnlGR<4YV_Pu`nx&7&)_G7QyAIB~GppZ#lXgLx{}8I#{vlK| zF|o1zr@sHC=6dXYE27VJ&1@lTC1bkZ>h`Lo-<0=DG81GXGxBbfwb4Y;mPd(Zps?$4m< z6Q)sds-!TL0&}7!fykQ!gLLm42;mZDsv8p8BpwNT^dTk@`tEO|W?7$erFO|K z{%-No9-a^9u$m0*JCEUT6hlGdqRWx6j_qp*76-u(@1KxO9yPUjylr0}{FPhDTbRU7 z-Xzhwc%x0;v+-H1vhSnj)eRjJZtdMOQ=EP?lF|k z4qv*hLNte&JZE}e!?01_^7~0tr7sPAU&Pgk5)`DhX4>?{nR6IOA|9r{2ckrvN#awe z(p`#J%t=(4(j5S6`$*Ce1EUeXJ`2RvToEs&(KRxbQ8T7n36pxdT1iQb?>bw?LAddE z6fWyMzYfqK5B@YhZBFB!a4g!W;c=a%R^Aa+P^Mq-Q$h$;Oh*nMX*KJ5nXETzqaF^s zEz_4@hd3}q{b78`I`aQ|o}&w&?U5!F*7(|ZsNUe(aR=lrK6QMOs-t6bZQLY#Y_VC} zRGfmxz8q&)GpW0!4Z~g^y}PV_n)3g(p2O~QFY3}Pp}-9tLShsDv7{0vigv4U%p_1AWOF`pD%d{pTZJo(UtKap- zKUKwwK%LIb<6Mk9NZugx$pQXdH4To&3gMIeZY&EK{|cj0J>V8d`K))L?%9;7a))Eks58XN;4gHoyfY1`WR zP#yDBD#r|nS}HnLEK)=wl>XW1=r78t-1AU{i!axk4EhYbRQ&x^UgEWsDGNO5sCEh+ z-bj*;_n|B8xc5K4%Rz9Ts9A(y9mn2b`}_m;l@EvfZML1@k-?XMKx%*?N=1YpiNpfl zgWWJe2TVbq1gGlW5N#yeHaYW5v3J}+?Fuz}wW%S8Q7u$Otz9@v2d@OU6pO`Ev!~2o z7>3hNys;cGYI#S7gWBv{#GzIs)sr;J#KQ)xI3yW{`B{#Plv{rc4z!J1@i}w`3P&kj zT_&ooDWE=7f@_bXbTkAL>b}rMXPBPA)qsnP+&Pv@IkFfs$|vURm+axe$Phyuuen(K z;eLQfFpEiVdEJE}BQ}_jiODCUe5>Z6e&6BII}^)}?$B_d)(V@1cc>cZP&NbQ8%rML z{1}5h>*Kw$etYR^{vnrr9-51X8$@j-Fwj*9DvHifd8H5zyR+uwkv9vTL_#{I^|;9D z)!ZnW8XZ%H$q~$)`}!=udzn<49n1pjV(VM2SJwfYYP8T?89?|dd;Xit&wI())#Q@D za$Y2^uzmo|*O$Cw4R3SUjfb)v&P||H?)oz-lhR+E6&bHQ#XiRg%~a!Gs{pAXz=YQ{ zNDJbOfI*uCX^iKbaE`_-kW6}>jlw|0lIHOike=@6SI)Ms_)!yVZJF#>|x z8gUAYC_e>Q%GR0}p z2MhO`Q3aM^%nlw?E{E=MP*n(BNXQt1Hb$_hc`3VJLx;Hn+S-Oq=%@)x*O`N><@L>Y zl;9>yOaS@V52ci#!mY+_fs958dVI_oBwcuyNk@(uCBmjURe8BqI%`$4*UOx~!h7;p=MI@|zHn7Tv8aw4C|U z+b6(1bjjXdcS>L2qA(S1rbdRhlF3wu;& z0SEnRX5yLb<18ZSx7(pbj}PosJ+S#SuGw1t+$9R{8aXe~o#DU{O+Ij_vv%{j7QR47 zm}f@(GeREdp$rEv4aOj*0sY_xwVeqXbeQ*`v%QtBABSWrZ0JVJRESe&f7NCOM;9id z?zO*ku-^5)AiI6GScAFQU+W}l%cmMH&lBvm{Y1QMxRV+1eZ*w%T<@g$>+O_pO`g~D z8%$RI3s@Y@HoxMP%tlK78#90HoyvTnbqf?v(d5O_M0BvocE8iD67on=q$FHg)nqX?J~ebMYl8OSG!yNI>t zunyBwZz7piwsuJ#gzO2?8QF^$C+>iaQp&`0$a63VHOI*a#yxhRoK)y8I>U%zCZ3sf z1d4(lilt6If{3A3KZf2%q$kUp5l0>|@*jpo_4#EOdlOzDX3@EChaUsoOLf>{p9&qz zuo|?Dh*vtUeeeYNi_So+{QLgJFMj0pn<8!k`<8j$QJyIkQ;~_Jgbl*oD?sl!vfi)6c!^z56ep;j4#;jKjo# z>imL7EVO94WLa|_M1hF~9z>95kEQj)#m%z#0~ftUj`>36*FDERBTBzh{L>dsQJ}yG zSN*>0Ucg6z&uQeoVNtjQ3jJC^-yGZq%)WM?^c<^nVgErY{jAUaADzBTO#i)9`+v`B zhcvb9_FGYXXMUs-%p#7i$ejVSbqjM4-I^gcG7VbVCLD@}M6g3qB?&q6=Oa(&Sb-3C zUA9fGw8BAK{C3+oN5`1`(-#o&Bt#OXs5Dxq|F$57NIjnJwa4S`=a3#9{Z?lXWsI{x z)WscF5({;*XyVO<<8PmFP@*VORF0Z=$CU@@g1a}Tr7BD3^P_Fn^R*b>#pNcgS=GnA zmI-|N8;yRG+>~e(!2@B@#VuXk4_^WOaOS-ORB@%>DsJexz5}aJM}901jpKNie>$Sk zp?sHDN22_uf(!a#rsDV@^W9_xDTE_0B?uxRbZH=mIsDY+bKIt&oJ+ZCsHqJ}uy*rs z=2D=5slX2k#i@BDUX;=LG5ghrf%+H+ct~C(Bg^!>>GU8q&xwvYs79FjRFp_qJW#7O z3Gxj~GQIRO>%$Rd~Zr6_m8qtdP!7Oz76hJdPbptIR8%@5q~Wv5}oAO{VAI&99{ zKa;djtV#g3m}n%CiR`^X;Hl0@ev_4gP~B4J6%tB0_% z%Pk!S5(w&w=+JSzpy5?;>(W9@FP~xq+mS5c7d#~bJGhUg0I<*w{=G;FWKc#(L=xs9 zhKK`MC5{%r&8&sPtFf>{QeMGOMW|lA_NhBb#^&&cxa|INut*}hqc z4si207U`n*!ieidA0qsMT+SW@dSH?j^j)536tAhnCe2F}>|y4}}eKyRUk z+UG7)f3uN-7>bt^4#*+_YFon}?PCK4eumxoMIAo?B|}SzOxM|AGYq0e7{6CDfLbZT zh~|VlL0voDBtk}kx2IJ%^6mr(_T;VZDdCKKkyhKt`nBLAwbo*HNRg{{9B1U~g!|!r z1_IUU{b|?()(vBU*3r}h*qPzD`7x5op#9-_C)O9CgAF-u;4Ei%e03f+)-lzkw_1I4 zMSt2ECT_tqWVha)b5!MR>PVfN4i}i_ppLll!zkTHkDsga!k%udNKk zky+W8@W@fyfHMi3<_Pkc#f^%3&ogdx4|0j`@eL z;87XJAhVIWF4wM#R4 z{@N&TdEUcr)dqaXf_h0lgW0PRxP^*8f9qyGUKj?7$#&|t>k(WCVUII&Faw%6pW1b+ zdK*5ESgw%wdu_I$sTY&y^t#>L0LzD@k2+{s04wK?Y~Dd0)4n>9#2DMT*0md1X`KwP z`LruEL6VEhl^e!{ud`4T8ncU@Y7=(*jlq3sbD(tT<7%u1Zq^J<2=l&&qA^A5A9PW` z;FL9-VCY0_9Ko$2hlFn<=IC@}G zfn4~1;3U$jo&lc}vgLCBzD5VVl1k4gukBQofdNJ`pL+wjWP&InmG?sn;}fuvub{yo z>OW&yM*%$?Gp?(o8d9mj~f> zw_82w#0XwquR+V^Uaw8;y>^2UC)IeY2>lo#2HED6{$=1=P{Jo>T2RrmrL-YMC|Cwn z)2Vy>BdT&@j4OC@zkjLO>@OrZ(qQ^)BjAdKqPxYbJu;N6pRTjcG;5GFY?JL>-Espr zBZR7}640jKH8K*XpZ?H8-`U}W{eteCTE&$(V^DJ|jprjzo0dwiVKxJ<-Ym=8Q&J%4 zar{R>l&wC?Ww%+rV3~x-J_WygFsx4pgxvVp+z=equI5VMZ?t}&TQ;~(IWqIyvT3n} zHesjcNS`jVy2*RcV7?snxIV_ObbgCt_K63OrY}(GI+uuemq6kMC97=1`d(ymFfjQL z)XX)dJ~X?6kBb{%H~xqd;SutEU-L{;#hFFrX09NZ%Et*Gwi@pg;Hae2_B)AoD2%er zAau-Tj|5;s)C^F|&~VZPuJ3&7%|@9T{n8p>WpmuJS8&)6Gd%-WJFa5C%PCeqTl z{lygOU$zUXg`cJde;=Nh{V!|#7JT&Rfzv*acGnz3v%I7aJ(8u~hu*_UXw&I4<`iBF zZtrEe+*U+;FKsl-HxJiIi+NNllC}@I3K$r7`zEi5~x||Y>YNJ2zt9{pEs;8rxJxVXdz-n{Fif)RUuFL za&Mlq3qfr?{6JkF3p}Cjh(jZ^#~;>3X8eYa9Xhw z$Q799M7hJk_uP|mv`O3Foq_xaCM8HwX$iVr%8-bFTc;NTZUb{qDZ>-0ED+?5Y0^^mTrkH>-!YPmD9Q zGn1JpL_8w4@zdV-?iezFP&WKojX=nyzLV4A8IYVh&F}I7Guzu*b(2Kf(p{IlC+B0n zJi-McChfq>4`i}qtmdN56~~ogbEfl0_)``XWEf2{VsjEi<`mbohyxchmL$3C~@B55W+y;qcoYrB&7U z_>beTa{Go4SV?Qoq_Z! zb`#wpbAn$jMumiou*%Y~@&2B-ouj~s;nsGTImoR65K>1Qq>*R-(1B`TZotDFU6~3w zXjWy{$p)>8;PcTIy?88$ARlI4Q4Aqoqt5U5_T&)c;*RrW1vJWjo@S{+tF$^)yb&st zh=gR#?Np)GR6*|Q9+e6*h$CEVp3n^PMMG!#CXqUcWu>*!jM~8fszej3(eV#g^k)Mf zc+kHxoh0%omht4ucvnmq4scHZe%=1oYkUk5r`n{$QWd5skbF!SizjPsqrAMCAglSC z+6If+mR0^hMGgMbk)>3*BxH=jnb+HGz0A?eLCn!r4c5hg0LVNBz4>eyMs7q@L+Jd^Ip zQn^$!+Dg4JQDGWfd;X9FMk0y(`#V4*s<;%Wo?DM3yDv-2L^ijqJWnLk2Dg3LCyxqR z#S~MgxAt;Ac?DnlO_)~2$|5cSU@qyrC_AZAv&b7Q4%Yl>7})fASYMZ~JEiUU>M)y@?(5v1(z^$&pnZ<6Mo<21fuK)3<2-y9;8N=)PKLo%vuyg7S-dyeLATRxO7Yh#B(ipI z`vzX%jj~qrnM$B={{6(|lC)l6%)n-V)DBPF)p?j{U7I9c1W|LZ;8XrgXsLk%oZyYt zjz1k8yNB!BCur{t@Ew3OY#9TbhT;)Bz1ZM?>zO+0V*UNsST2TZ11|MiPKn6!-4VDj z1@I}io#mssE6d|-lj{~hFA)zr2N<}q%OXU>lr8E1lu`79mK)Efqhm?YaECCznPoDswy5PZ_;j%nTH(vqKH2Ra!<9H8$> z2uT3pCMllQNNkA{Xgu9r;uB zMtwnCY)-O`I`*qOAh?lFac;`U2}nuCrUw5k2xXW*^2~OUa}p{WQJUm2gpr35~`s^V*Pc;MH=P6<|IVa?H zvw<#wk~aJXvYJ1dO_QM?sxulEm+!TDI*IHQ z7T{_revfj%XoqwdpmKmQ&panLzzmII8kB}|^umOak7Fujb-6pZzI<(eYqt-iUTYXq6T5n*Nc5g6W4AOPo>H4VUoGqSd#_#NN zmzCodSj+b;=$;t9$9BBVKI&<0*I#H4oD& zh0^7(*yuj9qq6rmNI$o?d)v9DkRkb{nfv3F-cN?g5d$)Pt?T_|KhCcDP&cRN-QMFo zb%(d_{4O$ehp+Ga4Axv&fJV&@U{FFkQ@ws^NvC#ecWLPLVKea4HB4>0^8#+0p3moG zYlC&SV%KhBb=PXc)#G`WN1XTWj%D%vJ`Q~$5&v~b%un+OKeT4r?~G37JXr*BK(!_m zT04`*o7C;}_j9Y&U!HQQ6dpAr>;2zP8u!{UjWL}u^)c-+%`x3E>z<8OV(XrrRU`lP z@NU}5TnNk~9*3TTg(xsS#lDUp*l&I=LVi z+bkOW6LY&Ps&&kk&zmVvA(uDkfw3eDABZN7vZ#j*;YsO3`KXb>E-*{ALGKJ4ND=I% z+`;|$$n~zirqBFNGXOR4BTt;Mz>_2700PVIJc-)@1(Y9FM(!K!N-`n)Q7v4vZA(y_ z=5^nj|4=}P6=JCBEECyimU!H#qU)7P$mQCu<+a?(v}=@WoL@HCWl9eov%v(tSPEHz zx%e2L#72HRoR*+|rDi%WaT45$=ShbG}BQ+2gtG4@UNU`g> zK7IREyB;!YX<@U9&RM@ilSK!tjeG)AYE0lAvEl7$^o@Fa3ehynD;3)Ew0?(}6)`AQ z=ZAU*T833U%C_A0`m?Xc!T&z1ETmUfsF1VDJXUwf0i#QJ@p^OD59K+x`NeQka5>$g z(iTz}qFKTOujG(TVU0tUr}=%_Agt{ow} zLZP0aUd|@@r*X(R-RN=|1$TV?GS#N}etQ`hy8F6ZKi3%J<0Xu@5mg4e48pCBDJ$?v za<3LmM(a8h7%~;6)c`#+igq72qNKJjKhAf`J)MrmV}sA{v+V3JeS3^{zjU6KH*Ry_ zGNW+xsg|8lrDD8aJJl|F9x;L2Jf_(9!Eq6z^Wg1hch#nolYME;GLXUFwn1OtGMMIGe1~+} z+TEQgR`3%q{90wP#P(Se&2645wRvbe&ESjWAoS5)4hB0oHukR~oBY{9^#;PaYr!v- z>{V5@4;3#$OiR`ke8H2V0nVDV$F^LY9D(%*EwumS=`R~isTtMyv8n^GCOnKUwZ8}2wEr_VJ z_CvPx;d5H?k`z3CQqZ$kwS#tSF9!Etp{wUNr^UVJ*8;%pxJbn2d{=E65Y*)a9sa!M ziCk9WeR;mZg!e|u4k0eL_V$j?E&A(CDjt&Tr?#Sf?9~@hHaxkx%zQ9`#!=X54y4vg zUefm^2eO%>Y&+`7UrEh(Wl;B!<6DtiM`-U5pef>B!Lko|XH_QnDH}gsY1YC|;9`d` zj@6f~+CaxM2Gcy8E3m<^7JF8DQG8_euL8y+)1$E+31z4fF4{0QdQGm% zvH)&VpJm!#aE&<2v7GPsaw+fd?0ajH{~%8}|G|7?`@C^X6yNKE&o6ZT-vb9hGE zKlu71ng*9c5SNgo-uxD{LZUTjH9C3w+<9N`%cTA{rBt{sQDjc?FG}ge6=!n@C}B4o z3dd}sNS!uJcx2V59mDKo>{(C7EZt7WENN11biw-N^l1Pfw^-Ym-B1_`5qV+f>B{wH z*`FU-Z19{qKA%hSIH*I8154-|d}8M0q#=_v?uSvz7GV$4W0$PzNr_V#V&$qLVj*Hu zKjeD1Vturt&7g+W%Tr_ZluejZ1r_sgx{nRg$V4mXXS*CxgjOoVa{xQ|g~b?}te-PB zLU`y1P2*p=Bf@~hykMJfG%FiUi~uMvsF@9|h>(X6Y9M?lrSYQ~2-T4850#vsy=NjJ znx1#8d*~@``{wngZ2*EbK;L;eR#6DmZE4xkMpR6tf-F#1MtsW7otKv;99kxPsX7)R zSz`_Lw>L_Dt`%j5@YkkX;tQWHbW6Xr%`|Al{WWCRByF?e{PyVlh~-;%koCleGhOuTtHKX}(BuY*A}ce0sR}hKszL(5 z!&143`Qo6+I~i#^@`SX0wcNfE7iD29=dg0hLWlk|VTjetS+gI$Ik<%P1#I-Ueuh&Y zwEU=+jjnk}c6YB}lk%AXC*j44lf>buNjhcXpaQ=E(V`PMNW2SH=>kmf zVE>iggK zF5hOJcOQipJy#=Z*;XhjLZ+v;S7n<_Um#0T2|vDEvFp!CP#~IL3v=;!>Q?sRlhWdn z!>ucFr}p!{Ks)CqRQl}oo=RI5{76;L7P#04}N1L;lsSYL_YUDmfOgZZU}T>18D z5$OJ!5Y;;X-}u+bNak^9NbiQ1N(29C4#orqG=0W?PQKoS(JEa9Atp2zXKbty$5T#(Sgzaq3*QS8BYPs0}%~47xg1jm1Twev{E4 z!xbjKHx;Q0j0K_o_NEDNF_6D@CZsiWj|;1PHN;XECd~YNwg`oB8zWqy5@w2km|P{I z%HL#z8HmA*ZCl_`T<@|I0~6wuB1}BqSCyaV>1V<&{hPR96s=Pl{3uOegHWQs{>yqS zkuWS3sGz1!?l&0xU}jo3Y*Kh!^_d*k#fIUCY>A zL%3V_!@+A1|G)>uGJP&Bm&!N>gyOJ5iC zxWj`wS1XKiDM&2bJ-!_hR=ottjJ(iC7juRL4y3m5Wd($7XbC7KQlp3<;Nx0mt?(^; zayzDt|9Do_>YP_tp1_sV4!RcW*Ve8%65c;w-j zsqo!+;gOr9-M^0UqO5L-Tup-cJSon(RK);ZS|~6U!wHIHNt=xg(7=$JuwMA4EVRL* z$4YoNjW5)CV(7J#^pXSAVq=|G@d+(8VBm*-Exi3I$!}|O;5_r0ybhSE=(1DMg(YG~ z-`;(lphQ7&n$bH)kBRiX|EuCR%f;)!gyV{E9~O}Oec`7DFh5EC;Zl4~PZOUd;3F&h zsW!Xa6BV@jPbW9WKVUPAZ2xh0?~>-v$t{ZXb8_z#f(Y~Y;KM`4Z&rdsxT22@LI6!p z!kL#}66zsGX%$dJu*6>k^{FV-47v zxK7Xew=;ZpwVG;!aRTDA89~jyou2P_ zX4q-pbGOV~?-y!3rawjyuW^s|XQxrp9Re2Pn3%`Ej391adWpDjMoepb1?yq=Udtc6 zHz9;Qx1Z-8kqqIfvo}-}44Zdl9$(+lUf5rmQH4UyCtr{dW)Z`tOVZ_Ndc!o%Z?9y&{IevDT`XK z(7dtT86)A~h3rEy4v}SvAAtx)jN6f?h~Rk#G3EuQ9|&U^OnapWr!6?T0r z=p9a30~`%?wr5gi>+Q``N-A8)V%ud;-bDdwI+4`lr8etsEsQO#?oQ<@wlwT*$5j$o**F!A`J#hV+t#FDo!`9w)1?36;-e8M4VtCRpa@EHLB>uTq z3@H9=sDKm0{X@Sjw=ERIF4t4vd|(WC>>p61w~E-@&QMLZ&{S5LKPoKO`wKA}UWWdZ zk^wvZDHY0se3&UFN3}h{tJ^{?(IZ0WZLbwLI%7whzK^kKaak=Qwf4SR2NtAQgr;^k zM4M7jHKFlCUiAu81Nnp8UytfGo$tED7MSbVMufrrAoyB9rQL6UQ-9=d6|jXQ53iQj zg9Y1x0@SveJ+mu;ARDhd-atf^@(ly95icec8lFr~q$;_>CpTpKhcJJf08eci^-o_e zr&I{<5?zN%rqCElQ0m|zGpW*KS1C#2Jt<+7oL*qM&Q%x-J?q9a8;SAK^(?<7qCCN_ zj?K4>dSi<~QPCM1EHjY#AjEp{6LA)S8nbn~%6dKJl@vCQW0!JNoCgm8Ey#sznvi({ zMIQf`EioK2UH+M$Iam_|1U8Re6mdqc0zk$YnqWbRJT^>D#qI91Adf0cmNo*iLdGvC z{9$fJ9o1DnWPq0s4<|2k2YUG`6e0CUYY|TQbpD68HBK#X*!(>)QAS)3BT=R@8i~ax zKj0O40$ADRv#NRBxW4&`&C~eIGs^~@5&Yb!YKcYPN}ECA&tMQNsiM9oI(zJyjaesI1 zs?qtBn>h)1eA8g^0{7-~OECCkFlCjBN;zwLWJg?dSRHUWtQZ`18tq-9`||rpxoO~0 z;z+BJxIe(1bT~m8JlanGhRF19v{PlW(eLjKd-CXa8*!?C^?Lc;-SC>@r;CIbtWjTx z1tgp}@6UAC8fMUcrKctk-L0^(Sz=hsg1r; zfeN=ClT&rt1XuDb<>*)GE0-{iO#+j}9-L{>3fwHA9K|~~P|$U@H_J1NH@-$6_slEj z&qH~@H^5zVWWCqJnFYGsDmBx=a`#!&bLmrpF<=D{5_5DVNl04ok&DAWasDya{su)f zUyC*X^t65Dx2(S?k+CJ4BXLbl3RV)5_$AUU!2ool+OV)qLI#CPlZ=$_w`_+b9J{ES znk#w+dJ`Fw6z4Vf%kx@f5kr_W^Hc<59GQWlq^#k%l#xDz!g(diQ}EmCt0f$^6G}AF3417@T%QdKH0q!XlPC!>i7!k+XNCP zxkIOVbkC{-1OTV;f{DHJ9wE5sWw6xIeYyCZjOH}4vyf^)S^SQnZXZJcR(gm94}+)l zR>dC($-V@|%e*3WH;lfoxJ23qqfF=9^A0yn4FAf%Nc;r-6jf;%BH^r4_m-t?AT^Kv z`9gJ1;N5+3I@L0B4YDjfCpO4*9-JE*z(%=Cd?XDjl*PczIhtG&m(5A<>>>7+%E*U#zgf+S0 z5;sg9WdFGA5;ycMcmHB;2MR=zNY2pL`yKrSX_mHX`adNM=a0+vKgeH3 z4yOOu`?~x;l$}#>rSH1!W81c^j_q{Jj&0lS*tXFzJGPy4Y}+=^?6vmZ=Tz{zxllHc*gh*oHg4u_WKRJd*t9e+{u0Kgw!vjReoGoU2 zJ`flk#UxyfM#o>LDQC$31Rwb#L?u>$QU1aFzX2(|zX2)uVXqinKD~GME_X)=E$p$s zE*2Aji^U}bZD;g_+anW3G=-MN-tx5Ll4l?%Ur>PW_l!2iaEz;G1;4i`96`wK?b( z^Hp}{@UZH8bg}8HKfP>gx;a}XMz$cZwXucQtma%g`IBsM8Ne^#6$<`KjX-`1N}6m8 zZ7#)Q2ug`aFoY~V=S$$D@i-d9f;w?wI|U-j_}zyuR!rxcfz9piY7GN_qujWE6t$p4 zB04b@YF}X$!%oI-Plt(4xU+I!#fPr$(hFrbfVBCU<41OmuDa6Tfz7}%bOZdxH&(!s zDor!%hBaqsH1@eJMKHzp1gxQt)r8+~dw?9C!?Apj14wMj)xW%dQU^ znK4#1o^IrBhAwt63Ub80235Tpn3J3&Bp430&`{iR$=4TEuqjWIpo23b;0U;0>mVeP za&TZiN&%u6VV#cL4gpmwLi^qADEUMv8n|p?68<-(LPDV-c zapKlsKvN@dq#2M`RZzSklH7929-Tw9WVc z><(PDYeec9D`YJSIo-Kkz+qLo3%RniC_lGYIGNn)wBzrU+k;@1omNV0Ii0>ig~Oty zj_*|dd5Z3yHS>T~eWlMmFffW_R{2(oe%m5(&lOwaO;1F;GLo&SpSC-ky{)b~#11!o z%XDu*mzVb4|E(9XdUo3L4H81^Z*02UqhJ@!5M5JC`yNthuyf9UIslOP^epL4ESaSMM=2C!T~zYL4g|nx;8Q zo@NE4I4wQtQiC%%3vpjtzPyy@DZNz>JSE4qo+wfhG;R>?%I`x=LW`#A56x}$E858v z>PB@cCoa0NXkxBIl=mOyREC1UADucZ(z`oPTdhu*9yPg>abIFrECnuApiC!F z#+~B&y1jQNnVG4kCV6d?iw){C`rdB{G(He4)nwQb={hxV~%EK7JLtNB8D0wNrvCtl{fmlMKjd6doqU5$JM)m zh7`AH`kd)rh%gQM%BM%oIV%hBz$D>}(@@!1N)!T@pJCU2tOEQw8|tb+wv z6*!LVi>G9$#w0=q5d!*wyz!?kIiV_qZh_wKtcD-JE%S4cY0%d`sswwz3PI+M=eawd z;3?94|4?AY#rzMd0W;UP|GZ*CQ#uwMB1n9T^&}Z%j!BtaGF#2hV$O6FxhK8nd zbbV=DsZH6}GafYRl?IcQl+M&9${FuT`@=nN*7d<&lAhi*Wbrg)3ec!Dw0QrT?eFn< z{yU%|S6eZ@9r&GX0SwU%c_b~_kO>gN7GzRr>r;WT#1h85`FNpH$f;+BGAe27vUeJR z1lC`&Z8FwpJ}mO*LDm^j0$W|UJCRAS{Bl^xS)oau?VYXoKG?|SyZ-7vT(c_Ra|_3N zW_S~MU)d}272B;jjW8tn+wE}tQNCML3p5g~78$X>p_bM#h@tkVkU&VQvQ;-J7urU? zf5lzGLL_UA103mR`XG7}r8+qW>8x>-UJ}v2dJgd_|9nTYDAwY+&CH*7SRhtonoiIb zt3)!FIHt*Q2~&Y{n5-dDf*wG>3m!5O?klMon&*BG;v$eIq3&nHO{{I|slaXZNydV- z0xq~XHA(O>qr8w5hPbp<%5bp}r83n1=G3#PgR2O~xo2kEU?*xS2lwQVhWv476oSUa zNBT>r&1ztKinDQ1Bb}jsK**CjWk*DNSqv$OJ+dWGYfkeLm1@nw5E|0fO?RT=jk$NH z{+uljqGvXBseo<>Ei{{-45#<79jB*5zYmRB$WRz+Hfs$#v@tNcAX>C=0eBJ!IjNDv zOiIH=BZO$^-jqYGqo*15nj(WlPKqfXxkYtN%+78iIA2b+MO{+**ZN@(5U@yKi_wRP znMbB$Q4kodwP~4VY=(QzP*5mR@NM6xZdI!4Ysn6t{>gYY7< zKG5&v{avavB%tSS10ZLDk2{fk6Ff`t7Uq<*T{03p^EmB0_})YV5?ILPF^MtrGY-{x z=bR@{B=XBt+``=Y+(Hl;_My&X);n6)Ku6Xs9z4r;pZfCiH|pKYYl=g}N!=|dA3;C4 zcm_DP;YNVy4#NB>55f|uBs#zj0MhNz^tfbbw$3S2F;MI7ty1W`mK2>ljY~E0VjRNs zFUqEp=?Jk&-&CW7tJO{6f$UhVlLLJ2aua+g~PAut{8m{2eQWc*Yl-13o12d2+XZxCXp{ zLj2*-`0J1C@n(C>IdcQUs($+yxohqhqvj0EL9TgyReiT6R50F1G>ttQb4`9}OQUF7 zOYfs&r~G)uGGm2x#Fo3OtlX`%j7e$zbZ7s~r)tXsCpk-3O~;s7CWh=s8%{S@rx6@WxOoK9Im0Na*{;jTa&O5~vmLo1*LUj!h+b^v(`FGJt=m&wB z!@(i109pFQIL@q3 z2xrT2R5m;VEsRsH^t6w}xt~8vY-NTo6)dp;x#r|>3iK4QkW8Vjv3P+=N7V*g z|FYfgH}PP?B*pCev6A@Zg12O5(J*gl$|lx$q1(|*Y!%ui)-K3xVaru_WjkT@Ph@fU^%eLFrkv0Lp2`x<7<1M|l1WB&b%ox0w zmq*-~l=`L}bIs`2U-caxcf6bX96^E)_0_eTxXpT*&Nzj+_i}o zJ~`>vAjjxa^M(iL|IUnXF#T64^na2Wk+xe0jC}x(L=l80#7-#`Lz0jksX^=%M<{@d-k5#~ zLti?EKyE{CD_?SSR`czV7&3Pt`EW3OXJWW_cbmJX_vLTGRvGwz0wbl{cOmkaN0Ee# zn08a!s(~m{Cibl`Xz)dHaU{Gg+7N^y0g`CS0V2x9E?Q!up@+GZ+BnX8o4E(gLsbkD zW1N8`tTRXBZm`}74!y%^$kd{eE2686sgaDZAkuh9W;KG)3qr2V&(GM9((YeVW75vo zjfHKnfSYy){HON&jq$ub9=fXq;U*~wwpS1!r$9t5F16d~XpqrFb9zGYfr?iyelAKH zoJbTxX*yqrX|jXQHq-fwlLBV9CooM}G>Bjqz>eaL0OWDK!>AC)y`hoyc{_AnlqeBM zWJt?gi0U>V*AB@eP_p5CJujjApcB3aP(`slR&OIxSeed$|EtLs{MBT0%XLzmzN-eh zOL(*?$s!+Fm){f2Y6TtKwwhXgbKR%3`jzIE&N7oF9u$Q5)yCx42O`0|@0^C2jk%ds zc7tsS0xc&bHtcB?afLUt3K5@BPMLuzN)_0@GRJEjCyH&zc~Z7oFjWJ)$I23^;-07$ z18X^knmUa%A8>}sX)^=_{u&ysU6WA}wtd}{(?}x3Ia8ul*Nb8gE(`HvURBf~ZSocU z+U+@gIKhzDH)&-KCw}7NaESU48JI=Q{0MY_JWKQouLWh;+1E5N z+B1^4Td^SRu|D4s5>9Hj>SIk&HVCGOcyt#z`SSc2XXq!NtODQI*hiCDo7Vb|gZjz$ z*cy*Lt;uq0K9d#pCmUtb3S_txNs(il&ZK$5G(>xSNye<10qEvPAx2s5Pe(gMcKFM-n`o+@6zX9}H(whB zsH$POBx2+=u`j~4JEDB^=BNmR$y{O^m!0uzwr!R->sUHHZ>*TwjL(a=5FrsvRN0ZY z*x`CVYGVHxzbPJSwElT>-vV4Y8fisTIB$pr#N{gcF1K?q>pTM45hmrnh@p{~8eCX5 zk;-0Uy-dI3W3tO1$_wo>q~&l)nM)0dRt}VM@1dGy3=)dKGR?$ITB3zdGPvk!mg2^~ z%oRb=aYbq;rF5j0ck*-y0s@;0S9{ubHB|y`t|_0r;Q<=sn5$juokL&_Z?K|fC1ljx z!l?&YgCq~rc?Dg(lI9%d%vd^PVfM>ybPdt3Dqz`0J(_j<;8B#AyyNo;Bdb`|(+meT zN{Z8Nup{uH=BzZ;DI5#T9`_Xdn1%|sc1Ze`G=U7*3{SDVX%xs3^B#F!(S3a+4{S#+ zMYyfoW!c(0<}zrocbFzS&@sP_flu+Zg1Y)mZO*KOQJ8g-hH-r^2UE)rizsnxb+zO+ z`KBa6#-C2#jqVlf&EQZ0WcNq}!uQG;ARO_C2=+0XyM}rhWq|j@xUFY5na)_eGeiP? zHy@OrAZg(Q5!|)^Y{gq>h}LkJcqQFJveMHR zJkTrJXR5{7Ea4uzDDBE_?;3`-)Klf~Ls6!0m;&Vftnxm4&G$F9goy2BFi0}#NA|G70z?@b0b0mK-W7`@G)P`@T*S|xzw-w|ZmmPm!tZV)0 z34gzY1G>(i29djnb@d)((_Tj9TNg+VJlh{qw$IvKF=A4DUo7lVbZK{^EOhPWrV^NM zK^|DcIr%x69Rjn=%tZi`J#r-sFHbKQEbNb1$&)0Sb$7Dh%Re=2ksW)dezxh*ba)`< zH(tj$OYwj;G9|fMjaKPzr}d7wImG7M!!US5bO`kc8af=+i*2}zi%k%jzQer9%ZtI5 z2LrdWyT8LsnN8I@c)0_Rm#bV|WfIC3Cx08sdz35j@C`L}yT(e%x*#BsE_OqREmQJ>i=`%a+EeQAv9_W#Z4Vh%8T|+yz9T))Ry*bk z9TvV|={FMhq^})^Si%-yv5UUqDT+_d2XW%Z={AmFUgq4ti_gWJC1-#sH zr1lTfkM*BmTuk5o<5l?uU{$^*{@3KTO$x5E))@$Gu&`5rDP+qL9RR~l=!8wR_bb(-(7dm@Ayu!z* zU4Qb>0(@>iGaI7;BXC``rrOt6$+8460?i3~N&1}Wg^`AM6HrKv0#$uA6##CC`bo=n z6O>8Ic3u|o1{xrV=9T&jSVGOVy1-t*;hH?*BIS}r0N%dzw!IJFKRYlHz=^lN0 zJk?FnH24z@+#t%ThBh-a2y{~vMgFy~`FkQ56BDvHXZ}2i{7I?uSv^e zLC^^2!O_j?Bc4erD}N_aM(ZYzX20?u`XHhsEhoYJaurUp3OJgGLff1W?(;*2(-mL9 zO7*Tt7c(D6liUS`CJ%hjVGjiu?Va*Nz!TT!%i`JiSG(W+Z9ILzHjY7AhlyQ%8};1| zzy2004z)FrS)U_Dd1S|k$e;QCO;BBwmY>@b46X2}omMkQVk&(X{&iJSc^uS>aXZv| z_GJiQ*mIJW=nn8OrHK}4eX_=`k6aC4I|B=5+O$QgOyGWq>(ZpE>BR4M&RugS6i) zgS6K;i-)=lenG68qw6d5Rbc z_Mmf|4QLXvRA5s#;(Q~Bg=FgZ6y3!=)_L){!y~4OMr8)u`*W==?u%EcXrJuje7i6h zT2o`OYnjq4z}Hnz6x7g%{Y|$8|2&8lB9P$h!Sy4xB4#Jk3SzspqU1v!@%)ejW2sv< zu!pQt$Bwl@y$>DPPuY0kb8IgKa7Yqy%&{EH-%urBlNv98DR+PEkD;5~p&uqv#u_Q_ zEOjyoWbYEI{W*=eY;cUR&ZPGuWDgs)+SLD5&QcMA?-Aa%B>S8~OoaY7kCy&ryAK^Bn@8uj1q>_Ngt+uyKk|AE!8FhE7clhTNd!+A*1n z0If1i%6ntqf+|H{F8yPsQW^k_tXoSArtUIu+I|0%ACf4H(UXufLpN)tHKnNJJ#Mi8 zGX%lMvsu*6KO=i{QItJ*ImrVCL5!upzkcbh=XeGqk?(f*B9tB%CR*_v_2F$(2p6`G+bPv+X zxTOus1P&l%L}d$M%ZuV86fm5cQ0?8EK74?TFPt2dd~n-!-q9}LN&R9J!e)&^o-tz{ zno|hfSQYxnW%}F?x-pl3Bw4O*a{ih}Wpe5i0KNv}!X%C=3p~|}zr)%K@A+Ah2l@U- zVQ6pRq8%p1h_4e0@LsoT`X6AmLYc^riv*UkQtgG8_WNEI_-c;1zq7x7{yd0~Wi+Iy zB$UEY*4qBg8p~#yC~0K+bvfu+REI+p{h&Cj4$L%z1ub`!FchIg8R76qXCaes-vvh3 zFz1!GX6)ZWj#ID|7Aa^M9%Sk>J>cql_0{l;o!+B@&I9)89{E#E@rBo~BKN!h-ungW zFw7%?u^jV2Iu`ZubXb%Atc)z1q2E^;F?@dx@{&j!?lb=g@7Y`tBl^C_;Y&D{Z;IzH zdAb*Yl0l2bbi9PAoV~dLig1D#M{QceFLy@>$As z_4+*gS$$lnrzqNK8%Je+BSE;}QnEvzB8OW%<<+VGaHwEo``^oJ7FL%3*g3xdXz)2} zLiXMIyS*;;aPQ`211RZ;NDYFXQzTUOf2H&e+8$aPvKQ^YQo58zgUJgHms8!Z7sHD6+)^kj(D4 zwKDw0An_|%FjQrS_Jxtf=dsjA&dsZ^j5dhO`IIy3sdL8H_dJ-DPo&k_zv;s^S)KptwD#*w zi^lr_Kls>TnQIDGa%QUH3E@oc>qe2`Dek~sE?|g+VI2#amNtkIkE)2351yR;I4is%R_+!@F%ZrfQ3&GVcC95=x{) zrtz0k`Zn2nO#xSX7W<&bLA$C#M2{Y3z$5ME?fm$87ZrvkqoCTpRg>wW)lt>ms;3vR z=mm9|VO_V}lTQXQ4xAkSl#^gifdZz0OmZ!rQ}m~5M<>25oy!ke52|$G-exDQ56wnc zzScr&)Rp+1M&&;S&CQAD($m4(LK%hU#;KXU=PP`?hah3#*(ZJ)*55lKxbKpF?}~@; z6G~=imS@`mi?H$0b9GhOH?Vb!;JNfq{yquC1hmY^oHv5@ya@mBs?SHs9oH^gDyh69 z*X<$0(cUoOBQJuZA)+b3W?Y7t@u?Wl3aKp#C77>>8j6YpemlNF9fy?#PGu6=X32ZQ ztJTpmQ(|XxIn*QKN-Fl!WU-;3Y;!7h8PZ90Zs;{zW2e#TjP>KB0ASLhU9)ePjWruD z#U8X&xFw0VsnSCuEd8&W7lF52LsF4s90Pyl!<)`@=3^QWc>O@X6vY2CJ&^78=*Bh?ei$3B1GnIKtd@ldgI#d?6O3$PyE` zqt8y24b%n)tpg|UV>5^PCqfG!A5k7=!>N>}>tffl7%<<)tG9_5DBZMJ zJSguJd=^|NE?6B4`gZalJqTq>HC}wSN}n+lxUZyBivb+<4&#kHyXn~J`8PWo&%mO+ zs3_FskG4#&?d6`%+$laP5b=bE%e$1bcEND$;Fff6=00o4#eB$Nks}~txR6eu2Pn`* zVIo!(XAMF|267x~+yd>Od|c!YGhKd2Rsx1N4u4XFJgVlWyc_XPz04t_SL!E@7||Q@ zp!pU=;V#@(JD4(?j+-TWubD0;fMtRI{7$yoBp`U zs>qt^ZkV4_jj{oU>vO~0&1KMX48s#HXZWUhs@LLOFlBW(SftFTbpqu5hkc=2O3kae(&kdVyzY%PdOF7@{>og5o({%aaBhMCj z)a|2NX6GdGw#!GsXtr&8Tuf19U^e(q7bgu=v_)O;&_K%tRImFkt-}oD#-~HBVcN1a z0@#n2r|RoW_FgxYoRP8KwHFpD&K~0JmbRih`*Kh%n4WFz0HYx`W_t$=Ye0;mMNIv0 z-H@>F)l986R`#abn?(QOR(dzk-v#FGsGK2$uJYHIHo^o)?URalqMt`e=Orq1gNsUcZT7B;d z7bs5)e|oE`$Y847i;0ZCbQO2}w1#Qe@?s|kpi$m&!Xlx4Rj)Qovnk^Uq~56;)M}Q} z?q=RCEJla*g)VlIl{@#7Z-OxYiN=9KlzBdYD6Qevh$7E z39Bd%a7Bi9EiAUGk`6*!5;kt!S5Pa%?LZYWo9LmqSw4cplp$hLft66I3>-iQTh~{G z5iUame95MC{Zp}ME`!k6k2Y=R<{5;zK75#{FV0Su0UjMw{DZ?;z$4(y4mmd%FFwAG zo_fqd#m}J9V~=t?ODaFcCkr+v@7DZRAf{}ypG-lA*>V=Yu&WVHMiq8P1xH&c1ksF3gkHn7JyQL1c71 zNWH}v|DeY5AhoE$z(?4X2F-Ch_Sk%jF7?Y_3jj*u8m^=@YeE0K(>)1{NnsF=0M3u= z6?PeP)kX&mgRY%j>kIst$HZvU>sJB^E6O!_F{?&1!DTjNrTVeq7aAil<%!DuI&|iF zbZ&?rU^G6u_SggtjqzQ=H-c8u+3dE0JDZ6jWP7`e&`JH8{`WbHnG3*I|Bn-jHUQie(r1odek==9 zowwghE%1gk2-@1Ti4b$%1%#L>3TSwelwwe^^08@Q`b21Vc`#yg0o+FeCu`i@qu|=libo2PB8G9S_0}&&P3zV)ik`osdgp zIue;B5WOIJaVh%)YG(Os+E$jw=k&0rrZ&>dnEY$47n>x~3q~?sJKYDo zE@V@v#fpUQ()N_e_fLb~I)TJdZhnSxj)bsf zR?+$6bAuV_ti&3`rHIQ5fZpwAvJ$~b)MlSD4z$4W`m>~w!lQ6 zla^F(ct2r2*!uni*Co?NksQkxQrvLO>5a1+Lnx){x=n0yg=%cFrG#e$P`dJjOW3hB zp)YN}bD&Rf*QhnO!Xu~Ct9YlTfELFCNn12(;Xa@#_%p6?RU2yyYPsscTN?C$nkHbh zRSXiyW>F7_>$J2I)0=voTc+VuNc5qR0bfg?uQThS_# zM+gP}JdJ6KWSbwyJYra0o&C3bqmIjp!b~PL{rD8Ht40LR#dF%0|xMlGC6s_glj(p|^wqbzgyhSJK^Lwtt9F%+~ZE&mDBMvHeNj7s|oI^It zzm!tIrefMLd5hh&=L2HoFa{f(lJ%td0z!Iix;Ro)5OA(W%r{L$uSz_Y-M>V&CR%tHfGb@&MCIv%>_4d0+Z|n z(~lt_WBYjsVSB-L6#BpEhZG{P^w^f>RkclQOvkv`LZo7@opU@V!f+aOR9$5G;e3B9 z1&M9P^>GU3^?ShGDCk8@c30rRo!l{IE*d!6PRAy4sNJ3C_WI>LXUgoxm>pyi(gkW! zm1CMtDTLsv&NuRfGdyt|0AW)J|LO~A5IB0@l1_QG2O(lJxFE%83IU#^e-0JnLGrKv zD*1lq*dH}lm`FcD2NB;~a=iC`lyfD>4XxJPIC;7#ua0j1I6nO2#nG#Q#0WYPgoG%LC0{(ZKmj`y)ByrkS)po9*4oZLu-dq?Lj^VFtogB1SZbf1k!m28CV^8TdnuW z$miqt>+^@>#`7Q#j2`?8>4_`S824{aMoezHNmCCLLsIlc4&Og6c+4x^$wXJ2;HKuBnuNn{rvYRI`ME*h~;-5xkj>B zhQ%hbhJf$@hu-|UQ(f;cNhsl zhKF_f9vG5OjFO~7ssL($J*0LsiaUsl!pW1y6hSOqh;}`|D;f|vQ>2JseV&^)la$Aw zK(uca53%Fx4oi}fmjY5{CIIup?cZ74 zEmj;rTlfYc>R~-uExZuow_I%T(XDow^jtI+)XK4W6W4zFE}<~XL5{G8 zO13QoPnw3C!%5>;+lOnk%?{`}H>BX3)V@FN0SGkCjUK&ibS`fI29(iCN8XNZ8$RgM z!3JhC`-Uu#5nA%+LHiZOT<&7U%iAUOdhm(7-B$2P=;cz$wL_ph!%XPcXM2C>ia^`w zy@ccvA1_~@+eoPVF9EmMilc`PuXFsyt5@mfXWlo12dfq*DVSD@I|({gEh9R#2K?8L z{(czcjR&D2lN+Mn9%GMXYe$!FrgIVn4|g)Zu5tzV9+*%??V?nXR5rAXNOM+ zOZ+lE-6cLEVflt_X~mwbv&8NdB=)arE0qk#V3wagggOxC1S+&hoKJcAg*O~C+Z?zk0urQ;=XI^GD0u*^U{?&NfepDGZ?`MS22`JLY&tyA#M95 zfsEaq%q&{$qLGFb9#u{9JV3<_Tc;r3Kf{Lcx8G`dIB30+^#?@ULIW0MvGaJvb`gy@zKU$^ckYmSj7s`k2NMHFLZ1jB5-*RiY&PgK4IU% zaTlRkf*O>N+YRvuPsH1;Pvx7bN7yA(zK5|wN-e(|6vCr?VNeHAg#wd%{*Gf4{MfR;g^tQ;AyJ~em#o0vYOoXJ?OhH09R4PNKY7b z?Ao_w|J^3DdQ)H($=!8C<#cXm-jq{FG7`QtEj+b%=aaOJT=W9Fg~?Pp^w3CyoKLx` zyF+bF^->)kKCzVtHOl;UF_20UL|Ug!iWW^dALFH1vEA|*>~%2TKFXo5M?iYQQs5MJ z2SP5<9ga7EZ27_)rHtg&t%f@gpkIfu2X>~3ue-DnI>*F7`#8f;Cx`gfU!uQ{nS`K+K5Q_8xkL~GHf zT*x6ejP9U#Og#e;^CZ`3jg*@!M=7Oyo^$+G(n-ZXWUq7Q3+493^55CD#vIdICfi>O z)if{09Qjjkd~jnD#>Pz;Od@5gTPIBT9&M&lUmk%O-v02-M8NMRY5(rOvzVo_z#1;7 z^QH$U*kMso>2kz$h;sUL9OVzgLc0zzcNkw7SZ+opp_~!Et(pluWB+blIHacVrD1nh zq&Qw{1HQvmK%#j?6V^u{FlP0jVgpvs;MGj?qFJvy#AvndHWsN+Kz^z!fL$Aw! zzWg~^g9)USVE3qcY8E9R8rOvr_isP#qAS_MqVv{(%7sv+q(^!)=4@DVA?#(7 z>JUP@t}$gF#WRc@V{gXQkIYbLd%ZS5oaF?udz;bP^94jH!Ycm1XFM1CKM{!7x&A-y z_ka+fIMUx49uGD)xygt~9|z*#pGQBtOa)V9A*9?uDp-J*;CR~oht7@K!9>XoRA?sD zAFY*#m8Y3C6d~r46t6Q||9@`x+JA5N=p6)r_K%DGqs-9?T6g2PcolIDxA=nic?jyh z!c2>MW{fa0YIIJ9@=9G*=oyC_`K~OCi4iIT za)8XL0Sz1+iHxWq&734tx&d$tid|{m??Hvsynbc}*!Vs+Kj=vqzG)xLJnTO;V!63C zy13>e$A6yNBXF80uu$w(X0>Hn%;fM(1<&6sluu-?)H~Od?~Yrlp*OxgD4<*9Ox`W< zTA`rS{Gh+;5OqU-w63Y{*}@f}`Vkg@zPxgSIW$oPGjT9tzFKAAEGXyY7L_#Yu~XII zWBERMXQIKOvEp7)LF08RUEg*scQUo;ZOZ{&5k;Xg5DUFi=ck4#+vy67g;K0SBPyGO z0>CIt1!=t0T51a)jPFjt)b-tJD6)TpnJb?J$`rkTFPczeF;XCoW8%*tTzzi9*0h6m zT(VhGxQ@Q`cJlcM5n&GUkPYr^#BA3}+q_I-U7jN4WLE0Syynlx^G>6W7+Qo04~558 ztNn0oM+%~V`n;e61DB@K!t5u1A~lpDD-y!Ps}+H$biHvUS>;w~IpXRA>r+cHghD;! zHDjG?qv2#j&Qr}QXM#5bibVOXOH{IR_>L~z zR*Zh;EvK)5Vigd@%^HTEd~2Gy=aN0Mf4y(~Y|>oEP)*}slTv2iP7z;lO9t9Z6dVwe9nSOm#2KLZEiM4>l`p51&k${qyQ7W6gt)U^#Ifz}&5Q{BTrT z{e(xC+cUMOu|^tcrQZbwN;?mBaE(Gk+|ysTNl17eogxhWUEgo#zJx$>T`Ex8;E!;{ zJzcYrfN*+IJ_Hxvvq%j9`-0M>rfO! zE8*G7@>?PXKzeRjiToO|(AKM!j_=Rrs0frl5?ljyb9lj01A*cIRuAZqD;2P2eU?z< zUjPz95jH3&RwO6z+shQcwML@G+fnOZYPjNRgi^=b)HM|AjKAjSYG6l@CiP6ptQb4K zLK(J#xC3&sCP=10ct-WcEh#~A(sWef{+AbIh5H*bGG86 z@tib;itaa69ycFlwyA8%#!G62Zn8%qy@Z#_x4>SNA`Sn%}=v+h@KZ=++?Ai>Y z;Ws8|guK}EpvgK7(f|iel`3h9khnsV+6wSOlNl5n-tTydzF2B4c*bu`j*2M7Nh0ce z`JP@Tu)i|nHOK&)MX#MSp-p0`cgdHho+P@s6qt@$4L~FbB7Md1o1H156QZx4*+wYP z4ueKc4aUX9dD-Wgz~?z^xuswqsepPhS_{U!_;++R1efqXYK!F`SUXRgQ3}A~*T7Lo zg;>M}Ach!X(VUp1WSl(_3F4Q7P#`Dn(2f4cV2AI57o6X<#Y@1UZH2Q5$V#1DLs8s| zh@If()vrRKOrAfd`iTsfmfsyXtM4>$CM1$Cb@nlJZrV2K$-%MLGaWH1P0{d4)s-@p;?% zQDSEP#Z;4M^o2OY@v*mB{!i2HpUNA!*qHxwHT&OI#HD{(5i|eGiU_qz;u4)Fn1I11 zwgO^3OHNLCQgd}Kl#xWOLAF2w{9g3nc(k0ol5Qt}CGi6}Mt72_FNz7>U?6E9#rJ>2 z?DvK9x5$-9*0jI1poNjD{|($T#O{m)C%FSh=bRcVT1{~(*gLOjP&YkZ{gYc|$0ES} zM=f11u4LuCfA9=DXJ7l?w)d|Sv90i;BywfzUt;#vzr^g$?9Mm;Lh_03rq`$#{x;QS z&VA#~j*c;KBf3 zIxMnQA_`3;z(|#N>36p=O;^qAVkJH{fH#IeQDG`=Ex!mfgpx+4r-G#33)anEF)r*i z8nH7*n-k)g2Q->U1vdM=s^S*|Y-06dR>`iuElNIicBm?`1^0eyJQomdCUxt-c4A}C zWT|c!UK0t?)+PZPH)1QK_hd3iH5yv@AQ&`DqxhA&N(haGfk`|s1xUjr-%dK3f-bUvkrc^#NLP@bAaDDq-q|0F6pL@ zC41w2)mI5Ow@vgFli`EG=HW+j_jaANCc+rb8gDo2V#Xie7(hvKLfF_oTR7MEM6gy# zn9YcK;1h$wndS$O?6&zkw9v&8;z@$yPf-XL3*%`OLQz0~j{ zPW7+a6oDPQ)!*$^N=DyGVU8IUMiFd*H{pOhA0f~qxbk7F4F-Up*si~Rtr9LNn!fd~ zvcLWEZ;pqj>k!3LuS2S-@pJMDjy>+!AN`yRF~9j({&nWnz5i~UE^rG&a{9DYplXpI!&CO zUnJ<5V>Yk>js5|cUf{)}Z=3+30^|&Byc)kl9VC5@4|hh9JBgk){q2I^YWUZ##{qye z7cQo@BFDZCwq%^5Dm1@$$JdZf`YxRXL3gF1LIjWwyh`%`<@3pcF|Yl&VFBVW?=CaC zd8hU&ABWqlACB2HpBCLd2J4VUNg>fk;)yg>p;Yi)$Ug&GW}@&y4H*CjVN!V0TSy=V z(in&U_rqV+>sP*kkF<#6Q~Kjz=EI;Ie~VJ`ysr5La^Vob;E-NzJ%BAM-PH^`bC^+? z3}7q(P!rS*W%!c#z#>Z24V@7yl9@=0EuDDH&sAhtEyN8gJ4ABuqv|+EnJzx3F?*Xt<*4t~_%avkGFVG7@oP2AsJZ2L zdQc&l13aE3{P_*ynBHEAL-;O&dErIr6zN^oNM8W1qctE~kO7J>Q;LxzJh$(K3b_U` zByMI%NRJqg-G>#^xSAtkT~R_19n!HB1szJooXwO$ezgY`MpeWGYA4kioKX-%7(JYJ z5o5V_&S>Y!u&ahGjtvKE%o@VKI{R60)yw4O15WPzb?XSVo7yYWL_dr$O!VVPH=udv zE0_)U(uP$DUuFb^j!Akm1e3~kIx~>y*$ua7A$=EkH->6V`E0l{V?$?m&ZvKi!~?FrlNoe?(oP}_Uw!2f3ICVn$@ zldj#j7cSOjVq6MTS?P@b-e_GK#Ad`S0+4rRHke+Kp@n`UQQBrEi7TfV{_BWOH94M{ z-kLy5!`m=vn4tY;>b@UbZb0Z3YTcXn|2^W12QDTzj;|2>2%+(vvO&@R%BCH|EcXGC@7+EEy~TUXy+h_cAhC5_!@S;ko* z9Phb{Xl4mPekP?pH5I}igRoxYg0uY=1(oT_PCAo#x70$094a@43htC6WLT7W+TX~| zX}wxpP~?$c$y^gEPlo<`!V49F{L3Q^iE`E?VE@XEHw!68Q$)|{{LPK$ln)2;drGDd zLNEwm7r|*pq?s&~Pm_XJFY^6~m8o7GlSdkY5B5!!gH`&C)YVm2Clc`6wlr2=3Vf4= z4?ntk7ifeII9ge^BOz~bjC_kH~Q_s4`RWisT z?)TrWhCl2P*NVMkZYSi?>!C#W(9~N**e*xHSPo8-IInML7U*kyTac#Wug9WKw3E%@ z>dOy?hd)LkTy>7&1M0w`g0g=r0_A@xf<|9AvcHNTBdV;HUV6?g z`R!?a4SUgTgOL|wKIkNuX2MORzwC@GojlccYBwjIOD=H9>0lj-k@1_hR7Is*FS2vO z(h(~Md4271J!jlB3;y~$vWQBumhjzSc!72_Y@QSVaDyr)E;gF{899D{iS>Z{b%^tDX%SXZ94ikD0C^ z8l_7AdZ#cuX?LN>Ft)u=g{Bzr%10R+Wp=0*ei$f}b61MOjPc;8;f;Km<=ZE%ybTR( zLimANqWctTA2Yq*N5Y*`X&rpb(;su$sbj`o*k2l|fVGzmwlv};-a+v=HRDxy?$IR3 zuNnCl9@7zGjg~NgfWrVMGA$ykP`=oBtqd1Y`Qyi4$ov?2C_QxHwHd&rmF`Oy50gbVRN?$07xQBu2Y5eKmpS zxdUWCI}k&yWwxQh4i3R;OTj+evzNVFnuoe+x1Eh}pj`-5YnCZ%;QHIR`$c_e*&%k$ zk!f)ItL&flAj5Q349TB6lL0#}II-fK%e8aV=vuBYdu!g~0q&wHpA=yaF9y?zps~#r z3Ef4oh;v*AQ{1=VQ`B&_3Q?SX}UeO;zc;lS*syKVxk`>(cyg!tU+WkeN4(=}fs?ZN-dn?}e(oaT4 zQP$iaL0pnkW_;rXm?gJ*!0zg_Dt9GAX>G1lV*0 zD?h3sio8Y7=_Is7i@zre?F_(Ta=*^ONUr$=4$*Cfhdp-~-)&7w&gq22@}u>v z+Zek1)Z5$V=^H(xilifwB1NZ9yMgIWlM5$iroK}9%jQkVs7P6&D~g*kOI}|mi6>2) z6+_Hkmr8Ic<1=C^1}Z6@$}r|8q-6d|Q&J2tvH5II#bR|g{HBu2$xIv%Oya3NQy;{; zd}B8W6oP?mdN#B^yoB{ak#_I@c3MlJs$TJI8$sRqsCjFU$Zk{%_cMZSx!pdV*7zwX zE$4l>Nf z)G)0t2HE-(ljI4kkTIGQ888Nu6QChv7>AnSglq55g~|=Z{&^=9P!0|>$oo@FKlSIT zuD5_bh2iJeE+*b&LY$PT+eIioQe~Jg)d5vS z=Wwd940Q;2caP;SQIL{5QVYHxb?)(quK*`-?SXz4Fy0JQo~{hgIYFH z5Oad{j@^6$L&Oa5Ow(5X6$oZ%W#lXdnxv3WzPJi zrN?%;8cHpSLK5s@`jE~Hx2c^btKBLP7SyIX6_!h7z{F=S{i?yxb$kXCd3FPFcOZ#QQnID^-o75_X=>(uD zhEgPjFegf$hMzj9)v(N1=lRKdj}lct0FApNnjGZtSeqCg3~wX?U?l!FDG==)LPknt z0(|iRSUKv14EY=?fkvOVQNNq9MM0ozvAaUG^5XhA5;;dxHkj+OKLiMO2{e)r(c)?d zBuJnSXm6WocsM)W!U^j2z4P8~p~*v--)y||44TMdOi&pn0yrZEd?yLVf{Cc%^cy6| z;byF2l$~uE@}SWBm7yELDDoh!yjoH^rfarORvNzeQAs-W0n9FavxB)WZAVEG29p&elO)cfKOGf?ZoPOD@JCoM0 zn;W8W4Ypw^$C%)ql(NR|t8C3_8yzmUArNjeAO1z2SR%Z)7*1hJxf-g`(^1x$+1}S# zKbs?UkqnN=Ve^p|GE_pD(X1o0x~bI0O6q35*J;b^?U)nOmD949F{}K?E0WZ^{nCqT z4)1fPt=o2McR}@iS6{08Chn0`bcV11>YE>eUa43cakgF-V5pZstqxaT7)? z*R?`9sU6>aw%xWZrdJ;WF5{W|LsJr)m@pLU$1C4g(3?fZutmhru##|?U3f~WemWST zZcR_`=k2|c>N{F}mNaFrRw0|GYfYKZP>4p-dw7MXs^^SJ||!-M8Pd-U|N=+I%} z%(^sVb3_I?XE8h?#~k=A(*$H4pRTU~IZXgB`q^}58I0oYBl9$8xA=`h$nk$JVs;|Z zYO;-$(}CfU?rjkHN(H4T`J~Rx1_#lPYiIydsmZEG^nFi&47hcm24UT!qguG=8kTOP z>aw$uyLr|T|C)rzaW;hvEca}1-( z&Zh~A$F`qp7J#@ca+c4_BcPN05TrRP-orZ3Pps%G%74EoTwWKQkC{Bpi<29f(giov z`H0y0+|}trM9l(lm~wSB!Ih6M{*jk-Fu*b$L#sw9hci+Qh-sQx-9Rb`>#y6HVfO-jG8 z*1SfO5}fm4DYkL%;<_VydxVXKn9i2vrNNrEIRMImgTxTAGKqMhH1P=sd1&22Qj^36 z9;KgMG;U{2jynROuUH_cPdPKKjCFYek;35wu%)v;&^NIfB#y7QaGF?md2QO?C5>3qL zzCYDd^an`ik456)&!q_;z%4uz;(yQy?EjQ)XJTjiPu+k?b;-Z&JO4%Fv!n_6h3ii7 z2c(0~@508$MuV+66QcG&DSpl>;`1q5NFBjiypE*cIIMoi%~og2Rw!WD7pw(If*iaW zSfW)$V5hv09=`CoeQ#lDZ8XLuA%^uig+zrOWxWb`63Cc(2H(F!nGTM`?<7(jQ{;qj ztwfPd|NhOsC43~|?Td6%=<>v}F?v1N2t)enibwXC{J{Uar9GZuf7|Zu#O8Jwt0cTg zVCs~w0_J4`wYOA0N_JM7E&IaG9HA30?ov^Ac6Kf^J&;5)w)!LacqntT%99d3T_XA= z6&ji1R6iQomn!9nBWdBO9AeU&YXNtSrhsyu#i-Sev#WqzfPBag@?IB6us9p5Y(M2e z3!I5md@VK6ho3UIaCL~*`PPa1m%|s*dGrnnfU?1j>&THXWXMvzVL%6|?}yHAyTtTR z#>~!X3Ip-%8X|IyFk&z})P$mbE0KN$MALL|;c`MOgZZc=N3@Eh{le|bB5nxh@FqM1 zdkaXm?~las6a$RMn_`Q6#CuMzS_#>{O@57u5JPXS+cx+rVa^c{K zP!2N~hn9&~bA{ZFF+VIri%}I<^@>cQ-$|ocDw2h~Z6%v^RkmY!f0nC4w{*H=`Phzc zUB}E7vSRTQQQqj0hNsTxNGB^xM@tH~Q_`6RN+3W~N^3<^_G%eK*2N=QL<{#6Y^N)XL57I_28W3(RLZV zTHw=wCj^Q!%(;sWeStME7vlS6x2#l-m;?_vl_N2)EB>>0#Rm_Sq%;(Nr%WGSMh+UD zqAP7;(~td+8T#l=VQ>@>KAoa06l8?VdN7T~;oo#|7j-kpX+u8BOC=kxOah0aRKbER zw6u$3PoM{`kP6@S%QwgS3KFU$`75J)@&dkx6U#h zrR%I69G4#TLU6fXRD%I)TFf^0y?|#h#;WMtw&ARX8Y>o>jVy1Ie`W$G1TL-b|Ew+m zIx8MACE*(OlzF0Wtm~85f3L1f31%-0k0zx3cJ3M7JDPkdi{JTj&+RMhjT)%Drq1TG^-V_-TX9{fIM| zo$TJpb9jb21aL&KPcI1zw8Rv-P5HGwfiDY3yN{wC1p-GbWzXAZL;$>+o@!` z=0!@|7N)Yxd2royrzx;9gpISA9}n;jy9T1Zb1)>(sw;dARj3a|`7I5NV@b1NrZI%h zbVQIjGt|61T%Xlw_~{r4?M(f{qano7Eu{iVBAx(OS%r3n+|N*jC3ebY0SSBEV+RdK zx{k3$WpLmuMxqEmRhJ(brCu<>Chi%6O^iSyrST!$v^bgQ18f1wo8Zb97^OS(C_XN^ zBFbK|!%m-aj*S_W%Fvy~(40CEu+mV9p{vO19L7vq&dbWp(P%YRQOb!2)+V__dn-5v za)_3hTXfD#IAB91f8@8?*Awm1uFBs;<75s78Y*HJev%3gC@E9?IUzee-d8VmA& zjgu#+uTnyO9MeF`SqY|q4)``>A*YGMuqjZEp1fYUkSjzVkJwPR3DVz-M-Dpdu;aP$ z;DVE}Ldr~;{x>RJ_Ae?OH0Q~)oh`@9huy;ttOkZ5er*4i|Y~gcp4in5owsYmPW4{wwf*8R~M#MgG7Xao4(XmF_V9r zr?-JiPET(d_-X#q$wWvN`?g4Bl=KP%CD7xA+;@83D@T0!G|G);GK%;KZdj6y_o}|B zWA+KGefBy@PS^b=FI74A4|R2)+HMzHOf5S@<*i$e^~y3VIDj$^H; zzs{k2^KK~jbpBEKo95Ok>(`<>>k!DVCb(2c^uWqH9Uk_iPzFB54ju?pEHMsIkvW^G zfmP@6_21!){^WUfweFDqRSU+5!K!I7&@h^+J14+U0W?o^p6UGa8UuPFO>O3rTAS4t zw6-7U_|KN+SehGEP*~mGt&{0fA{$B>n@Rw(8*UiywZhI#m!0=7W@OdYo0A)_nH#{V zmlev3foO0Jg!pq0i+rYStH_h5Q~6m1K~SuYF%HXr`tJpLdPmUHe3=*qpHX_U6=AbY zTx^0I1ZFuFTizn?ue>+7!$GixW2XW{;|RqXb8m)c{$*|=gcFp{6X4LT2~Jj+$qEE{ z_z_9rub;--8i7`_9k zv_f3ga$0`ru{s6FrNVloJJC$4eXBiYId%c&R3jL2V%^cKiIBf%LjS(f=vm_6MWKV@ zMzoMpMQsy*EzxJ>od z2qjj!2wT9@h5^_G(1mH3a8u&DxEU}b$k)4NPUCi7eK51BFH(yOnPp5{F;jNIAv-Iq z@3(PHP9;-aqE@2*W1lN?d$!n4In8cs7I{z(d%VL&VyVYwjy$5j{P0f5_rrkzFd3)2sDD| z(L+j5Tn4F!rhO&VUfU@X9*Scrp({n6rEGT9Wj|G>0iVDOYvl;jHq3=D9kDsI@qqh! zUT+tf^6V?BXo)%kD&GQk2m&dm*wpdrzDY2kY8O^YWvUF76Z&z|5KbUnyFp%?PG_k& zUy;!dhJNUfv}v*cUojI3f0MW%1Y6qeB|3j-OQEq8po1RBo^v^bE2~95pRC8PUd%T6 zG`PSe!!-u?5@trtMlXhl=2|dP7nHcla;FyyK8fwYBV6S_+b@7l~^lPa~`lYGqrKpj`W1?>X z@o7zfvz2Y@BMP_$hhM+>d_cJJV`o<#Ik025;R3wteQ%lwGrspS66~4|EF=6297nv| zulDpt$Tr_o@`<80O!l4c?mU`U*>?OQI#sZ%Fir$~#oOp!@95{ zE4+Br16e$LP+#Tw`|C-F{HZxJ@z~~0=ptSfB`4yzS2~$!@TL;c(`QU>IjZ>RiSY?c zBxSyujEmD2648yEnJe8JHQJ**d@<4XFm&+4iP7N4Om1*;#Txb=;lGK4Bzdo(zDh6? zhN~dd=$>{I zBgk%K=nV#sPItjj9In3~=r{447v=+cQ#JA*deXkPg#Mvrgn{lq2en*i{8zyE={sO7 zQ1CZkOc7h`#R-h`l9E9&2%_3%^pe@MNAYo_{gc2lk$D}uKaM^LJCA8?%P5qiV7gR zoK;`QQ!*ni^n@>p$0rcdJmb1jC}*3sIdCnKAedCwJo)*Z&%JXCF(E>586UP}0kdm9 z*f$ao^L&DPkpJ`r&6aADyCHP2adj_G7fr>m4VZKx>yT<7^Oo0yGXf>nR-5la$cs%m zV|L+m&WAy0Q)w9+8&XaV4$PER^2|ckfsz;#fkFhid)UP5wZs7{E&i++KQ$1r?WE?c z`ZEH-z8Q{_tfpG~@Muh*$CiC@U9tEs-wEjCOJD*GL~vb4h#k~e+5XNCznAd?)O?}5 z3X?f#wKz{iisD}ht?X5yf<6r~n{WA{|BHMTK`He#MRm)d7Dw7(*|Wdvko0Q$Qskqc9ReP4?yNkHDtx=rBUA6TCuznt-cT=5pIawY z@o3Y))s-oye-|)?YOVqbUA`W(IXF*SJ(<5reI!GWh2`}r_EqKWpqNp<=c(*hWd<~f zHcT5o(bEm_OSNd+#MS=9030a>rr*OCEaIH9bA(#%`tG_6^L8N*yyxSDGDA6n>#ipJ z{%RrrdWQL$`NT1q+O)!0ftJ2c;{wOTK!g((DWo#*{8QfoG)oYtcybn%$Kir%Dt88P zmB%UyfWLY%F7QNn_X9}LlrnNNkFLxRZte|1NE5xk83{UKegFJ`g=@f;6a*0q+kpF! zZi!znaP6_7dSTk@;M-Tj1s#WhT_%-$x!rgALO$dac$P`ZPLa}gW4#nmX&t%{`E7dto$i|qS9;XiCLIeQvy>EOb zQg6b&6Z?tSyw8lCWD2TDGegpQ_4 zejG@-3|$^rh*jG`?IP;@9iks$dFY{W{?7Vxet;KW40u0=m?EuE%>HIbOk#nU;-{ojOkrY&xP%!kOu&ag zBq;^GgXYa^{Mvwm{T;r>Psve7%`=;1hDz*;`T9g(Yz>L0+C=>qwaMfn;`*u;XJfqG z^t^q}P~m8t$;OmCWRVL~@-+6qyz|2SeO!s?KOZ0@b0J8HN--_@A-RR%w+UD>P3FO? zreK_bImk*aFGaNDvSR^eylzaqFN0r{y?$6gW^E(0#jf%KIj_HscsLR$y6Mw&@e)>` zG0$@piV7Hh(0>6Yh`|JSGh??!CAvIknn48Y!}Sv*T7S)pKQe{^Cpq`uCC}C*i4)g@ zf8kw4IivcrB^$V+MkPF{69bCIf)gNy)qjcQ!r~)_P+Z957te<5AjC9R;~>YX1j4|b zvbo_YK_RR>L9Y9I)u)IM`zAq{g3p8kKRAOomp%DN5CPHDeT6p$Np2cRE{D=>U6z(-EbS0nb^FIUOl1xwdCTB?_I0=YxvY1;T*R5W^P_4 z5m?bTEN$?n=5OS@|!DWKR<^#eU z$JD7oe%FliI@|iEy|&m{lo-x_un>+>6=wj93pQ@f((T0saIRxKsBh027j(}CBt-Z{ z%J$D~4eDxC^?ELJBd3(U0yu|`Xg@aA0g7)hdN=HDmrpHsY89!ow%6S1unL^gx;8{c zI9^B<&*r*wDPLwS!grRW6S@iEG6xdZzmf%PVbG9PnOn-(G!lyvFQ9~HbymfdPvc~V z{K56+b+IXlST350{jtaX3seV|AO3&eyy@xa|H;W^WTN|zC$t*h6Iv0(?+NX-7@&N~ zR*WF(vM3i{ZO6#eGmAJ_qtFTnu>t{wY`kvI0-Qpj&k-zW}T$X>YCxtlOv!jMmCo65U z{Y*HOqX~_kqpdK=$~Wcp&aqbfdZgbd^cLurK;z|ow+%7HK=aaJAPfq{xT<>m7}%(B z0nzzJ$9DZi$1Yr6-c7S<3_Qa*bN`KVEz} zNkm3M>b#^bhA`B;X28hWmY#+pMIp1yAZGs+4`^<-a@sssEt7mk83?1E=G^{;kl^yYX1*#XH1uI@!Q$JV-uuRaB= z0&46IlM#>g#o*35GY~7<73)a5OQH;Fob@X57_mk`I|G~)A-pV}Ub2GORd`@lRX*K& zLqc_}+m9bozvQ~U=sLyKA&reiPIfU^WBU3nds^WeNL-l4)Cr##nr<>S9u!0#(0DLe zDX3#C>xRi-*Cco2px{nXN+L=j1|y(RmeZ>X{ECv_zVOvphKB|+yk_wSDuAx!uBufp z>><#iOF0QTd~X4?1@nPsO3fY!6oZN!;(Hv>k0Dm!K7s>MH{~x!-p+hl$nrC<*jyx^ zY|PC-5|}c5yy1=hZJEErylN2yK}94=PlEknf1#T}27^vk z)R+3BnAf{MD&qRoDDtXUy^DQdgVlTbm>G>TylnW$+&Y<(#o`O=EQsSWshDr*S}PZ3 zfTFPQ9#cx*aj40meV#~5eeD0HKAp6`M4oM%If}XWc!|5e|!?a{K;_qHs?R9V54&UJSfds@3*Q z=Qa5jV%7GqaIiNv`jL8(P&hY*a>)XEJhEH`ilUX?ObZ7{3VmBlc|jzT2OqqYJ?m5a zqKJdv!6}70`=&rIm)sCL{-~z3Gx2#Q7i8rvHE=>i#usHUv%jnhHig@(zDc^{;{B6w zri~GV7(2kyLpr;hEwQ2zGvaLW@L>;V*Ivt$tNL!=OA8Rjj^uC%MS>#_YSEvP-~{2q zreZuUtJsCDUb~AI)fUAzuV{h@+7CfE`FN)zJ1Kr{DS{&%r%^ zx368A7We1)VM0!DjNQdoFW@Gf^H497%mOFcLG`Q-(aFF}SFm0K#~IepdkPp6%IZUbo1QW%WWd`&vbT`UZ}OI z&t}=%rg8G9j>;6}#E>1Mu1BJ3*0Z@ys}fw!+jzs>Wg%H1f$TFRn+tk$Omq?WCzyiY zIKc=an!z*PX6Pc8GPr|W1L&x0HC`|ms5u)K1FwX?I!!p&!)O7hRQfzU-gVB62}YYo z_nPJB+4{fKO*@#*YXnXEpOU8{j5faeX-v_bg3!<43_b<8R|Lq+XPtE4JN z=!1#LwJTAa!Mf~EhY2aS92Q$;2CKtq`bRVYz(?CRTBc&@4BC~0!L(v$HoJCZ zG;ObFJ-Yz4nD|nb^azXQY`A#H+*W?>qO3wstxUo>>k-g1N*jXEZ=uWj*(wrNoX0qV zJhsCiAn9GHEpB0Uc+dJXl`wJ~bGhZ*FMq1eX2`vP3}`pBUG#`t$j)(QK4^Dc4V-UT zS@X)^N1>$Q9=YApOkK{BZ3Ql|!az<`=RTC2U`N`i9(lyRvSzG8$G*`XounQ*-xP~w z7eb0CBxruQz4YjFg?Idu>SFjO!-J9iKi`r|`&Uby@6{&?#~9zB?eif$V12~l;)bxi zUILho`X)rvK@?ubw%9(Wp3)v_GJ0teg1X;A%J^IYCJ0Ijhuagkuk_34t zr8$fc^n1rnO~zT@TSwm-m8VgdvXrn(f>?tXh9pzyu?_adaD1(PKXDWunQnFn-yXHL zS6WrczU9L+Wsb?hhBV74svw=6O5w`&-NrDWSDf{XS3gD*yaR^Vn=R`z3qWTPg3_Uc zL0Z`C%JwH?)bHo_f&^3P`z~zeh(HF{ERmLg92XJmD8t!}_6V2I#y40%fwIuV{6USY z#0;w@9prJ_xXR8vRs~0 zo+1ftrra0e-XqtE1#^jfAsF3|CVw7)UL!<8RM7YNC1z|Pr?hZD2m;|q_{6tG)txu0 zl^D68J)M0roOK};_@~hB?>GJjdw{1+o8jD+GZ1>MEIKkM4rlxZe~9WSN4?xAb!m`< zJm5QywI3!ZRudX%LU=loetN3qnZU5<3iti;uN zNT;#H35_FKs8FxNY0!efh?)!5`y-NRA<)lEgvm+@_-&}eDyFWdGfX8{aL5AetY0n? z6Oh}35B-!^TYyO>C#3_jWpejDl)cGwY!(}5VAhL2!kC9Plo4nt zH0QycvL|2^qRMIw;*z6c6jp2q_O=0 z#T*ZOj(y4rz%i60PFS^`d$z_=L$?v3+h6qB+}!zgu!OsP>ww4)Nsi$wi5(D;A!2Jj zMda6%8sJXR#$;GT&L@wvukhS#3t1&b6LkEektKEi5mThpSFVfH>l~nUhUpddQ^n0MQ%WE zmXD0Nb)I|07!vsLRi&|R9Fa{#Rb7dl1Hn?rx5T7EE_T`c{f*9qNu?MM`3+A#vJ1wr z9?Wp^h&HI9t$_cHq6zLda&R{iN$Sbqvan-5L>LiJR@5-9<+E_2!Az}dJzOGBWU~5! z2^`%}1|X?RQx%5ZrPk&Uj!DN02|K5>40m_!b=FY_k$an>`*sJIyI-=?y57Y)z%kEV zt#&;(+>aFlh9bOS z+Wf}z;X1jK`u#o~+Gy6NUA~9oA-~HRfwQ@APH8DYqN(f-?cpdk2Y5p1D7JyKSJ^)^ zKxgvN`l`_#Sa$u{#-L~VK^H5bbElOenR)M`M3?=d=r1{({h^ZB`Zm9KA%LVCfzUw1 zK}*nWZb%ZZyymIglqJbCFQcjPQRIt11~5@k?37xc<^z0&?d!2wR^dt5b}(rQRP@fx zFv_#qw4Zco(pEg%20JpW{KK+-M)PRlnqZ*HlQHY7*|uK6d?@KrOKFK?74ZnE+?{f$ zqn$wQ*`N5>*dNfjXhHBu9i3ct+~1xgmJ}?o)H?WBk6P*@v>EGE=(trq-ljKt8xNWF zY5OVm)PI7KzN0t%?-w{b%m2JJ|3A20>~w7Z&Fx}kWd2WY)eGvBa2U7Vu98{M(poQSm{ z2}0JG@+;g?2U-d*0Yw>T2-cD`3knebt>~`~yCP8<$P*LKJ}! z-Y~viKbY~KIp)}25M^x?)JIzO+FgeR)Kv=;z(ft!-b4>%1GKx zC7j5xHj-f_2mn^8fhuXxlrTEu4eoueZOV!8@yyhCctI7K+@DI0bmlfq&kHlubF*a&m$0B zwN7yY^hu2Xd=SnGPTzh24FbJvuogLEh#%4`PtX}vpkQWn?JB`9iv6J|SaCZbtB5Q> zmb1kyf>`|h2AIfG=Aa=|ac!2w&k%y9V#iey&t;$BlD!oA>9|3%ZM{9nIZ*D5ogjGO za9j9&k+JK5Z#Nrv7Q8%*N?O2T$WVQ*vG(MbDC!_UoiX%|ehZydeD*(b`DRv4V0?b6 zzj}j>x8J2fxR8r+myMmTG_1T|@cKCE zf1cjA*sy##+d0i?Z)goPK@xj$XY^cFqqU6RUA7;|f1Q+E?tYxGM!@YXhiT=;F?+KP zz)RkP%BZ%Ysj5Q5IITP2=(<syyFOA+Yz4l!M6^WE z`CxQwIQwjM>pCxyky%21f>3$mO9J98Sn!avD^?q$ zNsb@T3>PXOK&VV2oUD^u5vK4cogcSde~rB3nDF^LP`w5=GN<=5R&DY5e6gW|&1)9F z$7TvvELC&DCPi**l+O$ug1U^^RU<^~C5OFXkx~13t73$s8p9?UfP%LZ4bS#^!7h*) z*ihq+O;Aj9w%!E~bWa()4eEc`;THqH0^{}x8=Tt(MX>2#Nqfc3FL zQ9~N8+vku(H>qL|8mpt}ZtA-BK18aw`azX&H{nkALoz++@@Ddj?4M9~4Htu`JY1To zgccVb%@Cr=IF1S&p6&<8pz_y-?hl29PH080BYF+yFy4WNHGu^=*&=p<_yc=vlguU* z1#JBARK$C&AjN2yL-ctD;(M=l67;56LkM~2+uQ=f1psy2(Ol-orR@kD+fW|C(Gs$8 zYFJ#j4qjY%#L?s&F8X|!47p=WU|jtlqOe%ow#1R%;tb(b-sR}SWeaM&2X(-idR#rO z7()bP#Z1w6_WGVp`@$kG0*a=R8K1f?w_hQ_=13dm(vB5?Q@|-Rwb^1g!}=)JV$E3_j^(DC9(SABZR+z)=E696 z9GJm}kI2fIIc9SKdqEIVopU#Y3;Jd@ND&Dp0S&wYx<3opkRj^KaEHr=jP}@qy}54I zYd2gzkK{dM(TJu2f$`3+M4lY$KcgQZr=XAjn64m?a}#PUK2ttwHN(Jk58b2V$>^zrazdNSzT zI#47b!hhlt5Nf~wg@(2v{_(M&_(DDY5~L6xF}J8a z?;btpU@CrhP!wxr8*M~*Bt~j)1F=5F9v_zZ{XZPOpMSRjMwbs2KR_Q~FG)|?z2Ie5 zSWY!@`Yll#X+U?P8vQ&bfINLDc;Urfh`I4T<`)sYNNxDtZ%l~M?i>cBIA&a7dSr@b zdX%HQc-4ELC7~y3$U88$gGX98DG`t^*pk5)6rSg=%w}KQ^dh|T;KAAX7h zOK7YJQH&9kwVH2#ZLXvYDw7MxTQ>r_@5ZlZWevA5ZprnJI{7E4{wwMwMQ5O31XS%$ zB^(c?bLHyva(X_ruyP0OnpmJE7pFCeB#xA4Pb{9SH5uPRA?nCfj9s#H2bUuPQsTbq z_07_B+{4vPOmZ%e0l!$|0hjbOCh*|Ux!rp7FiL-rNleEraxT?^(;9jXkuw?)s$*#1jG9h(S0)O2@DqzQmR(!-Pz>I2o<TblVC1tpYKXaJ5{bC<4i8p<*K>jX8L#0SzT`|2*Y4KSLTNdt3!b@J+lU7 znzN)!R*eUdi={R|fGtpe*UfvOhRoMJZh+{f9T22S2&weAPJBFsCLq*cP1fd zww@R~?hs|YFA*rH_j-o0VUUO+grmEYVlzLj6xFXesf-SdH`R?OScwa!9`)+>*&6th z@+NO*XJ47%X^P%9@gh=#e)CIYa|;4X+BYaPU@XgFh*UmNoGB}O&kySok?Af11U>L=@HWQpDh40wjJoNvXFlPFRPdI=%|3c%*9ECAW;Fpn(m(sVp`J@WFxTCg;oYT`U04$ z1(nGGG~ghkBq}rU>ghI@p@Ut_;UrVNFmyVLB&tpG6n41%GkV>uUG|@KhMfOXiAO_)(JEb}tFOs%aC=6=5=4KJFnIz{P6rndG zI!9Q6cq+alGN(hrm0CXlcVU0x*w`@3zzj(4KbousNIib_nnTW6s}eu5QCJaSSgr4F z4g%CktIwt4)mB~ImvAvWOIla0N%alP97nLZ zQ1;Hzm3`~BXk4+eVpeS1uGqG1+qP}ns8|)-w(X>nyzI8mx$mC#e(m1<{u}KZbI!5a zTm!Rz=$*-!BUTHVMrhi7u3!_I?#52;3g6#(3Z-uqJHAd2`QUzBs#Zde}mqU4WMBXXwvN z76?fl^-zOl^UMUl#=j05UTT7D0r85Dm(7@5)yd# z*W(VLG3Bn+%PxtmztK8Fq0Wv>dt*{n`p0T^rUCi@P$KZ3DB>g!_&nYUME`Wsf1l~} z1pmtJ=H~u?Au#*@AKJ@*=X6ik&J@BfP}A*Q>LXZpfYGq#jR)xSucJlKkb$5UCm%Rz z$A5JXL|V-zvS>bK7?9ubOYXJD{dIGj!Y~wecf!@5&&t)CXQBBf1cRzgM-BH=u`3o= zN{|1@rJa(^(aquJ2~@>07Z7o34BthZHHbMelH`b~#kjsE0~=Yba`)|| zo{9GKPQge&*EWi*%0NUjJ*3Y3-Rb3=XFHooQK*)fHp;&qn@WZ+3+ZGpoYjeAUQw`m zIhyIpo-y#QDw?Y@OU8A^Dj5{e66VA6dIcJh zQVsrGX$LkR*usLHdJ2VpsZyo>rvDKkMv9>P8tPS3(xop>}T@ zP8g`!CF?jN^nodxVBtzp1oz(gHZ6LFaAZrMFkC=;Q%g-7A~lAQ2Ki^W*vOd+ z;|Mx%o2bwKc1#>i^;!|_XEr$~_oBVx6`^{|%na6K z;Ct}pOL(PDdtL;zMx5bZ%(+NuOOwZ#YL?U#@s=zuS{cUZ~D z^A|cMLpRZovaoeZl$u4={0M9=m5i)77 zJU-401uD+MugZyVdPlULtMB|cJ`DW2Q&iy`GNJ02N4H+cZ2r+^^LO_VQ$nK&2@fxW zYnky4CwMiyYf6gNfD7X|lL83^WMSPww|#oGKi2rmQoQIAT{fHi8A`lJUJ0JAoGZZJ!U5jXzaA zZ+suJYnr8_Rs{YRyT?4cI8x9i0RSzz_i4%vX++b3y#X_JsjULSSuiAVd;~$zMaUYm znPdWrS59fFmOcHVRUK|H6WwhA=uG9zPIea0>*rO`7a;o0%t8@<>nB&BPY0LB17k{ z$$8StJ)xVIw0MIr^VD!-|rWdH+UL4z+U-bccO6_ z9BBWOZvEkws@LFpHFzC*&q>V-fc`%Ie9XhcjgS-vAcYJj+wYLR%rI8IN?H`ir>+lC zQWE%ihCu(+$60+&#*56xb_q`l`!nw7Y8Z3sEw3X<4qpHm6i87UE5aSiLb=cOxIitS z4jCzMpf89wDiXx0|It_pDgVbRIlKx5M})E?skoUF7bbXTIT}}lb~?Ydq|m^T!)A22 zq+RN^yAdhnC5sHu&0P;$HxsV26UGVrhEf9)OR`?HUQds@#aL(tbc%g86uNu5bFwna z24GvF>Y8N975V&2!T^pGwPXc3WoS;=8yr0xIs_6s_X(HWwh~y4ls)5&oEkZ}DWvr) z4a*?@nm^k*D|RvSlGZ2JDz;#D3`DRmdK&}37I5| zLR`YNFkf`zdTd3_rkHW=Q;t$wHbL}HOoY&Z16&-)z;R`~V6TF>bjJx7f?QFJOEID4 zGd2O)xA;T6qX)|a5S&8Cn24ObiCoMULJoMnBm(=9S&cim!AwB9+O%pCC7N= zYs}*=TFMO57$cIIXhWA8E=~YW(3v#ekSYcslC&adcw~wP{Im$XWVc2k)SM@!n$GX6 zc|p~|h^>)b@2-47jb7f?I!qh9jDzDTnlE+h#M9*nz`IU=o>|^;e0Dm_wmvmJ;q+M5 zM$240q|aTT_zd+ifkJ|Y5^?!VFIK&0liVNd`=?`@<)7H9S^jf?-lZ<_EhUcH{q4CH z2bpzx!o>41yI3)s0jb{COaMt@Zh-oeB&5I)(EHV8%Nnjk&QY)-7`n@7`*lQvDszRL zr6v0>>ds`ne^Ga;{HqEJt`^~UM|;liuI#@K;IR%#zbF&ejSI|(oMTXTM=yz9)1U_% zzL~16dw4P+Hs3QV9gP1jMyqFV5_7UFZW!g-Zp+@NWBt@JbA!45?N#C_wY@3REd{By z7v!c5K2|Psgpe4UYv15^d`+{iMJ8*rEYx2d;+*W2_P1-^x{?^}X^yrJo9NmjkRZyP z=%=VV9`~K9sJq6(P@sABA&K>y2|il=*V7NrAiHip69n>~84qCx?nE3yARBf; zKQ2hgF^KByVieo<+50KxK-4IN33{jO9gjXM6k!WQg@_RZ;T0 za-#n}*Oao0&O#PU!b{A^l87w+3}x7g|2GI?ecMRRO4N=MOA+YdPOWwLhXu@9hZgJ~ zaATH9+4%JZ%%Ri2euo-|wG__hBf;itgj`StUL#_0I>lS#{EEXnW&(dpcJLtR9h8<; zSW^TXN)f2>Iq0naKH0Ezn_AFeUisgE|*MY0#P5QHh7Eu@Srrs!C&s$v^GEQEN< zaS@v@;NVUCy{puv4Umz2E@8!`(Jx2G1p(Gp_R?J*YBjN)58hT{<-wCy-)si~t_7l8 zsOooVWJDM?7B@zy(nWX=mMDX5i$8o`uvB$-%eHDVRa)KC ztL&kkb>6)`!&YU;X53@dk)m)u=052MfpA+Gf|gsBf1B-U6=ccm!ab?x!}llUA3kTe zV7MWXAhbuj{L|;iYXD!*ZNg5*MUB7@seKy3C9SYGoAbNX#xTt%wfHHPq0m?A+s5TP zj^D2XN;&m#Lw>8$Jh4C8pt_EzAE<{YN!_@Fsz1g~G@IC%S2#_`h+XZ!rJPgz`S}z6 z1omQMD6+Z0$>MvK9kyJZra|#}xs4#LVlQ=g|Ixw97W7QEv|%Dq*!uzm=0)-g&(CJB zq(9W8AI*gC?H3-7Pck=wt=uYff&fML^{IFi&Ge~skf9QIEr*H2gif0%(>Sqaf&!5zA>MnU$RShu6+_!~u!lq?UY?7g|7l0wkN;-x5QCWNLv?V; zsoO4R_ZNoCcDE`{=e%1qD%#Pvaso#%Fx1>f7twS=A`*G4Xx}rcd_w|vaLD@mO^RRW z8m7n5lsxm88wwdv=J;b`tNv)1!4wgmxcD2VQ8^>Rt0Xr>@ErIeM9x>A2QMa2m5U7+ zfPI8-r+sIM-&^}G+nk-1YH$Hk(5CY7n{y}A$wmmZF{JNF5B8pTzk}p_FsQ|~9H8F# z--%sCHMfD7ihW7U#vBD4=YNTJy7?|Yk@Gk|e*&qpnWUGansj~mf;};}@>C0Qz&I`x z*Y9f@3li3g7|SmJlgJ(txzOpH30&fWne8BW|CqI?WMl5qx&JjE@MF(4_1FBw`Q5Dk zE4Vk8F2wMOXWk}wcHF|jf-l1-coEWa!#|uX3{3yP1;IxDUx~&9|998#P@1&uIz4R2 zcg_npY44dt6Uq3pzIHtxgw?n{zdXQZuLU@xsWIE;{W&oa4%51!k@KFKSy1h3C5x=~KS0yJrAo>h(sIG|e5 zl0?eHj`i*B^8U8=_Vs|7BZs61<&+3IE{+(WT-1L=|6LP*3}SNiJkKkqzdP-*43boD z)8(H#`ixPre5(vEq5)v`e#r@M`RahumL2!t=*nI^tU9aE0Tpk>X2Fq2N7vx9vaE1f zTrloo>iVo(>Ofk>(EI2shA|Z@8xpSwJ;p|gdBD1r*lEBj1Z;kJQ}o(_nY92#DS?Cp zL{?O9(|NpW+z6rhIv=OFO8KDpt^`rzn&{#J$_c#)k!VISX7Mxzyg07MYC77=*Tr%F zQ1}Oi?NQ9?PWEzX%F&MZCW;#np;$m%FO*TP|M?v~vJE708NXY2OS6&`la2^uWgFjh z$lCz`k^RfGv}hduY*>!lL}l8l?Y_J*Rff9`dU=^rPFxpY#ie9d6Zouk=rdDb57Gg?fC2PHWE}Au=mhh~K|b1E5c2g5;B*+&36#lH7+Y zdwr8C23e4Evi1^jQ;H5F&n@#ZnYCax$yOa@_R)WLf$4!x#5I-yFn@{jJ*W58P41vs zzL?a(vgTuf<6`SU;Gw0fG5JNue=2uTmo8d(@GKSj&gplWT>auhLA974E|^R;JUqjQ zY^2qnM_P3M@}^c{lNxTRrK{>{rM$wNj+1^`*1+ugfN^dfOqH3ikXyr)cE+{@75&j{ex5<}H@1_7q2eIVg-`gjt8 z435QJxg|b96@(@n{$VxH|Bu!1f65^E7M-B`uRsYS^MB5x-ld^!tJV6g{8if)dkK?z z-?xiM4?@DQfo=v&{3N77jHptnY_X86piVpIyUnywtffA6wbs?a-;mR}hl>Y)ybs%+ zq+ZG`f5aO9?KQ>I$Z5M96m%=e*0M%U7-jmT;jBNF&`6gwPn7Iyl+jpMSN0ll+wSUt z8Ddp8fizG&L~N7NvGhXmrTegb(R+#mV{ZrvidA@beJK-}CIB`bYTCF75F%y^1hNyk zH7Mkih(SwolNGX1LtSv>hC+3GN@Jy03=PCcpUl^;SGna6QMU8<5Kk)vvJS6}!r{aL zNr~=JUICv+gCgFw&aX>yt&Yq3i4JMmWRTCdRb$+0rXQn>?r%h&0hANu4D}TW0llIQ z7E%R77=eqdhVI+{V=Gy(9?>czsozwXq4#%XtAz6Vf%9BL=3Ko%d*x7y`wFvRW3xIn zxTZ2Wb!v3Ie?9&xSQ$0{UZEaA3Zi(mZBpOS;v05dOzUUJh|Y+WoW%kguvxSwK{a#w zlgL1RRZ_2lF{5RE@tF}l;0Q=7uy2p6P3oyP6xZ*55a%W=0z7m<4>OiyCu)&=Sl`z2 zk~UboY^!>Aw*|GaPa<1#80RIhF*JCCR25oj#hq^RM(*s$A3Cv9@dQ-d7VE7pEv3`Y zU^e=lmN`Ac%*>pVr5eq#S2k1L%s;VZ?YVHVJh)R38l2+jPWzG>yPjSXFEt1Tl4 z&sWpi{+Vp$^|qWZyXHsT=7zK_WiiefR%wJaS%m4JNJ2%3rrTJrM<}%y- z+3Q2+`ehIA@2<^mK0bV8mB7ibkB3P%(-%5^p4_cL3;IQb`LmIpPitrlGn%0zEnm0i ztI};eNCYGq_<0KTj^?$1C9Y z;=@mY8-fquF;zNSTh`hZyB_n$yVpqbN00aOO((wVsY2Zv->sbL?jIqSkDKq}8{Qdq z8_#U`Hf-z9okm+d@8eH*mv5b!x}{g=A#K$(zn>4^&~3$j-`eQKCO)UNsTTImSI+9} z5dJ}Ig30B7U(*wsAuWo&+R>k`QVC}pKKRK7YZ?G^y%2zNz`<~bd*>-g#EWFBJ)fKm19*l$vhr}R zXE@OA0Qof&36p_OSD{ELFB*lcpBkyUV@tLNzC-!gzs6Z>*|lM(S-VPikEU#_F&&QK zVg=@PHX1OgCivi|R&3xwq_KP{vR)O;S|+I4Ugb@tswQaSHFtOfHN%*IumbeQz#$3V zjv$Y3vBT%5W*wysHX;sfQU49-7V4(MR?Tv3MA%BW$Uz_fLdY1@#K{Z4$SEi>2XD+z zj?r8HIm&|0Np?hLhVm@>xT0dc(UBhx5&}YBJzie~L(6#vj3J|_Rxk2*zH-Ff9mr+8 zHDF`9x==|+6L+4H%FzCjH$254o-)O=7;==0VzYS;2F%<5z+g8ios(CdiA>h{t-o1n z!YCAIpSk>j3?}3hruq8`zr%q$o$l4|o=I7}jz>`6kCP?c%i3Vx{n|@mUz)@Eo;Q@2 zN={^x2U1VpMN+8E<1T0JK?XaKGE;$%Uj{BcWQzNq z=nsN!DlG%}lai55&w`D9Zw{7qu!7)lZIF~j!slRR@Z~W=+j6{F4BroXf6|1xzQvB#~zFoWR*zzT%Qh3E;D3EdFFPBJsk&qxU|!Trz1 zgb)+LBscT@%!JVW$yZqDk+&kZYO5-L+H79IBygYbJ1R#tp<(_q-RJ7>Hy9A=_$l$V zX8`n{j#V*Ojs_DRzkF_Bh(^?7O)kjUA{KS50LCS6g#5hz+c`wY1Cc92JE2sAalsiC zg&3iEo)Fl8l+>cw0nyGjUNhJ8jKyoM#l}Js@BC5nT>_E#f zT5u3=JFP!Rq_I>rB{%Ir$_c8vkYE-??i*H;6=o6zw=9QkvC`4Tgotn-1TSNFzLFDRxkfk{6H|Ca>#vvS;E0=5q8Alo0BPie}3#5fM!z%6A$rsz8pOO$5JJbbw zG2-w6;Y<-21B6s&Oo7_|X>?#jo)Ma!F_AEEzYc=xz{!P21#~zpPk~IyZ!N(^-(vQC zPQ_HKcCmlUU4~V*)dA&)NNQy{fPndT;*qpA3i|!X3+-F;#EkVN_GKKpoFn9V$$FiO zFK8pPw8QfI!{h9)M#}N0{us#<FZlQ$CUt<)1-X<}x?R&sXeRXK8+Tyb#8l2};f7zlRTsD@6bckI{siETOu@BJeLv|JW~(MK=Uz$z zg32AIuM@dh5_5NKOkrtiW59}-*oGn{Z=3neIkEkU`V2WYW)&FiUcIJ#K2T)so`$L% z1}sg?G73?&-u)q!SRySLW)1%a)^GQ$QLF|z94T$L6Kzf zIyl#geeAI3^|y$2$cH-3Z1$Kt3tWCB^*1U zD{mR)xK(J80=Pqe$7h1X2*%Vyj6ikSHnXlih;Q1Jh5%Io7k{_&-WkIrQPwFgR-wco zbNYf;Ul#AsCVp|0XfkoZaM1g091AD!Okj97K!NYb>t0yCWU+%f!73T!b0Cz)Wnk6l zuh-lGTbEu|8}rt$Um_OaZi8~lLv43`GQ7HrqqPprm7wrHh_!J90|TRh=hP9I6#*>9 zZu6-lko^$;kNmw2{Sm;^;L@)%-}A;6*o-}eWLPlGc&{75#z9NZ}+tQNSDTKyX1;RaEJ z7ET`s{1f}rQr`j>%|En>Ch~;**LxZ42!Ra!MLVM?l*tg|=$!M@j{P&fGORO)m;)if z8>BHy!Gq=P@h>{1oY>6kNHarE_5CC1M@01V5e6__81JU9sLa~o_dE=U^YGb*;}x$4 zaDSSSX;jPodQ<-O_kbBhfy>|G5NhPatwgP4de>nyTYd)A?!UK~RIXPd5U#lBXeWlE znK)YqD$_#JicoHfx$Fa3KU`=Hj8N^nvzFVCD(}PQZXVxDa)g{W%X1-<5Ou{Z-cWY= zqD)1y|7pr{{O>x&|BXgi|4YK~Kbf)#(!W3jzOnl~mBU5=ZsO|e?}+A=z`Q8|wXuTB z7W9sStBRNFNvFt}IgyBf(jb!WdcIHsYG8e8IRlw?(4_XpHHW5Q&j3}M=O&xsJ?e;g z7+P@5ss==i9aJ^^B4Rjuco7$OXWkBMseR#{T2_D7oX(B&whWiNLUJ82`w0GQ2;#sy z`brT7ku*o|gu1?g5t9lCYn~C7jfitwspFB$*WF2@R-cr}J8yo{N)v1Kp6cBv}Q;@B~|XIQW1wRkWLh=8FTmeWoelyWRbH(8Ldop4eOGB&VlhGv>=o?>KZ&q>1M zhA(DHjel?o)yfzDj6%$bRQBsFPyv`lrEonU2{(=LlX?wBt1VsW%@1hX`>AyabYG*Z{GW z|5R!veta`wkRWpwbytJaPZfD>=NK??KE@=v3H*-dp zq^@O=&ckq48+ep&n&;;ap=YV+x1(pb3@^o*u~p~WA@nb4xMYjOQPup)Q*S==KyQi6 zKPk@OcJ9iMnGLR)e}P!;RBsUEhs*{s=Os*MQA8t5x6=?s91wa8t^$XfMHFHYDi{h$ zsRl}*Ullhk1)1btOA8XDz8|bJ*DExwejJ4i`xdFYhU7TJyDm^SpiF`2m52sc;OCO) zjseckT2JLfTCZF_v(Jn?rh`_JcfWqrB4-SIC+Hcu-`8ub0I|sgS=?8bX zII|V+z;O?>^&8a(k5z2I3*3U;5v8KR=6@SB9HZu^Ve3Plq45fJ7$BB~0m0fy<-aS~ z7DI;PeS&{Bz75Nd?oshr+IEM0o)eH7=hY|j%X$TR0)jYHBq=+oui1nKGx_-fyre2y(hpumiD~F( zQe#eZ&CYT{3={5he_-LXL4%z1CilQfz|O+?>PV3z9OMWJqh5g)(OweP@P(XHr$!moY``U;o?OKXv=J)X2^ zK!`yt&^tl#SZ=qFAJ_9yp|)*&1s=%%5e4M{HsJiES%muxn4r#0Lf!w***HspCnO{_ z4yODX2nY;x*&-Su#_y~4PBHE|!Z#|{x1-!I!MxCy+IK&KqsdTwU$2jIa1>Cff&7~j)u_xSnhvDiWfJV400>;3)vKm)GwQLOefUUhZNhh#9${TUGiZQ2HRh zm=SQ$KWbNO!*QA-BN(ul6NM+$45;*xKEptJ^6O}0$p=8NkTEaet|5NPt&5sMka=j< z{y=m2hgdtAgXj2vD61E-Nfd}IG5wdRIVG3Ee zc@<{oA^{LI_(1k)bbKL0(wFG~tYIHW0El{BdMn0vV*ZHJ|f06UTSCD;L<{=mjQ>CczgnEd79vphfKysS_^n z5CJih`3n(|Y4UsI+rQr zqVrq1J144>G}Zdvk?E>~8ESn`adiuZ+xC`lIMH3mGMA=1$ESU0dEk0`Z@#{#$k10} z#~ZB5B%Wrl4SJ}r8f$=k>Lm}B)aY%5*C(g{)HqVw=Tcw*ek5= ztBU)ZvQA$t8_D7(safOZQ3;Wi(1Y7YaHF(H4^2ycu}14Gk+yOm7N?p{RY0oPKeTWD zaA<$uAD?i+C)VWxH`nlt$@W^_B??CH z`!{y#ppSg4`;LdVYi&UOP(4o$$Jd+A?!({n5bazibzEtE~IEZT?K;-=dArt7f;8?3ZiDU0bR>@oy!=o{0QBxHiS z$X9T`L<#D|p;2e3xaOgR3V}tq10?%)1o#hia{yp{8R!iE6ViVl1Q13l}xza=-K`k)^Ve&9D|GAj*ZSft5AGN_MP3i_PL*Equic?x-pj z(XES;w5y?rmM9QNUU_ZYkpI0=Jms* zg7I9Y_!bkT@ph>VSxQeUEy+r@)1V6`yy7YOW;Sy_gpjaI0++3WQ?`gatBrbU!p%eQ z<>&=*7?Q}e&dbK~PbaN_^F{J6=lz(%OW-u?9pcdiDS_!qsO6I~&P-y) zY~9`Z@4PhWU>zl=QTWyuD9Q$E{j&E7NoPsbYnmFXgvY9@1L6?ywoOcji_*sQyUr~% zfK{aA|HxrK60llRUjCSc%vo={&+~1fyECQ@cgt|}e-iByJh%9C+e2@GXubN}A@2z< zjQX6vI%auVV_A}4S$s9X>FXifH{kdV!S`BbqCdO$;li9}fT^ixfSpesrg%7ZPs7+B zE+4&1LiuWmX;TRSjFJs+e>G@a0FiEEa(IBKA0mwgS3zu&R9fvmCoB%h5gKX@uFkL4 zEP*-2O$n$-fMFnW9!E37J8-VwWE{-NV64a5&xSv?J_T3RNSw9RN?ZhZPqoTEc0u{Rd3L$iVdf$^2y?U|?cr`)>fl zNWj9u_P@ef-&g;42LUSwT7AU$u|k=j!L~Io{jL+Mc@0M@RIGXbS#B zxcV95U>cAluu0%$re59uu?4g3WBsE|po*kQt>AParncI5oJ0J|UIe(s6(m4rN? za(1Q|56am+zQDf`d4a@5MI~=s+4+Y+Ljr_)A^ms(mmv3T6_CK4pi=RO?69~uv8ccA zXw8~RtHQ!^b93oe1~dWT4k`yIU@v{Mv_L3nY_NwgfgnE7u=GHly`NE}Qp0fcj{crs zhx8(x`5(RHfSs`&_|RU&EmcBZNOD;4whDOq#aU2*M?a#k|KleJB*>=~JP--&n`#H& zY!7lDQcqwXBIMivN))6YaTc(QohzVMPEi(c8H*0)hcu)6&F{r_M~Qa<6Ve%oTMN{q z`2&<$ISP2E66$N>7*3#%XLhT9%kEj1DdMlBWAh{yWEs}n0B8umXX3}1EN)DIK+O{m z|H1Tb2VtBKpdCs=wbQo?616?uOH1#gbxAG&GLOM-#b-^Ks@BLpYMP#etlT; zEw17t7l^OuXR4wy+9^UWWOxKlmt4_LVznQ;L12IW zE?zH+erz^g<0IdE%0uGs#BdMmVCL2 zW$<2I^?dyH1^&e6TLHboyZK=+qK*HM4EqqTYQX=OZ2|cy)#XuNt}S-N*VB3Cduf&t zWNm&m$J^OTxADPRfQbodeHu*Yy4>q(IEE7IiHh64)UJaQfPsK~jl2G&4_jY^+w&F~ z-=9bI|@qp4FL+-URtigML(m#>M>FuL{Yb8qL~?HxQ+*C&4tL`?6hSJu_nvJGX}Wnc2v);OiPXt8I}CTbGkw^Lb?jsj#zgN z?VK4G%a|)mdkWRfP4PAKJ>2L_qo}&|$S%5SZXC1EH@YY3yt#wAA{zNEK`KMkgh&O& zH`)F57+$!Kzzlv(w|c#SK>)KQflf8BLLFI>B?UpNlo{^PW6(WhH82?AD|~Nr!7A!Z zd=9@aCMB|JFbXCXk$7C3l5knC&b~HDmMRv|7qwRcl+wR0k8ffIq;w0c>%$!QDbgRJrx zq*FFI+&_PAizO=eB0UPd|MtgQ+&A)Y0zYE?N^bZ(EDjfK(OzoqlPKi&ZAZ58RKja^ zIAx^0HI@W+jz_mQxpY{eWgR>{#=R}GK0QT=vJENu)W40L!OzWcJPK0sC6(H~^Ssdf zFt;Om3cy?V?LFIC9T+HdWj``@2~mzM0KIu&(gPNz!^6j66K~%8RQ+>q-usdE`U->N z&AulL&3)WasM4Ks4jN*b{(Qubynq9ur=TyEY7F6qa8=gb>14!($;V|D^#?bC?a8sG z)6FbJzRD;Lv5V-H9SS~SLtVMnhN+a7hp2ON0jxb8&iM5u{i-Q3H5i$XPpNVEg;R5O z-m(wttQk^u?$sH&HmenY6E}djL4Jt$=%XH3m%?!j?F`bkg@tI5^6(t~J)hq$_Ttx_ zL*D4hxN{Dniz=FkB$sqS`9LeD|8{d>?$VEqG1~56A`;sU4r1!Looh~NniL@sFXq

gQt1dY``oL*)s2_7Fk8nQtD1G=$9`j+Z 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

b@{>x%$^ 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 literal 0 HcmV?d00001 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_base.c b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_base.c new file mode 100644 index 000000000..2898f668f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_base.c @@ -0,0 +1,348 @@ +/********************************************************************** + Copyright(c) 2011-2015 Intel Corporation All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**********************************************************************/ + +#include +#include // for memset +#include "ec_code.h" +#include "ec_base.h" // for GF tables +#include "ec_types.h" + +unsigned char gf_mul(unsigned char a, unsigned char b) +{ +#ifndef GF_LARGE_TABLES + int i; + + if ((a == 0) || (b == 0)) + return 0; + + return gff_base[(i = gflog_base[a] + gflog_base[b]) > 254 ? i - 255 : i]; +#else + return gf_mul_table_base[b * 256 + a]; +#endif +} + +unsigned char gf_inv(unsigned char a) +{ +#ifndef GF_LARGE_TABLES + if (a == 0) + return 0; + + return gff_base[255 - gflog_base[a]]; +#else + return gf_inv_table_base[a]; +#endif +} + +void gf_gen_rs_matrix(unsigned char *a, int m, int k) +{ + int i, j; + unsigned char p, gen = 1; + + memset(a, 0, k * m); + for (i = 0; i < k; i++) + a[k * i + i] = 1; + + for (i = k; i < m; i++) { + p = 1; + for (j = 0; j < k; j++) { + a[k * i + j] = p; + p = gf_mul(p, gen); + } + gen = gf_mul(gen, 2); + } +} + +void gf_gen_cauchy1_matrix(unsigned char *a, int m, int k) +{ + int i, j; + unsigned char *p; + + // Identity matrix in high position + memset(a, 0, k * m); + for (i = 0; i < k; i++) + a[k * i + i] = 1; + + // For the rest choose 1/(i + j) | i != j + p = &a[k * k]; + for (i = k; i < m; i++) + for (j = 0; j < k; j++) + *p++ = gf_inv(i ^ j); + +} + +int gf_invert_matrix(unsigned char *in_mat, unsigned char *out_mat, const int n) +{ + int i, j, k; + unsigned char temp; + + // Set out_mat[] to the identity matrix + for (i = 0; i < n * n; i++) // memset(out_mat, 0, n*n) + out_mat[i] = 0; + + for (i = 0; i < n; i++) + out_mat[i * n + i] = 1; + + // Inverse + for (i = 0; i < n; i++) { + // Check for 0 in pivot element + if (in_mat[i * n + i] == 0) { + // Find a row with non-zero in current column and swap + for (j = i + 1; j < n; j++) + if (in_mat[j * n + i]) + break; + + if (j == n) // Couldn't find means it's singular + return -1; + + for (k = 0; k < n; k++) { // Swap rows i,j + temp = in_mat[i * n + k]; + in_mat[i * n + k] = in_mat[j * n + k]; + in_mat[j * n + k] = temp; + + temp = out_mat[i * n + k]; + out_mat[i * n + k] = out_mat[j * n + k]; + out_mat[j * n + k] = temp; + } + } + + temp = gf_inv(in_mat[i * n + i]); // 1/pivot + for (j = 0; j < n; j++) { // Scale row i by 1/pivot + in_mat[i * n + j] = gf_mul(in_mat[i * n + j], temp); + out_mat[i * n + j] = gf_mul(out_mat[i * n + j], temp); + } + + for (j = 0; j < n; j++) { + if (j == i) + continue; + + temp = in_mat[j * n + i]; + for (k = 0; k < n; k++) { + out_mat[j * n + k] ^= gf_mul(temp, out_mat[i * n + k]); + in_mat[j * n + k] ^= gf_mul(temp, in_mat[i * n + k]); + } + } + } + return 0; +} + +// Calculates const table gftbl in GF(2^8) from single input A +// gftbl(A) = {A{00}, A{01}, A{02}, ... , A{0f} }, {A{00}, A{10}, A{20}, ... , A{f0} } + +void gf_vect_mul_init(unsigned char c, unsigned char *tbl) +{ + unsigned char c2 = (c << 1) ^ ((c & 0x80) ? 0x1d : 0); //Mult by GF{2} + unsigned char c4 = (c2 << 1) ^ ((c2 & 0x80) ? 0x1d : 0); //Mult by GF{2} + unsigned char c8 = (c4 << 1) ^ ((c4 & 0x80) ? 0x1d : 0); //Mult by GF{2} + +#if __WORDSIZE == 64 || _WIN64 || __x86_64__ + unsigned long long v1, v2, v4, v8, *t; + unsigned long long v10, v20, v40, v80; + unsigned char c17, c18, c20, c24; + + t = (unsigned long long *)tbl; + + v1 = c * 0x0100010001000100ull; + v2 = c2 * 0x0101000001010000ull; + v4 = c4 * 0x0101010100000000ull; + v8 = c8 * 0x0101010101010101ull; + + v4 = v1 ^ v2 ^ v4; + t[0] = v4; + t[1] = v8 ^ v4; + + c17 = (c8 << 1) ^ ((c8 & 0x80) ? 0x1d : 0); //Mult by GF{2} + c18 = (c17 << 1) ^ ((c17 & 0x80) ? 0x1d : 0); //Mult by GF{2} + c20 = (c18 << 1) ^ ((c18 & 0x80) ? 0x1d : 0); //Mult by GF{2} + c24 = (c20 << 1) ^ ((c20 & 0x80) ? 0x1d : 0); //Mult by GF{2} + + v10 = c17 * 0x0100010001000100ull; + v20 = c18 * 0x0101000001010000ull; + v40 = c20 * 0x0101010100000000ull; + v80 = c24 * 0x0101010101010101ull; + + v40 = v10 ^ v20 ^ v40; + t[2] = v40; + t[3] = v80 ^ v40; + +#else // 32-bit or other + unsigned char c3, c5, c6, c7, c9, c10, c11, c12, c13, c14, c15; + unsigned char c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, + c31; + + c3 = c2 ^ c; + c5 = c4 ^ c; + c6 = c4 ^ c2; + c7 = c4 ^ c3; + + c9 = c8 ^ c; + c10 = c8 ^ c2; + c11 = c8 ^ c3; + c12 = c8 ^ c4; + c13 = c8 ^ c5; + c14 = c8 ^ c6; + c15 = c8 ^ c7; + + tbl[0] = 0; + tbl[1] = c; + tbl[2] = c2; + tbl[3] = c3; + tbl[4] = c4; + tbl[5] = c5; + tbl[6] = c6; + tbl[7] = c7; + tbl[8] = c8; + tbl[9] = c9; + tbl[10] = c10; + tbl[11] = c11; + tbl[12] = c12; + tbl[13] = c13; + tbl[14] = c14; + tbl[15] = c15; + + c17 = (c8 << 1) ^ ((c8 & 0x80) ? 0x1d : 0); //Mult by GF{2} + c18 = (c17 << 1) ^ ((c17 & 0x80) ? 0x1d : 0); //Mult by GF{2} + c19 = c18 ^ c17; + c20 = (c18 << 1) ^ ((c18 & 0x80) ? 0x1d : 0); //Mult by GF{2} + c21 = c20 ^ c17; + c22 = c20 ^ c18; + c23 = c20 ^ c19; + c24 = (c20 << 1) ^ ((c20 & 0x80) ? 0x1d : 0); //Mult by GF{2} + c25 = c24 ^ c17; + c26 = c24 ^ c18; + c27 = c24 ^ c19; + c28 = c24 ^ c20; + c29 = c24 ^ c21; + c30 = c24 ^ c22; + c31 = c24 ^ c23; + + tbl[16] = 0; + tbl[17] = c17; + tbl[18] = c18; + tbl[19] = c19; + tbl[20] = c20; + tbl[21] = c21; + tbl[22] = c22; + tbl[23] = c23; + tbl[24] = c24; + tbl[25] = c25; + tbl[26] = c26; + tbl[27] = c27; + tbl[28] = c28; + tbl[29] = c29; + tbl[30] = c30; + tbl[31] = c31; + +#endif //__WORDSIZE == 64 || _WIN64 || __x86_64__ +} + +void gf_vect_dot_prod_base(int len, int vlen, unsigned char *v, + unsigned char **src, unsigned char *dest) +{ + int i, j; + unsigned char s; + for (i = 0; i < len; i++) { + s = 0; + for (j = 0; j < vlen; j++) + s ^= gf_mul(src[j][i], v[j * 32 + 1]); + + dest[i] = s; + } +} + +void gf_vect_mad_base(int len, int vec, int vec_i, + unsigned char *v, unsigned char *src, unsigned char *dest) +{ + int i; + unsigned char s; + for (i = 0; i < len; i++) { + s = dest[i]; + s ^= gf_mul(src[i], v[vec_i * 32 + 1]); + dest[i] = s; + } +} + +void ec_encode_data_base(int len, int srcs, int dests, unsigned char *v, + unsigned char **src, unsigned char **dest) +{ + int i, j, l; + unsigned char s; + + for (l = 0; l < dests; l++) { + for (i = 0; i < len; i++) { + s = 0; + for (j = 0; j < srcs; j++) + s ^= gf_mul(src[j][i], v[j * 32 + l * srcs * 32 + 1]); + + dest[l][i] = s; + } + } +} + +void ec_encode_data_update_base(int len, int k, int rows, int vec_i, unsigned char *v, + unsigned char *data, unsigned char **dest) +{ + int i, l; + unsigned char s; + + for (l = 0; l < rows; l++) { + for (i = 0; i < len; i++) { + s = dest[l][i]; + s ^= gf_mul(data[i], v[vec_i * 32 + l * k * 32 + 1]); + + dest[l][i] = s; + } + } +} + +void gf_vect_mul_base(int len, unsigned char *a, unsigned char *src, unsigned char *dest) +{ + //2nd element of table array is ref value used to fill it in + unsigned char c = a[1]; + while (len-- > 0) + *dest++ = gf_mul(c, *src++); +} + +struct slver { + UINT16 snum; + UINT8 ver; + UINT8 core; +}; + +// Version info +struct slver gf_vect_mul_init_slver_00020035; +struct slver gf_vect_mul_init_slver = { 0x0035, 0x02, 0x00 }; + +struct slver ec_encode_data_base_slver_00010135; +struct slver ec_encode_data_base_slver = { 0x0135, 0x01, 0x00 }; + +struct slver gf_vect_mul_base_slver_00010136; +struct slver gf_vect_mul_base_slver = { 0x0136, 0x01, 0x00 }; + +struct slver gf_vect_dot_prod_base_slver_00010137; +struct slver gf_vect_dot_prod_base_slver = { 0x0137, 0x01, 0x00 }; diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_base.h b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_base.h new file mode 100644 index 000000000..db4fd9d6c --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_base.h @@ -0,0 +1,6680 @@ +/********************************************************************** + Copyright(c) 2011-2015 Intel Corporation All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**********************************************************************/ + +#ifndef _EC_BASE_H_ +#define _EC_BASE_H_ + +// Global GF(256) tables +#ifndef GF_LARGE_TABLES +unsigned char gff_base[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, + 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0x4c, 0x98, 0x2d, 0x5a, + 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, + 0x60, 0xc0, 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, + 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, 0x46, 0x8c, + 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, + 0xb9, 0x6f, 0xde, 0xa1, 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, + 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, + 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, + 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, 0xd9, 0xaf, 0x43, 0x86, + 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, + 0x67, 0xce, 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, + 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, 0x85, 0x17, + 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, + 0x84, 0x15, 0x2a, 0x54, 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, + 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, + 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, + 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, 0xe3, 0xdb, 0xab, 0x4b, + 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, + 0xae, 0x41, 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, + 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, 0x51, 0xa2, + 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, + 0xac, 0x45, 0x8a, 0x09, 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, + 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16, + 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, + 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01 +}; + +unsigned char gflog_base[] = { + 0x00, 0xff, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, + 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, 0x04, 0x64, 0xe0, 0x0e, + 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, + 0x4c, 0x71, 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, + 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45, 0x1d, 0xb5, + 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, + 0x4d, 0xe4, 0x72, 0xa6, 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, + 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88, + 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, + 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40, 0x1e, 0x42, 0xb6, 0xa3, + 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, + 0xba, 0x3d, 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, + 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57, 0x07, 0x70, + 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, + 0x31, 0xc5, 0xfe, 0x18, 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, + 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e, + 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, + 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61, 0xf2, 0x56, 0xd3, 0xab, + 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, + 0x41, 0xa2, 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, + 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6, 0x6c, 0xa1, + 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, + 0xbb, 0xcc, 0x3e, 0x5a, 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, + 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7, + 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, + 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf +}; +#else +unsigned char gf_mul_table_base[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, + 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, + 0xfe, 0xff, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, + 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, + 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, + 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, + 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, + 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, + 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, + 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 0xc0, 0xc2, + 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, + 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, + 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, + 0x1d, 0x1f, 0x19, 0x1b, 0x15, 0x17, 0x11, 0x13, 0x0d, 0x0f, + 0x09, 0x0b, 0x05, 0x07, 0x01, 0x03, 0x3d, 0x3f, 0x39, 0x3b, + 0x35, 0x37, 0x31, 0x33, 0x2d, 0x2f, 0x29, 0x2b, 0x25, 0x27, + 0x21, 0x23, 0x5d, 0x5f, 0x59, 0x5b, 0x55, 0x57, 0x51, 0x53, + 0x4d, 0x4f, 0x49, 0x4b, 0x45, 0x47, 0x41, 0x43, 0x7d, 0x7f, + 0x79, 0x7b, 0x75, 0x77, 0x71, 0x73, 0x6d, 0x6f, 0x69, 0x6b, + 0x65, 0x67, 0x61, 0x63, 0x9d, 0x9f, 0x99, 0x9b, 0x95, 0x97, + 0x91, 0x93, 0x8d, 0x8f, 0x89, 0x8b, 0x85, 0x87, 0x81, 0x83, + 0xbd, 0xbf, 0xb9, 0xbb, 0xb5, 0xb7, 0xb1, 0xb3, 0xad, 0xaf, + 0xa9, 0xab, 0xa5, 0xa7, 0xa1, 0xa3, 0xdd, 0xdf, 0xd9, 0xdb, + 0xd5, 0xd7, 0xd1, 0xd3, 0xcd, 0xcf, 0xc9, 0xcb, 0xc5, 0xc7, + 0xc1, 0xc3, 0xfd, 0xff, 0xf9, 0xfb, 0xf5, 0xf7, 0xf1, 0xf3, + 0xed, 0xef, 0xe9, 0xeb, 0xe5, 0xe7, 0xe1, 0xe3, 0x00, 0x03, + 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, + 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, + 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, + 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, + 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, 0x50, 0x53, 0x56, 0x55, + 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, + 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, + 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, + 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, + 0xe4, 0xe7, 0xe2, 0xe1, 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, + 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, + 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, + 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9d, 0x9e, 0x9b, 0x98, + 0x91, 0x92, 0x97, 0x94, 0x85, 0x86, 0x83, 0x80, 0x89, 0x8a, + 0x8f, 0x8c, 0xad, 0xae, 0xab, 0xa8, 0xa1, 0xa2, 0xa7, 0xa4, + 0xb5, 0xb6, 0xb3, 0xb0, 0xb9, 0xba, 0xbf, 0xbc, 0xfd, 0xfe, + 0xfb, 0xf8, 0xf1, 0xf2, 0xf7, 0xf4, 0xe5, 0xe6, 0xe3, 0xe0, + 0xe9, 0xea, 0xef, 0xec, 0xcd, 0xce, 0xcb, 0xc8, 0xc1, 0xc2, + 0xc7, 0xc4, 0xd5, 0xd6, 0xd3, 0xd0, 0xd9, 0xda, 0xdf, 0xdc, + 0x5d, 0x5e, 0x5b, 0x58, 0x51, 0x52, 0x57, 0x54, 0x45, 0x46, + 0x43, 0x40, 0x49, 0x4a, 0x4f, 0x4c, 0x6d, 0x6e, 0x6b, 0x68, + 0x61, 0x62, 0x67, 0x64, 0x75, 0x76, 0x73, 0x70, 0x79, 0x7a, + 0x7f, 0x7c, 0x3d, 0x3e, 0x3b, 0x38, 0x31, 0x32, 0x37, 0x34, + 0x25, 0x26, 0x23, 0x20, 0x29, 0x2a, 0x2f, 0x2c, 0x0d, 0x0e, + 0x0b, 0x08, 0x01, 0x02, 0x07, 0x04, 0x15, 0x16, 0x13, 0x10, + 0x19, 0x1a, 0x1f, 0x1c, 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, + 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c, + 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c, 0x60, 0x64, + 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x80, 0x84, 0x88, 0x8c, + 0x90, 0x94, 0x98, 0x9c, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, + 0xb8, 0xbc, 0xc0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4, 0xd8, 0xdc, + 0xe0, 0xe4, 0xe8, 0xec, 0xf0, 0xf4, 0xf8, 0xfc, 0x1d, 0x19, + 0x15, 0x11, 0x0d, 0x09, 0x05, 0x01, 0x3d, 0x39, 0x35, 0x31, + 0x2d, 0x29, 0x25, 0x21, 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, + 0x45, 0x41, 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61, + 0x9d, 0x99, 0x95, 0x91, 0x8d, 0x89, 0x85, 0x81, 0xbd, 0xb9, + 0xb5, 0xb1, 0xad, 0xa9, 0xa5, 0xa1, 0xdd, 0xd9, 0xd5, 0xd1, + 0xcd, 0xc9, 0xc5, 0xc1, 0xfd, 0xf9, 0xf5, 0xf1, 0xed, 0xe9, + 0xe5, 0xe1, 0x3a, 0x3e, 0x32, 0x36, 0x2a, 0x2e, 0x22, 0x26, + 0x1a, 0x1e, 0x12, 0x16, 0x0a, 0x0e, 0x02, 0x06, 0x7a, 0x7e, + 0x72, 0x76, 0x6a, 0x6e, 0x62, 0x66, 0x5a, 0x5e, 0x52, 0x56, + 0x4a, 0x4e, 0x42, 0x46, 0xba, 0xbe, 0xb2, 0xb6, 0xaa, 0xae, + 0xa2, 0xa6, 0x9a, 0x9e, 0x92, 0x96, 0x8a, 0x8e, 0x82, 0x86, + 0xfa, 0xfe, 0xf2, 0xf6, 0xea, 0xee, 0xe2, 0xe6, 0xda, 0xde, + 0xd2, 0xd6, 0xca, 0xce, 0xc2, 0xc6, 0x27, 0x23, 0x2f, 0x2b, + 0x37, 0x33, 0x3f, 0x3b, 0x07, 0x03, 0x0f, 0x0b, 0x17, 0x13, + 0x1f, 0x1b, 0x67, 0x63, 0x6f, 0x6b, 0x77, 0x73, 0x7f, 0x7b, + 0x47, 0x43, 0x4f, 0x4b, 0x57, 0x53, 0x5f, 0x5b, 0xa7, 0xa3, + 0xaf, 0xab, 0xb7, 0xb3, 0xbf, 0xbb, 0x87, 0x83, 0x8f, 0x8b, + 0x97, 0x93, 0x9f, 0x9b, 0xe7, 0xe3, 0xef, 0xeb, 0xf7, 0xf3, + 0xff, 0xfb, 0xc7, 0xc3, 0xcf, 0xcb, 0xd7, 0xd3, 0xdf, 0xdb, + 0x00, 0x05, 0x0a, 0x0f, 0x14, 0x11, 0x1e, 0x1b, 0x28, 0x2d, + 0x22, 0x27, 0x3c, 0x39, 0x36, 0x33, 0x50, 0x55, 0x5a, 0x5f, + 0x44, 0x41, 0x4e, 0x4b, 0x78, 0x7d, 0x72, 0x77, 0x6c, 0x69, + 0x66, 0x63, 0xa0, 0xa5, 0xaa, 0xaf, 0xb4, 0xb1, 0xbe, 0xbb, + 0x88, 0x8d, 0x82, 0x87, 0x9c, 0x99, 0x96, 0x93, 0xf0, 0xf5, + 0xfa, 0xff, 0xe4, 0xe1, 0xee, 0xeb, 0xd8, 0xdd, 0xd2, 0xd7, + 0xcc, 0xc9, 0xc6, 0xc3, 0x5d, 0x58, 0x57, 0x52, 0x49, 0x4c, + 0x43, 0x46, 0x75, 0x70, 0x7f, 0x7a, 0x61, 0x64, 0x6b, 0x6e, + 0x0d, 0x08, 0x07, 0x02, 0x19, 0x1c, 0x13, 0x16, 0x25, 0x20, + 0x2f, 0x2a, 0x31, 0x34, 0x3b, 0x3e, 0xfd, 0xf8, 0xf7, 0xf2, + 0xe9, 0xec, 0xe3, 0xe6, 0xd5, 0xd0, 0xdf, 0xda, 0xc1, 0xc4, + 0xcb, 0xce, 0xad, 0xa8, 0xa7, 0xa2, 0xb9, 0xbc, 0xb3, 0xb6, + 0x85, 0x80, 0x8f, 0x8a, 0x91, 0x94, 0x9b, 0x9e, 0xba, 0xbf, + 0xb0, 0xb5, 0xae, 0xab, 0xa4, 0xa1, 0x92, 0x97, 0x98, 0x9d, + 0x86, 0x83, 0x8c, 0x89, 0xea, 0xef, 0xe0, 0xe5, 0xfe, 0xfb, + 0xf4, 0xf1, 0xc2, 0xc7, 0xc8, 0xcd, 0xd6, 0xd3, 0xdc, 0xd9, + 0x1a, 0x1f, 0x10, 0x15, 0x0e, 0x0b, 0x04, 0x01, 0x32, 0x37, + 0x38, 0x3d, 0x26, 0x23, 0x2c, 0x29, 0x4a, 0x4f, 0x40, 0x45, + 0x5e, 0x5b, 0x54, 0x51, 0x62, 0x67, 0x68, 0x6d, 0x76, 0x73, + 0x7c, 0x79, 0xe7, 0xe2, 0xed, 0xe8, 0xf3, 0xf6, 0xf9, 0xfc, + 0xcf, 0xca, 0xc5, 0xc0, 0xdb, 0xde, 0xd1, 0xd4, 0xb7, 0xb2, + 0xbd, 0xb8, 0xa3, 0xa6, 0xa9, 0xac, 0x9f, 0x9a, 0x95, 0x90, + 0x8b, 0x8e, 0x81, 0x84, 0x47, 0x42, 0x4d, 0x48, 0x53, 0x56, + 0x59, 0x5c, 0x6f, 0x6a, 0x65, 0x60, 0x7b, 0x7e, 0x71, 0x74, + 0x17, 0x12, 0x1d, 0x18, 0x03, 0x06, 0x09, 0x0c, 0x3f, 0x3a, + 0x35, 0x30, 0x2b, 0x2e, 0x21, 0x24, 0x00, 0x06, 0x0c, 0x0a, + 0x18, 0x1e, 0x14, 0x12, 0x30, 0x36, 0x3c, 0x3a, 0x28, 0x2e, + 0x24, 0x22, 0x60, 0x66, 0x6c, 0x6a, 0x78, 0x7e, 0x74, 0x72, + 0x50, 0x56, 0x5c, 0x5a, 0x48, 0x4e, 0x44, 0x42, 0xc0, 0xc6, + 0xcc, 0xca, 0xd8, 0xde, 0xd4, 0xd2, 0xf0, 0xf6, 0xfc, 0xfa, + 0xe8, 0xee, 0xe4, 0xe2, 0xa0, 0xa6, 0xac, 0xaa, 0xb8, 0xbe, + 0xb4, 0xb2, 0x90, 0x96, 0x9c, 0x9a, 0x88, 0x8e, 0x84, 0x82, + 0x9d, 0x9b, 0x91, 0x97, 0x85, 0x83, 0x89, 0x8f, 0xad, 0xab, + 0xa1, 0xa7, 0xb5, 0xb3, 0xb9, 0xbf, 0xfd, 0xfb, 0xf1, 0xf7, + 0xe5, 0xe3, 0xe9, 0xef, 0xcd, 0xcb, 0xc1, 0xc7, 0xd5, 0xd3, + 0xd9, 0xdf, 0x5d, 0x5b, 0x51, 0x57, 0x45, 0x43, 0x49, 0x4f, + 0x6d, 0x6b, 0x61, 0x67, 0x75, 0x73, 0x79, 0x7f, 0x3d, 0x3b, + 0x31, 0x37, 0x25, 0x23, 0x29, 0x2f, 0x0d, 0x0b, 0x01, 0x07, + 0x15, 0x13, 0x19, 0x1f, 0x27, 0x21, 0x2b, 0x2d, 0x3f, 0x39, + 0x33, 0x35, 0x17, 0x11, 0x1b, 0x1d, 0x0f, 0x09, 0x03, 0x05, + 0x47, 0x41, 0x4b, 0x4d, 0x5f, 0x59, 0x53, 0x55, 0x77, 0x71, + 0x7b, 0x7d, 0x6f, 0x69, 0x63, 0x65, 0xe7, 0xe1, 0xeb, 0xed, + 0xff, 0xf9, 0xf3, 0xf5, 0xd7, 0xd1, 0xdb, 0xdd, 0xcf, 0xc9, + 0xc3, 0xc5, 0x87, 0x81, 0x8b, 0x8d, 0x9f, 0x99, 0x93, 0x95, + 0xb7, 0xb1, 0xbb, 0xbd, 0xaf, 0xa9, 0xa3, 0xa5, 0xba, 0xbc, + 0xb6, 0xb0, 0xa2, 0xa4, 0xae, 0xa8, 0x8a, 0x8c, 0x86, 0x80, + 0x92, 0x94, 0x9e, 0x98, 0xda, 0xdc, 0xd6, 0xd0, 0xc2, 0xc4, + 0xce, 0xc8, 0xea, 0xec, 0xe6, 0xe0, 0xf2, 0xf4, 0xfe, 0xf8, + 0x7a, 0x7c, 0x76, 0x70, 0x62, 0x64, 0x6e, 0x68, 0x4a, 0x4c, + 0x46, 0x40, 0x52, 0x54, 0x5e, 0x58, 0x1a, 0x1c, 0x16, 0x10, + 0x02, 0x04, 0x0e, 0x08, 0x2a, 0x2c, 0x26, 0x20, 0x32, 0x34, + 0x3e, 0x38, 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, + 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, + 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, + 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, + 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, + 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, + 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, 0xdd, 0xda, 0xd3, 0xd4, + 0xc1, 0xc6, 0xcf, 0xc8, 0xe5, 0xe2, 0xeb, 0xec, 0xf9, 0xfe, + 0xf7, 0xf0, 0xad, 0xaa, 0xa3, 0xa4, 0xb1, 0xb6, 0xbf, 0xb8, + 0x95, 0x92, 0x9b, 0x9c, 0x89, 0x8e, 0x87, 0x80, 0x3d, 0x3a, + 0x33, 0x34, 0x21, 0x26, 0x2f, 0x28, 0x05, 0x02, 0x0b, 0x0c, + 0x19, 0x1e, 0x17, 0x10, 0x4d, 0x4a, 0x43, 0x44, 0x51, 0x56, + 0x5f, 0x58, 0x75, 0x72, 0x7b, 0x7c, 0x69, 0x6e, 0x67, 0x60, + 0xa7, 0xa0, 0xa9, 0xae, 0xbb, 0xbc, 0xb5, 0xb2, 0x9f, 0x98, + 0x91, 0x96, 0x83, 0x84, 0x8d, 0x8a, 0xd7, 0xd0, 0xd9, 0xde, + 0xcb, 0xcc, 0xc5, 0xc2, 0xef, 0xe8, 0xe1, 0xe6, 0xf3, 0xf4, + 0xfd, 0xfa, 0x47, 0x40, 0x49, 0x4e, 0x5b, 0x5c, 0x55, 0x52, + 0x7f, 0x78, 0x71, 0x76, 0x63, 0x64, 0x6d, 0x6a, 0x37, 0x30, + 0x39, 0x3e, 0x2b, 0x2c, 0x25, 0x22, 0x0f, 0x08, 0x01, 0x06, + 0x13, 0x14, 0x1d, 0x1a, 0x7a, 0x7d, 0x74, 0x73, 0x66, 0x61, + 0x68, 0x6f, 0x42, 0x45, 0x4c, 0x4b, 0x5e, 0x59, 0x50, 0x57, + 0x0a, 0x0d, 0x04, 0x03, 0x16, 0x11, 0x18, 0x1f, 0x32, 0x35, + 0x3c, 0x3b, 0x2e, 0x29, 0x20, 0x27, 0x9a, 0x9d, 0x94, 0x93, + 0x86, 0x81, 0x88, 0x8f, 0xa2, 0xa5, 0xac, 0xab, 0xbe, 0xb9, + 0xb0, 0xb7, 0xea, 0xed, 0xe4, 0xe3, 0xf6, 0xf1, 0xf8, 0xff, + 0xd2, 0xd5, 0xdc, 0xdb, 0xce, 0xc9, 0xc0, 0xc7, 0x00, 0x08, + 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x50, 0x58, + 0x60, 0x68, 0x70, 0x78, 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, + 0xb0, 0xb8, 0xc0, 0xc8, 0xd0, 0xd8, 0xe0, 0xe8, 0xf0, 0xf8, + 0x1d, 0x15, 0x0d, 0x05, 0x3d, 0x35, 0x2d, 0x25, 0x5d, 0x55, + 0x4d, 0x45, 0x7d, 0x75, 0x6d, 0x65, 0x9d, 0x95, 0x8d, 0x85, + 0xbd, 0xb5, 0xad, 0xa5, 0xdd, 0xd5, 0xcd, 0xc5, 0xfd, 0xf5, + 0xed, 0xe5, 0x3a, 0x32, 0x2a, 0x22, 0x1a, 0x12, 0x0a, 0x02, + 0x7a, 0x72, 0x6a, 0x62, 0x5a, 0x52, 0x4a, 0x42, 0xba, 0xb2, + 0xaa, 0xa2, 0x9a, 0x92, 0x8a, 0x82, 0xfa, 0xf2, 0xea, 0xe2, + 0xda, 0xd2, 0xca, 0xc2, 0x27, 0x2f, 0x37, 0x3f, 0x07, 0x0f, + 0x17, 0x1f, 0x67, 0x6f, 0x77, 0x7f, 0x47, 0x4f, 0x57, 0x5f, + 0xa7, 0xaf, 0xb7, 0xbf, 0x87, 0x8f, 0x97, 0x9f, 0xe7, 0xef, + 0xf7, 0xff, 0xc7, 0xcf, 0xd7, 0xdf, 0x74, 0x7c, 0x64, 0x6c, + 0x54, 0x5c, 0x44, 0x4c, 0x34, 0x3c, 0x24, 0x2c, 0x14, 0x1c, + 0x04, 0x0c, 0xf4, 0xfc, 0xe4, 0xec, 0xd4, 0xdc, 0xc4, 0xcc, + 0xb4, 0xbc, 0xa4, 0xac, 0x94, 0x9c, 0x84, 0x8c, 0x69, 0x61, + 0x79, 0x71, 0x49, 0x41, 0x59, 0x51, 0x29, 0x21, 0x39, 0x31, + 0x09, 0x01, 0x19, 0x11, 0xe9, 0xe1, 0xf9, 0xf1, 0xc9, 0xc1, + 0xd9, 0xd1, 0xa9, 0xa1, 0xb9, 0xb1, 0x89, 0x81, 0x99, 0x91, + 0x4e, 0x46, 0x5e, 0x56, 0x6e, 0x66, 0x7e, 0x76, 0x0e, 0x06, + 0x1e, 0x16, 0x2e, 0x26, 0x3e, 0x36, 0xce, 0xc6, 0xde, 0xd6, + 0xee, 0xe6, 0xfe, 0xf6, 0x8e, 0x86, 0x9e, 0x96, 0xae, 0xa6, + 0xbe, 0xb6, 0x53, 0x5b, 0x43, 0x4b, 0x73, 0x7b, 0x63, 0x6b, + 0x13, 0x1b, 0x03, 0x0b, 0x33, 0x3b, 0x23, 0x2b, 0xd3, 0xdb, + 0xc3, 0xcb, 0xf3, 0xfb, 0xe3, 0xeb, 0x93, 0x9b, 0x83, 0x8b, + 0xb3, 0xbb, 0xa3, 0xab, 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, + 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, + 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3d, 0x34, 0x2f, 0x26, + 0x19, 0x10, 0x0b, 0x02, 0x75, 0x7c, 0x67, 0x6e, 0x51, 0x58, + 0x43, 0x4a, 0xad, 0xa4, 0xbf, 0xb6, 0x89, 0x80, 0x9b, 0x92, + 0xe5, 0xec, 0xf7, 0xfe, 0xc1, 0xc8, 0xd3, 0xda, 0x7a, 0x73, + 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, 0x32, 0x3b, 0x20, 0x29, + 0x16, 0x1f, 0x04, 0x0d, 0xea, 0xe3, 0xf8, 0xf1, 0xce, 0xc7, + 0xdc, 0xd5, 0xa2, 0xab, 0xb0, 0xb9, 0x86, 0x8f, 0x94, 0x9d, + 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, + 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, 0xd7, 0xde, 0xc5, 0xcc, + 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, + 0xa9, 0xa0, 0xf4, 0xfd, 0xe6, 0xef, 0xd0, 0xd9, 0xc2, 0xcb, + 0xbc, 0xb5, 0xae, 0xa7, 0x98, 0x91, 0x8a, 0x83, 0x64, 0x6d, + 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, 0x2c, 0x25, 0x3e, 0x37, + 0x08, 0x01, 0x1a, 0x13, 0xc9, 0xc0, 0xdb, 0xd2, 0xed, 0xe4, + 0xff, 0xf6, 0x81, 0x88, 0x93, 0x9a, 0xa5, 0xac, 0xb7, 0xbe, + 0x59, 0x50, 0x4b, 0x42, 0x7d, 0x74, 0x6f, 0x66, 0x11, 0x18, + 0x03, 0x0a, 0x35, 0x3c, 0x27, 0x2e, 0x8e, 0x87, 0x9c, 0x95, + 0xaa, 0xa3, 0xb8, 0xb1, 0xc6, 0xcf, 0xd4, 0xdd, 0xe2, 0xeb, + 0xf0, 0xf9, 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, + 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, 0xb3, 0xba, + 0xa1, 0xa8, 0x97, 0x9e, 0x85, 0x8c, 0xfb, 0xf2, 0xe9, 0xe0, + 0xdf, 0xd6, 0xcd, 0xc4, 0x23, 0x2a, 0x31, 0x38, 0x07, 0x0e, + 0x15, 0x1c, 0x6b, 0x62, 0x79, 0x70, 0x4f, 0x46, 0x5d, 0x54, + 0x00, 0x0a, 0x14, 0x1e, 0x28, 0x22, 0x3c, 0x36, 0x50, 0x5a, + 0x44, 0x4e, 0x78, 0x72, 0x6c, 0x66, 0xa0, 0xaa, 0xb4, 0xbe, + 0x88, 0x82, 0x9c, 0x96, 0xf0, 0xfa, 0xe4, 0xee, 0xd8, 0xd2, + 0xcc, 0xc6, 0x5d, 0x57, 0x49, 0x43, 0x75, 0x7f, 0x61, 0x6b, + 0x0d, 0x07, 0x19, 0x13, 0x25, 0x2f, 0x31, 0x3b, 0xfd, 0xf7, + 0xe9, 0xe3, 0xd5, 0xdf, 0xc1, 0xcb, 0xad, 0xa7, 0xb9, 0xb3, + 0x85, 0x8f, 0x91, 0x9b, 0xba, 0xb0, 0xae, 0xa4, 0x92, 0x98, + 0x86, 0x8c, 0xea, 0xe0, 0xfe, 0xf4, 0xc2, 0xc8, 0xd6, 0xdc, + 0x1a, 0x10, 0x0e, 0x04, 0x32, 0x38, 0x26, 0x2c, 0x4a, 0x40, + 0x5e, 0x54, 0x62, 0x68, 0x76, 0x7c, 0xe7, 0xed, 0xf3, 0xf9, + 0xcf, 0xc5, 0xdb, 0xd1, 0xb7, 0xbd, 0xa3, 0xa9, 0x9f, 0x95, + 0x8b, 0x81, 0x47, 0x4d, 0x53, 0x59, 0x6f, 0x65, 0x7b, 0x71, + 0x17, 0x1d, 0x03, 0x09, 0x3f, 0x35, 0x2b, 0x21, 0x69, 0x63, + 0x7d, 0x77, 0x41, 0x4b, 0x55, 0x5f, 0x39, 0x33, 0x2d, 0x27, + 0x11, 0x1b, 0x05, 0x0f, 0xc9, 0xc3, 0xdd, 0xd7, 0xe1, 0xeb, + 0xf5, 0xff, 0x99, 0x93, 0x8d, 0x87, 0xb1, 0xbb, 0xa5, 0xaf, + 0x34, 0x3e, 0x20, 0x2a, 0x1c, 0x16, 0x08, 0x02, 0x64, 0x6e, + 0x70, 0x7a, 0x4c, 0x46, 0x58, 0x52, 0x94, 0x9e, 0x80, 0x8a, + 0xbc, 0xb6, 0xa8, 0xa2, 0xc4, 0xce, 0xd0, 0xda, 0xec, 0xe6, + 0xf8, 0xf2, 0xd3, 0xd9, 0xc7, 0xcd, 0xfb, 0xf1, 0xef, 0xe5, + 0x83, 0x89, 0x97, 0x9d, 0xab, 0xa1, 0xbf, 0xb5, 0x73, 0x79, + 0x67, 0x6d, 0x5b, 0x51, 0x4f, 0x45, 0x23, 0x29, 0x37, 0x3d, + 0x0b, 0x01, 0x1f, 0x15, 0x8e, 0x84, 0x9a, 0x90, 0xa6, 0xac, + 0xb2, 0xb8, 0xde, 0xd4, 0xca, 0xc0, 0xf6, 0xfc, 0xe2, 0xe8, + 0x2e, 0x24, 0x3a, 0x30, 0x06, 0x0c, 0x12, 0x18, 0x7e, 0x74, + 0x6a, 0x60, 0x56, 0x5c, 0x42, 0x48, 0x00, 0x0b, 0x16, 0x1d, + 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, + 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, + 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7d, 0x76, + 0x6b, 0x60, 0x51, 0x5a, 0x47, 0x4c, 0x25, 0x2e, 0x33, 0x38, + 0x09, 0x02, 0x1f, 0x14, 0xcd, 0xc6, 0xdb, 0xd0, 0xe1, 0xea, + 0xf7, 0xfc, 0x95, 0x9e, 0x83, 0x88, 0xb9, 0xb2, 0xaf, 0xa4, + 0xfa, 0xf1, 0xec, 0xe7, 0xd6, 0xdd, 0xc0, 0xcb, 0xa2, 0xa9, + 0xb4, 0xbf, 0x8e, 0x85, 0x98, 0x93, 0x4a, 0x41, 0x5c, 0x57, + 0x66, 0x6d, 0x70, 0x7b, 0x12, 0x19, 0x04, 0x0f, 0x3e, 0x35, + 0x28, 0x23, 0x87, 0x8c, 0x91, 0x9a, 0xab, 0xa0, 0xbd, 0xb6, + 0xdf, 0xd4, 0xc9, 0xc2, 0xf3, 0xf8, 0xe5, 0xee, 0x37, 0x3c, + 0x21, 0x2a, 0x1b, 0x10, 0x0d, 0x06, 0x6f, 0x64, 0x79, 0x72, + 0x43, 0x48, 0x55, 0x5e, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, + 0xd3, 0xd8, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, + 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, 0x01, 0x0a, + 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x94, 0x9f, 0x82, 0x89, + 0xb8, 0xb3, 0xae, 0xa5, 0xcc, 0xc7, 0xda, 0xd1, 0xe0, 0xeb, + 0xf6, 0xfd, 0x24, 0x2f, 0x32, 0x39, 0x08, 0x03, 0x1e, 0x15, + 0x7c, 0x77, 0x6a, 0x61, 0x50, 0x5b, 0x46, 0x4d, 0x13, 0x18, + 0x05, 0x0e, 0x3f, 0x34, 0x29, 0x22, 0x4b, 0x40, 0x5d, 0x56, + 0x67, 0x6c, 0x71, 0x7a, 0xa3, 0xa8, 0xb5, 0xbe, 0x8f, 0x84, + 0x99, 0x92, 0xfb, 0xf0, 0xed, 0xe6, 0xd7, 0xdc, 0xc1, 0xca, + 0x6e, 0x65, 0x78, 0x73, 0x42, 0x49, 0x54, 0x5f, 0x36, 0x3d, + 0x20, 0x2b, 0x1a, 0x11, 0x0c, 0x07, 0xde, 0xd5, 0xc8, 0xc3, + 0xf2, 0xf9, 0xe4, 0xef, 0x86, 0x8d, 0x90, 0x9b, 0xaa, 0xa1, + 0xbc, 0xb7, 0x00, 0x0c, 0x18, 0x14, 0x30, 0x3c, 0x28, 0x24, + 0x60, 0x6c, 0x78, 0x74, 0x50, 0x5c, 0x48, 0x44, 0xc0, 0xcc, + 0xd8, 0xd4, 0xf0, 0xfc, 0xe8, 0xe4, 0xa0, 0xac, 0xb8, 0xb4, + 0x90, 0x9c, 0x88, 0x84, 0x9d, 0x91, 0x85, 0x89, 0xad, 0xa1, + 0xb5, 0xb9, 0xfd, 0xf1, 0xe5, 0xe9, 0xcd, 0xc1, 0xd5, 0xd9, + 0x5d, 0x51, 0x45, 0x49, 0x6d, 0x61, 0x75, 0x79, 0x3d, 0x31, + 0x25, 0x29, 0x0d, 0x01, 0x15, 0x19, 0x27, 0x2b, 0x3f, 0x33, + 0x17, 0x1b, 0x0f, 0x03, 0x47, 0x4b, 0x5f, 0x53, 0x77, 0x7b, + 0x6f, 0x63, 0xe7, 0xeb, 0xff, 0xf3, 0xd7, 0xdb, 0xcf, 0xc3, + 0x87, 0x8b, 0x9f, 0x93, 0xb7, 0xbb, 0xaf, 0xa3, 0xba, 0xb6, + 0xa2, 0xae, 0x8a, 0x86, 0x92, 0x9e, 0xda, 0xd6, 0xc2, 0xce, + 0xea, 0xe6, 0xf2, 0xfe, 0x7a, 0x76, 0x62, 0x6e, 0x4a, 0x46, + 0x52, 0x5e, 0x1a, 0x16, 0x02, 0x0e, 0x2a, 0x26, 0x32, 0x3e, + 0x4e, 0x42, 0x56, 0x5a, 0x7e, 0x72, 0x66, 0x6a, 0x2e, 0x22, + 0x36, 0x3a, 0x1e, 0x12, 0x06, 0x0a, 0x8e, 0x82, 0x96, 0x9a, + 0xbe, 0xb2, 0xa6, 0xaa, 0xee, 0xe2, 0xf6, 0xfa, 0xde, 0xd2, + 0xc6, 0xca, 0xd3, 0xdf, 0xcb, 0xc7, 0xe3, 0xef, 0xfb, 0xf7, + 0xb3, 0xbf, 0xab, 0xa7, 0x83, 0x8f, 0x9b, 0x97, 0x13, 0x1f, + 0x0b, 0x07, 0x23, 0x2f, 0x3b, 0x37, 0x73, 0x7f, 0x6b, 0x67, + 0x43, 0x4f, 0x5b, 0x57, 0x69, 0x65, 0x71, 0x7d, 0x59, 0x55, + 0x41, 0x4d, 0x09, 0x05, 0x11, 0x1d, 0x39, 0x35, 0x21, 0x2d, + 0xa9, 0xa5, 0xb1, 0xbd, 0x99, 0x95, 0x81, 0x8d, 0xc9, 0xc5, + 0xd1, 0xdd, 0xf9, 0xf5, 0xe1, 0xed, 0xf4, 0xf8, 0xec, 0xe0, + 0xc4, 0xc8, 0xdc, 0xd0, 0x94, 0x98, 0x8c, 0x80, 0xa4, 0xa8, + 0xbc, 0xb0, 0x34, 0x38, 0x2c, 0x20, 0x04, 0x08, 0x1c, 0x10, + 0x54, 0x58, 0x4c, 0x40, 0x64, 0x68, 0x7c, 0x70, 0x00, 0x0d, + 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, + 0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, + 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, + 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, + 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, 0x6d, 0x60, 0x77, 0x7a, + 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, + 0x2b, 0x26, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, + 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0xb7, 0xba, + 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, + 0xeb, 0xe6, 0xf1, 0xfc, 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, + 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, + 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, + 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, 0xce, 0xc3, 0xd4, 0xd9, + 0xfa, 0xf7, 0xe0, 0xed, 0xa6, 0xab, 0xbc, 0xb1, 0x92, 0x9f, + 0x88, 0x85, 0x1e, 0x13, 0x04, 0x09, 0x2a, 0x27, 0x30, 0x3d, + 0x76, 0x7b, 0x6c, 0x61, 0x42, 0x4f, 0x58, 0x55, 0x73, 0x7e, + 0x69, 0x64, 0x47, 0x4a, 0x5d, 0x50, 0x1b, 0x16, 0x01, 0x0c, + 0x2f, 0x22, 0x35, 0x38, 0xa3, 0xae, 0xb9, 0xb4, 0x97, 0x9a, + 0x8d, 0x80, 0xcb, 0xc6, 0xd1, 0xdc, 0xff, 0xf2, 0xe5, 0xe8, + 0xa9, 0xa4, 0xb3, 0xbe, 0x9d, 0x90, 0x87, 0x8a, 0xc1, 0xcc, + 0xdb, 0xd6, 0xf5, 0xf8, 0xef, 0xe2, 0x79, 0x74, 0x63, 0x6e, + 0x4d, 0x40, 0x57, 0x5a, 0x11, 0x1c, 0x0b, 0x06, 0x25, 0x28, + 0x3f, 0x32, 0x14, 0x19, 0x0e, 0x03, 0x20, 0x2d, 0x3a, 0x37, + 0x7c, 0x71, 0x66, 0x6b, 0x48, 0x45, 0x52, 0x5f, 0xc4, 0xc9, + 0xde, 0xd3, 0xf0, 0xfd, 0xea, 0xe7, 0xac, 0xa1, 0xb6, 0xbb, + 0x98, 0x95, 0x82, 0x8f, 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, + 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, + 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, + 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdd, 0xd3, 0xc1, 0xcf, + 0xe5, 0xeb, 0xf9, 0xf7, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, + 0x89, 0x87, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, + 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0xa7, 0xa9, + 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, 0xd7, 0xd9, 0xcb, 0xc5, + 0xef, 0xe1, 0xf3, 0xfd, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, + 0x63, 0x6d, 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, + 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, + 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, 0x9a, 0x94, 0x86, 0x88, + 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, + 0xce, 0xc0, 0x53, 0x5d, 0x4f, 0x41, 0x6b, 0x65, 0x77, 0x79, + 0x23, 0x2d, 0x3f, 0x31, 0x1b, 0x15, 0x07, 0x09, 0xb3, 0xbd, + 0xaf, 0xa1, 0x8b, 0x85, 0x97, 0x99, 0xc3, 0xcd, 0xdf, 0xd1, + 0xfb, 0xf5, 0xe7, 0xe9, 0x8e, 0x80, 0x92, 0x9c, 0xb6, 0xb8, + 0xaa, 0xa4, 0xfe, 0xf0, 0xe2, 0xec, 0xc6, 0xc8, 0xda, 0xd4, + 0x6e, 0x60, 0x72, 0x7c, 0x56, 0x58, 0x4a, 0x44, 0x1e, 0x10, + 0x02, 0x0c, 0x26, 0x28, 0x3a, 0x34, 0xf4, 0xfa, 0xe8, 0xe6, + 0xcc, 0xc2, 0xd0, 0xde, 0x84, 0x8a, 0x98, 0x96, 0xbc, 0xb2, + 0xa0, 0xae, 0x14, 0x1a, 0x08, 0x06, 0x2c, 0x22, 0x30, 0x3e, + 0x64, 0x6a, 0x78, 0x76, 0x5c, 0x52, 0x40, 0x4e, 0x29, 0x27, + 0x35, 0x3b, 0x11, 0x1f, 0x0d, 0x03, 0x59, 0x57, 0x45, 0x4b, + 0x61, 0x6f, 0x7d, 0x73, 0xc9, 0xc7, 0xd5, 0xdb, 0xf1, 0xff, + 0xed, 0xe3, 0xb9, 0xb7, 0xa5, 0xab, 0x81, 0x8f, 0x9d, 0x93, + 0x00, 0x0f, 0x1e, 0x11, 0x3c, 0x33, 0x22, 0x2d, 0x78, 0x77, + 0x66, 0x69, 0x44, 0x4b, 0x5a, 0x55, 0xf0, 0xff, 0xee, 0xe1, + 0xcc, 0xc3, 0xd2, 0xdd, 0x88, 0x87, 0x96, 0x99, 0xb4, 0xbb, + 0xaa, 0xa5, 0xfd, 0xf2, 0xe3, 0xec, 0xc1, 0xce, 0xdf, 0xd0, + 0x85, 0x8a, 0x9b, 0x94, 0xb9, 0xb6, 0xa7, 0xa8, 0x0d, 0x02, + 0x13, 0x1c, 0x31, 0x3e, 0x2f, 0x20, 0x75, 0x7a, 0x6b, 0x64, + 0x49, 0x46, 0x57, 0x58, 0xe7, 0xe8, 0xf9, 0xf6, 0xdb, 0xd4, + 0xc5, 0xca, 0x9f, 0x90, 0x81, 0x8e, 0xa3, 0xac, 0xbd, 0xb2, + 0x17, 0x18, 0x09, 0x06, 0x2b, 0x24, 0x35, 0x3a, 0x6f, 0x60, + 0x71, 0x7e, 0x53, 0x5c, 0x4d, 0x42, 0x1a, 0x15, 0x04, 0x0b, + 0x26, 0x29, 0x38, 0x37, 0x62, 0x6d, 0x7c, 0x73, 0x5e, 0x51, + 0x40, 0x4f, 0xea, 0xe5, 0xf4, 0xfb, 0xd6, 0xd9, 0xc8, 0xc7, + 0x92, 0x9d, 0x8c, 0x83, 0xae, 0xa1, 0xb0, 0xbf, 0xd3, 0xdc, + 0xcd, 0xc2, 0xef, 0xe0, 0xf1, 0xfe, 0xab, 0xa4, 0xb5, 0xba, + 0x97, 0x98, 0x89, 0x86, 0x23, 0x2c, 0x3d, 0x32, 0x1f, 0x10, + 0x01, 0x0e, 0x5b, 0x54, 0x45, 0x4a, 0x67, 0x68, 0x79, 0x76, + 0x2e, 0x21, 0x30, 0x3f, 0x12, 0x1d, 0x0c, 0x03, 0x56, 0x59, + 0x48, 0x47, 0x6a, 0x65, 0x74, 0x7b, 0xde, 0xd1, 0xc0, 0xcf, + 0xe2, 0xed, 0xfc, 0xf3, 0xa6, 0xa9, 0xb8, 0xb7, 0x9a, 0x95, + 0x84, 0x8b, 0x34, 0x3b, 0x2a, 0x25, 0x08, 0x07, 0x16, 0x19, + 0x4c, 0x43, 0x52, 0x5d, 0x70, 0x7f, 0x6e, 0x61, 0xc4, 0xcb, + 0xda, 0xd5, 0xf8, 0xf7, 0xe6, 0xe9, 0xbc, 0xb3, 0xa2, 0xad, + 0x80, 0x8f, 0x9e, 0x91, 0xc9, 0xc6, 0xd7, 0xd8, 0xf5, 0xfa, + 0xeb, 0xe4, 0xb1, 0xbe, 0xaf, 0xa0, 0x8d, 0x82, 0x93, 0x9c, + 0x39, 0x36, 0x27, 0x28, 0x05, 0x0a, 0x1b, 0x14, 0x41, 0x4e, + 0x5f, 0x50, 0x7d, 0x72, 0x63, 0x6c, 0x00, 0x10, 0x20, 0x30, + 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, + 0xe0, 0xf0, 0x1d, 0x0d, 0x3d, 0x2d, 0x5d, 0x4d, 0x7d, 0x6d, + 0x9d, 0x8d, 0xbd, 0xad, 0xdd, 0xcd, 0xfd, 0xed, 0x3a, 0x2a, + 0x1a, 0x0a, 0x7a, 0x6a, 0x5a, 0x4a, 0xba, 0xaa, 0x9a, 0x8a, + 0xfa, 0xea, 0xda, 0xca, 0x27, 0x37, 0x07, 0x17, 0x67, 0x77, + 0x47, 0x57, 0xa7, 0xb7, 0x87, 0x97, 0xe7, 0xf7, 0xc7, 0xd7, + 0x74, 0x64, 0x54, 0x44, 0x34, 0x24, 0x14, 0x04, 0xf4, 0xe4, + 0xd4, 0xc4, 0xb4, 0xa4, 0x94, 0x84, 0x69, 0x79, 0x49, 0x59, + 0x29, 0x39, 0x09, 0x19, 0xe9, 0xf9, 0xc9, 0xd9, 0xa9, 0xb9, + 0x89, 0x99, 0x4e, 0x5e, 0x6e, 0x7e, 0x0e, 0x1e, 0x2e, 0x3e, + 0xce, 0xde, 0xee, 0xfe, 0x8e, 0x9e, 0xae, 0xbe, 0x53, 0x43, + 0x73, 0x63, 0x13, 0x03, 0x33, 0x23, 0xd3, 0xc3, 0xf3, 0xe3, + 0x93, 0x83, 0xb3, 0xa3, 0xe8, 0xf8, 0xc8, 0xd8, 0xa8, 0xb8, + 0x88, 0x98, 0x68, 0x78, 0x48, 0x58, 0x28, 0x38, 0x08, 0x18, + 0xf5, 0xe5, 0xd5, 0xc5, 0xb5, 0xa5, 0x95, 0x85, 0x75, 0x65, + 0x55, 0x45, 0x35, 0x25, 0x15, 0x05, 0xd2, 0xc2, 0xf2, 0xe2, + 0x92, 0x82, 0xb2, 0xa2, 0x52, 0x42, 0x72, 0x62, 0x12, 0x02, + 0x32, 0x22, 0xcf, 0xdf, 0xef, 0xff, 0x8f, 0x9f, 0xaf, 0xbf, + 0x4f, 0x5f, 0x6f, 0x7f, 0x0f, 0x1f, 0x2f, 0x3f, 0x9c, 0x8c, + 0xbc, 0xac, 0xdc, 0xcc, 0xfc, 0xec, 0x1c, 0x0c, 0x3c, 0x2c, + 0x5c, 0x4c, 0x7c, 0x6c, 0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, + 0xe1, 0xf1, 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, + 0xa6, 0xb6, 0x86, 0x96, 0xe6, 0xf6, 0xc6, 0xd6, 0x26, 0x36, + 0x06, 0x16, 0x66, 0x76, 0x46, 0x56, 0xbb, 0xab, 0x9b, 0x8b, + 0xfb, 0xeb, 0xdb, 0xcb, 0x3b, 0x2b, 0x1b, 0x0b, 0x7b, 0x6b, + 0x5b, 0x4b, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x0d, 0x1c, + 0x2f, 0x3e, 0x49, 0x58, 0x6b, 0x7a, 0x85, 0x94, 0xa7, 0xb6, + 0xc1, 0xd0, 0xe3, 0xf2, 0x1a, 0x0b, 0x38, 0x29, 0x5e, 0x4f, + 0x7c, 0x6d, 0x92, 0x83, 0xb0, 0xa1, 0xd6, 0xc7, 0xf4, 0xe5, + 0x17, 0x06, 0x35, 0x24, 0x53, 0x42, 0x71, 0x60, 0x9f, 0x8e, + 0xbd, 0xac, 0xdb, 0xca, 0xf9, 0xe8, 0x34, 0x25, 0x16, 0x07, + 0x70, 0x61, 0x52, 0x43, 0xbc, 0xad, 0x9e, 0x8f, 0xf8, 0xe9, + 0xda, 0xcb, 0x39, 0x28, 0x1b, 0x0a, 0x7d, 0x6c, 0x5f, 0x4e, + 0xb1, 0xa0, 0x93, 0x82, 0xf5, 0xe4, 0xd7, 0xc6, 0x2e, 0x3f, + 0x0c, 0x1d, 0x6a, 0x7b, 0x48, 0x59, 0xa6, 0xb7, 0x84, 0x95, + 0xe2, 0xf3, 0xc0, 0xd1, 0x23, 0x32, 0x01, 0x10, 0x67, 0x76, + 0x45, 0x54, 0xab, 0xba, 0x89, 0x98, 0xef, 0xfe, 0xcd, 0xdc, + 0x68, 0x79, 0x4a, 0x5b, 0x2c, 0x3d, 0x0e, 0x1f, 0xe0, 0xf1, + 0xc2, 0xd3, 0xa4, 0xb5, 0x86, 0x97, 0x65, 0x74, 0x47, 0x56, + 0x21, 0x30, 0x03, 0x12, 0xed, 0xfc, 0xcf, 0xde, 0xa9, 0xb8, + 0x8b, 0x9a, 0x72, 0x63, 0x50, 0x41, 0x36, 0x27, 0x14, 0x05, + 0xfa, 0xeb, 0xd8, 0xc9, 0xbe, 0xaf, 0x9c, 0x8d, 0x7f, 0x6e, + 0x5d, 0x4c, 0x3b, 0x2a, 0x19, 0x08, 0xf7, 0xe6, 0xd5, 0xc4, + 0xb3, 0xa2, 0x91, 0x80, 0x5c, 0x4d, 0x7e, 0x6f, 0x18, 0x09, + 0x3a, 0x2b, 0xd4, 0xc5, 0xf6, 0xe7, 0x90, 0x81, 0xb2, 0xa3, + 0x51, 0x40, 0x73, 0x62, 0x15, 0x04, 0x37, 0x26, 0xd9, 0xc8, + 0xfb, 0xea, 0x9d, 0x8c, 0xbf, 0xae, 0x46, 0x57, 0x64, 0x75, + 0x02, 0x13, 0x20, 0x31, 0xce, 0xdf, 0xec, 0xfd, 0x8a, 0x9b, + 0xa8, 0xb9, 0x4b, 0x5a, 0x69, 0x78, 0x0f, 0x1e, 0x2d, 0x3c, + 0xc3, 0xd2, 0xe1, 0xf0, 0x87, 0x96, 0xa5, 0xb4, 0x00, 0x12, + 0x24, 0x36, 0x48, 0x5a, 0x6c, 0x7e, 0x90, 0x82, 0xb4, 0xa6, + 0xd8, 0xca, 0xfc, 0xee, 0x3d, 0x2f, 0x19, 0x0b, 0x75, 0x67, + 0x51, 0x43, 0xad, 0xbf, 0x89, 0x9b, 0xe5, 0xf7, 0xc1, 0xd3, + 0x7a, 0x68, 0x5e, 0x4c, 0x32, 0x20, 0x16, 0x04, 0xea, 0xf8, + 0xce, 0xdc, 0xa2, 0xb0, 0x86, 0x94, 0x47, 0x55, 0x63, 0x71, + 0x0f, 0x1d, 0x2b, 0x39, 0xd7, 0xc5, 0xf3, 0xe1, 0x9f, 0x8d, + 0xbb, 0xa9, 0xf4, 0xe6, 0xd0, 0xc2, 0xbc, 0xae, 0x98, 0x8a, + 0x64, 0x76, 0x40, 0x52, 0x2c, 0x3e, 0x08, 0x1a, 0xc9, 0xdb, + 0xed, 0xff, 0x81, 0x93, 0xa5, 0xb7, 0x59, 0x4b, 0x7d, 0x6f, + 0x11, 0x03, 0x35, 0x27, 0x8e, 0x9c, 0xaa, 0xb8, 0xc6, 0xd4, + 0xe2, 0xf0, 0x1e, 0x0c, 0x3a, 0x28, 0x56, 0x44, 0x72, 0x60, + 0xb3, 0xa1, 0x97, 0x85, 0xfb, 0xe9, 0xdf, 0xcd, 0x23, 0x31, + 0x07, 0x15, 0x6b, 0x79, 0x4f, 0x5d, 0xf5, 0xe7, 0xd1, 0xc3, + 0xbd, 0xaf, 0x99, 0x8b, 0x65, 0x77, 0x41, 0x53, 0x2d, 0x3f, + 0x09, 0x1b, 0xc8, 0xda, 0xec, 0xfe, 0x80, 0x92, 0xa4, 0xb6, + 0x58, 0x4a, 0x7c, 0x6e, 0x10, 0x02, 0x34, 0x26, 0x8f, 0x9d, + 0xab, 0xb9, 0xc7, 0xd5, 0xe3, 0xf1, 0x1f, 0x0d, 0x3b, 0x29, + 0x57, 0x45, 0x73, 0x61, 0xb2, 0xa0, 0x96, 0x84, 0xfa, 0xe8, + 0xde, 0xcc, 0x22, 0x30, 0x06, 0x14, 0x6a, 0x78, 0x4e, 0x5c, + 0x01, 0x13, 0x25, 0x37, 0x49, 0x5b, 0x6d, 0x7f, 0x91, 0x83, + 0xb5, 0xa7, 0xd9, 0xcb, 0xfd, 0xef, 0x3c, 0x2e, 0x18, 0x0a, + 0x74, 0x66, 0x50, 0x42, 0xac, 0xbe, 0x88, 0x9a, 0xe4, 0xf6, + 0xc0, 0xd2, 0x7b, 0x69, 0x5f, 0x4d, 0x33, 0x21, 0x17, 0x05, + 0xeb, 0xf9, 0xcf, 0xdd, 0xa3, 0xb1, 0x87, 0x95, 0x46, 0x54, + 0x62, 0x70, 0x0e, 0x1c, 0x2a, 0x38, 0xd6, 0xc4, 0xf2, 0xe0, + 0x9e, 0x8c, 0xba, 0xa8, 0x00, 0x13, 0x26, 0x35, 0x4c, 0x5f, + 0x6a, 0x79, 0x98, 0x8b, 0xbe, 0xad, 0xd4, 0xc7, 0xf2, 0xe1, + 0x2d, 0x3e, 0x0b, 0x18, 0x61, 0x72, 0x47, 0x54, 0xb5, 0xa6, + 0x93, 0x80, 0xf9, 0xea, 0xdf, 0xcc, 0x5a, 0x49, 0x7c, 0x6f, + 0x16, 0x05, 0x30, 0x23, 0xc2, 0xd1, 0xe4, 0xf7, 0x8e, 0x9d, + 0xa8, 0xbb, 0x77, 0x64, 0x51, 0x42, 0x3b, 0x28, 0x1d, 0x0e, + 0xef, 0xfc, 0xc9, 0xda, 0xa3, 0xb0, 0x85, 0x96, 0xb4, 0xa7, + 0x92, 0x81, 0xf8, 0xeb, 0xde, 0xcd, 0x2c, 0x3f, 0x0a, 0x19, + 0x60, 0x73, 0x46, 0x55, 0x99, 0x8a, 0xbf, 0xac, 0xd5, 0xc6, + 0xf3, 0xe0, 0x01, 0x12, 0x27, 0x34, 0x4d, 0x5e, 0x6b, 0x78, + 0xee, 0xfd, 0xc8, 0xdb, 0xa2, 0xb1, 0x84, 0x97, 0x76, 0x65, + 0x50, 0x43, 0x3a, 0x29, 0x1c, 0x0f, 0xc3, 0xd0, 0xe5, 0xf6, + 0x8f, 0x9c, 0xa9, 0xba, 0x5b, 0x48, 0x7d, 0x6e, 0x17, 0x04, + 0x31, 0x22, 0x75, 0x66, 0x53, 0x40, 0x39, 0x2a, 0x1f, 0x0c, + 0xed, 0xfe, 0xcb, 0xd8, 0xa1, 0xb2, 0x87, 0x94, 0x58, 0x4b, + 0x7e, 0x6d, 0x14, 0x07, 0x32, 0x21, 0xc0, 0xd3, 0xe6, 0xf5, + 0x8c, 0x9f, 0xaa, 0xb9, 0x2f, 0x3c, 0x09, 0x1a, 0x63, 0x70, + 0x45, 0x56, 0xb7, 0xa4, 0x91, 0x82, 0xfb, 0xe8, 0xdd, 0xce, + 0x02, 0x11, 0x24, 0x37, 0x4e, 0x5d, 0x68, 0x7b, 0x9a, 0x89, + 0xbc, 0xaf, 0xd6, 0xc5, 0xf0, 0xe3, 0xc1, 0xd2, 0xe7, 0xf4, + 0x8d, 0x9e, 0xab, 0xb8, 0x59, 0x4a, 0x7f, 0x6c, 0x15, 0x06, + 0x33, 0x20, 0xec, 0xff, 0xca, 0xd9, 0xa0, 0xb3, 0x86, 0x95, + 0x74, 0x67, 0x52, 0x41, 0x38, 0x2b, 0x1e, 0x0d, 0x9b, 0x88, + 0xbd, 0xae, 0xd7, 0xc4, 0xf1, 0xe2, 0x03, 0x10, 0x25, 0x36, + 0x4f, 0x5c, 0x69, 0x7a, 0xb6, 0xa5, 0x90, 0x83, 0xfa, 0xe9, + 0xdc, 0xcf, 0x2e, 0x3d, 0x08, 0x1b, 0x62, 0x71, 0x44, 0x57, + 0x00, 0x14, 0x28, 0x3c, 0x50, 0x44, 0x78, 0x6c, 0xa0, 0xb4, + 0x88, 0x9c, 0xf0, 0xe4, 0xd8, 0xcc, 0x5d, 0x49, 0x75, 0x61, + 0x0d, 0x19, 0x25, 0x31, 0xfd, 0xe9, 0xd5, 0xc1, 0xad, 0xb9, + 0x85, 0x91, 0xba, 0xae, 0x92, 0x86, 0xea, 0xfe, 0xc2, 0xd6, + 0x1a, 0x0e, 0x32, 0x26, 0x4a, 0x5e, 0x62, 0x76, 0xe7, 0xf3, + 0xcf, 0xdb, 0xb7, 0xa3, 0x9f, 0x8b, 0x47, 0x53, 0x6f, 0x7b, + 0x17, 0x03, 0x3f, 0x2b, 0x69, 0x7d, 0x41, 0x55, 0x39, 0x2d, + 0x11, 0x05, 0xc9, 0xdd, 0xe1, 0xf5, 0x99, 0x8d, 0xb1, 0xa5, + 0x34, 0x20, 0x1c, 0x08, 0x64, 0x70, 0x4c, 0x58, 0x94, 0x80, + 0xbc, 0xa8, 0xc4, 0xd0, 0xec, 0xf8, 0xd3, 0xc7, 0xfb, 0xef, + 0x83, 0x97, 0xab, 0xbf, 0x73, 0x67, 0x5b, 0x4f, 0x23, 0x37, + 0x0b, 0x1f, 0x8e, 0x9a, 0xa6, 0xb2, 0xde, 0xca, 0xf6, 0xe2, + 0x2e, 0x3a, 0x06, 0x12, 0x7e, 0x6a, 0x56, 0x42, 0xd2, 0xc6, + 0xfa, 0xee, 0x82, 0x96, 0xaa, 0xbe, 0x72, 0x66, 0x5a, 0x4e, + 0x22, 0x36, 0x0a, 0x1e, 0x8f, 0x9b, 0xa7, 0xb3, 0xdf, 0xcb, + 0xf7, 0xe3, 0x2f, 0x3b, 0x07, 0x13, 0x7f, 0x6b, 0x57, 0x43, + 0x68, 0x7c, 0x40, 0x54, 0x38, 0x2c, 0x10, 0x04, 0xc8, 0xdc, + 0xe0, 0xf4, 0x98, 0x8c, 0xb0, 0xa4, 0x35, 0x21, 0x1d, 0x09, + 0x65, 0x71, 0x4d, 0x59, 0x95, 0x81, 0xbd, 0xa9, 0xc5, 0xd1, + 0xed, 0xf9, 0xbb, 0xaf, 0x93, 0x87, 0xeb, 0xff, 0xc3, 0xd7, + 0x1b, 0x0f, 0x33, 0x27, 0x4b, 0x5f, 0x63, 0x77, 0xe6, 0xf2, + 0xce, 0xda, 0xb6, 0xa2, 0x9e, 0x8a, 0x46, 0x52, 0x6e, 0x7a, + 0x16, 0x02, 0x3e, 0x2a, 0x01, 0x15, 0x29, 0x3d, 0x51, 0x45, + 0x79, 0x6d, 0xa1, 0xb5, 0x89, 0x9d, 0xf1, 0xe5, 0xd9, 0xcd, + 0x5c, 0x48, 0x74, 0x60, 0x0c, 0x18, 0x24, 0x30, 0xfc, 0xe8, + 0xd4, 0xc0, 0xac, 0xb8, 0x84, 0x90, 0x00, 0x15, 0x2a, 0x3f, + 0x54, 0x41, 0x7e, 0x6b, 0xa8, 0xbd, 0x82, 0x97, 0xfc, 0xe9, + 0xd6, 0xc3, 0x4d, 0x58, 0x67, 0x72, 0x19, 0x0c, 0x33, 0x26, + 0xe5, 0xf0, 0xcf, 0xda, 0xb1, 0xa4, 0x9b, 0x8e, 0x9a, 0x8f, + 0xb0, 0xa5, 0xce, 0xdb, 0xe4, 0xf1, 0x32, 0x27, 0x18, 0x0d, + 0x66, 0x73, 0x4c, 0x59, 0xd7, 0xc2, 0xfd, 0xe8, 0x83, 0x96, + 0xa9, 0xbc, 0x7f, 0x6a, 0x55, 0x40, 0x2b, 0x3e, 0x01, 0x14, + 0x29, 0x3c, 0x03, 0x16, 0x7d, 0x68, 0x57, 0x42, 0x81, 0x94, + 0xab, 0xbe, 0xd5, 0xc0, 0xff, 0xea, 0x64, 0x71, 0x4e, 0x5b, + 0x30, 0x25, 0x1a, 0x0f, 0xcc, 0xd9, 0xe6, 0xf3, 0x98, 0x8d, + 0xb2, 0xa7, 0xb3, 0xa6, 0x99, 0x8c, 0xe7, 0xf2, 0xcd, 0xd8, + 0x1b, 0x0e, 0x31, 0x24, 0x4f, 0x5a, 0x65, 0x70, 0xfe, 0xeb, + 0xd4, 0xc1, 0xaa, 0xbf, 0x80, 0x95, 0x56, 0x43, 0x7c, 0x69, + 0x02, 0x17, 0x28, 0x3d, 0x52, 0x47, 0x78, 0x6d, 0x06, 0x13, + 0x2c, 0x39, 0xfa, 0xef, 0xd0, 0xc5, 0xae, 0xbb, 0x84, 0x91, + 0x1f, 0x0a, 0x35, 0x20, 0x4b, 0x5e, 0x61, 0x74, 0xb7, 0xa2, + 0x9d, 0x88, 0xe3, 0xf6, 0xc9, 0xdc, 0xc8, 0xdd, 0xe2, 0xf7, + 0x9c, 0x89, 0xb6, 0xa3, 0x60, 0x75, 0x4a, 0x5f, 0x34, 0x21, + 0x1e, 0x0b, 0x85, 0x90, 0xaf, 0xba, 0xd1, 0xc4, 0xfb, 0xee, + 0x2d, 0x38, 0x07, 0x12, 0x79, 0x6c, 0x53, 0x46, 0x7b, 0x6e, + 0x51, 0x44, 0x2f, 0x3a, 0x05, 0x10, 0xd3, 0xc6, 0xf9, 0xec, + 0x87, 0x92, 0xad, 0xb8, 0x36, 0x23, 0x1c, 0x09, 0x62, 0x77, + 0x48, 0x5d, 0x9e, 0x8b, 0xb4, 0xa1, 0xca, 0xdf, 0xe0, 0xf5, + 0xe1, 0xf4, 0xcb, 0xde, 0xb5, 0xa0, 0x9f, 0x8a, 0x49, 0x5c, + 0x63, 0x76, 0x1d, 0x08, 0x37, 0x22, 0xac, 0xb9, 0x86, 0x93, + 0xf8, 0xed, 0xd2, 0xc7, 0x04, 0x11, 0x2e, 0x3b, 0x50, 0x45, + 0x7a, 0x6f, 0x00, 0x16, 0x2c, 0x3a, 0x58, 0x4e, 0x74, 0x62, + 0xb0, 0xa6, 0x9c, 0x8a, 0xe8, 0xfe, 0xc4, 0xd2, 0x7d, 0x6b, + 0x51, 0x47, 0x25, 0x33, 0x09, 0x1f, 0xcd, 0xdb, 0xe1, 0xf7, + 0x95, 0x83, 0xb9, 0xaf, 0xfa, 0xec, 0xd6, 0xc0, 0xa2, 0xb4, + 0x8e, 0x98, 0x4a, 0x5c, 0x66, 0x70, 0x12, 0x04, 0x3e, 0x28, + 0x87, 0x91, 0xab, 0xbd, 0xdf, 0xc9, 0xf3, 0xe5, 0x37, 0x21, + 0x1b, 0x0d, 0x6f, 0x79, 0x43, 0x55, 0xe9, 0xff, 0xc5, 0xd3, + 0xb1, 0xa7, 0x9d, 0x8b, 0x59, 0x4f, 0x75, 0x63, 0x01, 0x17, + 0x2d, 0x3b, 0x94, 0x82, 0xb8, 0xae, 0xcc, 0xda, 0xe0, 0xf6, + 0x24, 0x32, 0x08, 0x1e, 0x7c, 0x6a, 0x50, 0x46, 0x13, 0x05, + 0x3f, 0x29, 0x4b, 0x5d, 0x67, 0x71, 0xa3, 0xb5, 0x8f, 0x99, + 0xfb, 0xed, 0xd7, 0xc1, 0x6e, 0x78, 0x42, 0x54, 0x36, 0x20, + 0x1a, 0x0c, 0xde, 0xc8, 0xf2, 0xe4, 0x86, 0x90, 0xaa, 0xbc, + 0xcf, 0xd9, 0xe3, 0xf5, 0x97, 0x81, 0xbb, 0xad, 0x7f, 0x69, + 0x53, 0x45, 0x27, 0x31, 0x0b, 0x1d, 0xb2, 0xa4, 0x9e, 0x88, + 0xea, 0xfc, 0xc6, 0xd0, 0x02, 0x14, 0x2e, 0x38, 0x5a, 0x4c, + 0x76, 0x60, 0x35, 0x23, 0x19, 0x0f, 0x6d, 0x7b, 0x41, 0x57, + 0x85, 0x93, 0xa9, 0xbf, 0xdd, 0xcb, 0xf1, 0xe7, 0x48, 0x5e, + 0x64, 0x72, 0x10, 0x06, 0x3c, 0x2a, 0xf8, 0xee, 0xd4, 0xc2, + 0xa0, 0xb6, 0x8c, 0x9a, 0x26, 0x30, 0x0a, 0x1c, 0x7e, 0x68, + 0x52, 0x44, 0x96, 0x80, 0xba, 0xac, 0xce, 0xd8, 0xe2, 0xf4, + 0x5b, 0x4d, 0x77, 0x61, 0x03, 0x15, 0x2f, 0x39, 0xeb, 0xfd, + 0xc7, 0xd1, 0xb3, 0xa5, 0x9f, 0x89, 0xdc, 0xca, 0xf0, 0xe6, + 0x84, 0x92, 0xa8, 0xbe, 0x6c, 0x7a, 0x40, 0x56, 0x34, 0x22, + 0x18, 0x0e, 0xa1, 0xb7, 0x8d, 0x9b, 0xf9, 0xef, 0xd5, 0xc3, + 0x11, 0x07, 0x3d, 0x2b, 0x49, 0x5f, 0x65, 0x73, 0x00, 0x17, + 0x2e, 0x39, 0x5c, 0x4b, 0x72, 0x65, 0xb8, 0xaf, 0x96, 0x81, + 0xe4, 0xf3, 0xca, 0xdd, 0x6d, 0x7a, 0x43, 0x54, 0x31, 0x26, + 0x1f, 0x08, 0xd5, 0xc2, 0xfb, 0xec, 0x89, 0x9e, 0xa7, 0xb0, + 0xda, 0xcd, 0xf4, 0xe3, 0x86, 0x91, 0xa8, 0xbf, 0x62, 0x75, + 0x4c, 0x5b, 0x3e, 0x29, 0x10, 0x07, 0xb7, 0xa0, 0x99, 0x8e, + 0xeb, 0xfc, 0xc5, 0xd2, 0x0f, 0x18, 0x21, 0x36, 0x53, 0x44, + 0x7d, 0x6a, 0xa9, 0xbe, 0x87, 0x90, 0xf5, 0xe2, 0xdb, 0xcc, + 0x11, 0x06, 0x3f, 0x28, 0x4d, 0x5a, 0x63, 0x74, 0xc4, 0xd3, + 0xea, 0xfd, 0x98, 0x8f, 0xb6, 0xa1, 0x7c, 0x6b, 0x52, 0x45, + 0x20, 0x37, 0x0e, 0x19, 0x73, 0x64, 0x5d, 0x4a, 0x2f, 0x38, + 0x01, 0x16, 0xcb, 0xdc, 0xe5, 0xf2, 0x97, 0x80, 0xb9, 0xae, + 0x1e, 0x09, 0x30, 0x27, 0x42, 0x55, 0x6c, 0x7b, 0xa6, 0xb1, + 0x88, 0x9f, 0xfa, 0xed, 0xd4, 0xc3, 0x4f, 0x58, 0x61, 0x76, + 0x13, 0x04, 0x3d, 0x2a, 0xf7, 0xe0, 0xd9, 0xce, 0xab, 0xbc, + 0x85, 0x92, 0x22, 0x35, 0x0c, 0x1b, 0x7e, 0x69, 0x50, 0x47, + 0x9a, 0x8d, 0xb4, 0xa3, 0xc6, 0xd1, 0xe8, 0xff, 0x95, 0x82, + 0xbb, 0xac, 0xc9, 0xde, 0xe7, 0xf0, 0x2d, 0x3a, 0x03, 0x14, + 0x71, 0x66, 0x5f, 0x48, 0xf8, 0xef, 0xd6, 0xc1, 0xa4, 0xb3, + 0x8a, 0x9d, 0x40, 0x57, 0x6e, 0x79, 0x1c, 0x0b, 0x32, 0x25, + 0xe6, 0xf1, 0xc8, 0xdf, 0xba, 0xad, 0x94, 0x83, 0x5e, 0x49, + 0x70, 0x67, 0x02, 0x15, 0x2c, 0x3b, 0x8b, 0x9c, 0xa5, 0xb2, + 0xd7, 0xc0, 0xf9, 0xee, 0x33, 0x24, 0x1d, 0x0a, 0x6f, 0x78, + 0x41, 0x56, 0x3c, 0x2b, 0x12, 0x05, 0x60, 0x77, 0x4e, 0x59, + 0x84, 0x93, 0xaa, 0xbd, 0xd8, 0xcf, 0xf6, 0xe1, 0x51, 0x46, + 0x7f, 0x68, 0x0d, 0x1a, 0x23, 0x34, 0xe9, 0xfe, 0xc7, 0xd0, + 0xb5, 0xa2, 0x9b, 0x8c, 0x00, 0x18, 0x30, 0x28, 0x60, 0x78, + 0x50, 0x48, 0xc0, 0xd8, 0xf0, 0xe8, 0xa0, 0xb8, 0x90, 0x88, + 0x9d, 0x85, 0xad, 0xb5, 0xfd, 0xe5, 0xcd, 0xd5, 0x5d, 0x45, + 0x6d, 0x75, 0x3d, 0x25, 0x0d, 0x15, 0x27, 0x3f, 0x17, 0x0f, + 0x47, 0x5f, 0x77, 0x6f, 0xe7, 0xff, 0xd7, 0xcf, 0x87, 0x9f, + 0xb7, 0xaf, 0xba, 0xa2, 0x8a, 0x92, 0xda, 0xc2, 0xea, 0xf2, + 0x7a, 0x62, 0x4a, 0x52, 0x1a, 0x02, 0x2a, 0x32, 0x4e, 0x56, + 0x7e, 0x66, 0x2e, 0x36, 0x1e, 0x06, 0x8e, 0x96, 0xbe, 0xa6, + 0xee, 0xf6, 0xde, 0xc6, 0xd3, 0xcb, 0xe3, 0xfb, 0xb3, 0xab, + 0x83, 0x9b, 0x13, 0x0b, 0x23, 0x3b, 0x73, 0x6b, 0x43, 0x5b, + 0x69, 0x71, 0x59, 0x41, 0x09, 0x11, 0x39, 0x21, 0xa9, 0xb1, + 0x99, 0x81, 0xc9, 0xd1, 0xf9, 0xe1, 0xf4, 0xec, 0xc4, 0xdc, + 0x94, 0x8c, 0xa4, 0xbc, 0x34, 0x2c, 0x04, 0x1c, 0x54, 0x4c, + 0x64, 0x7c, 0x9c, 0x84, 0xac, 0xb4, 0xfc, 0xe4, 0xcc, 0xd4, + 0x5c, 0x44, 0x6c, 0x74, 0x3c, 0x24, 0x0c, 0x14, 0x01, 0x19, + 0x31, 0x29, 0x61, 0x79, 0x51, 0x49, 0xc1, 0xd9, 0xf1, 0xe9, + 0xa1, 0xb9, 0x91, 0x89, 0xbb, 0xa3, 0x8b, 0x93, 0xdb, 0xc3, + 0xeb, 0xf3, 0x7b, 0x63, 0x4b, 0x53, 0x1b, 0x03, 0x2b, 0x33, + 0x26, 0x3e, 0x16, 0x0e, 0x46, 0x5e, 0x76, 0x6e, 0xe6, 0xfe, + 0xd6, 0xce, 0x86, 0x9e, 0xb6, 0xae, 0xd2, 0xca, 0xe2, 0xfa, + 0xb2, 0xaa, 0x82, 0x9a, 0x12, 0x0a, 0x22, 0x3a, 0x72, 0x6a, + 0x42, 0x5a, 0x4f, 0x57, 0x7f, 0x67, 0x2f, 0x37, 0x1f, 0x07, + 0x8f, 0x97, 0xbf, 0xa7, 0xef, 0xf7, 0xdf, 0xc7, 0xf5, 0xed, + 0xc5, 0xdd, 0x95, 0x8d, 0xa5, 0xbd, 0x35, 0x2d, 0x05, 0x1d, + 0x55, 0x4d, 0x65, 0x7d, 0x68, 0x70, 0x58, 0x40, 0x08, 0x10, + 0x38, 0x20, 0xa8, 0xb0, 0x98, 0x80, 0xc8, 0xd0, 0xf8, 0xe0, + 0x00, 0x19, 0x32, 0x2b, 0x64, 0x7d, 0x56, 0x4f, 0xc8, 0xd1, + 0xfa, 0xe3, 0xac, 0xb5, 0x9e, 0x87, 0x8d, 0x94, 0xbf, 0xa6, + 0xe9, 0xf0, 0xdb, 0xc2, 0x45, 0x5c, 0x77, 0x6e, 0x21, 0x38, + 0x13, 0x0a, 0x07, 0x1e, 0x35, 0x2c, 0x63, 0x7a, 0x51, 0x48, + 0xcf, 0xd6, 0xfd, 0xe4, 0xab, 0xb2, 0x99, 0x80, 0x8a, 0x93, + 0xb8, 0xa1, 0xee, 0xf7, 0xdc, 0xc5, 0x42, 0x5b, 0x70, 0x69, + 0x26, 0x3f, 0x14, 0x0d, 0x0e, 0x17, 0x3c, 0x25, 0x6a, 0x73, + 0x58, 0x41, 0xc6, 0xdf, 0xf4, 0xed, 0xa2, 0xbb, 0x90, 0x89, + 0x83, 0x9a, 0xb1, 0xa8, 0xe7, 0xfe, 0xd5, 0xcc, 0x4b, 0x52, + 0x79, 0x60, 0x2f, 0x36, 0x1d, 0x04, 0x09, 0x10, 0x3b, 0x22, + 0x6d, 0x74, 0x5f, 0x46, 0xc1, 0xd8, 0xf3, 0xea, 0xa5, 0xbc, + 0x97, 0x8e, 0x84, 0x9d, 0xb6, 0xaf, 0xe0, 0xf9, 0xd2, 0xcb, + 0x4c, 0x55, 0x7e, 0x67, 0x28, 0x31, 0x1a, 0x03, 0x1c, 0x05, + 0x2e, 0x37, 0x78, 0x61, 0x4a, 0x53, 0xd4, 0xcd, 0xe6, 0xff, + 0xb0, 0xa9, 0x82, 0x9b, 0x91, 0x88, 0xa3, 0xba, 0xf5, 0xec, + 0xc7, 0xde, 0x59, 0x40, 0x6b, 0x72, 0x3d, 0x24, 0x0f, 0x16, + 0x1b, 0x02, 0x29, 0x30, 0x7f, 0x66, 0x4d, 0x54, 0xd3, 0xca, + 0xe1, 0xf8, 0xb7, 0xae, 0x85, 0x9c, 0x96, 0x8f, 0xa4, 0xbd, + 0xf2, 0xeb, 0xc0, 0xd9, 0x5e, 0x47, 0x6c, 0x75, 0x3a, 0x23, + 0x08, 0x11, 0x12, 0x0b, 0x20, 0x39, 0x76, 0x6f, 0x44, 0x5d, + 0xda, 0xc3, 0xe8, 0xf1, 0xbe, 0xa7, 0x8c, 0x95, 0x9f, 0x86, + 0xad, 0xb4, 0xfb, 0xe2, 0xc9, 0xd0, 0x57, 0x4e, 0x65, 0x7c, + 0x33, 0x2a, 0x01, 0x18, 0x15, 0x0c, 0x27, 0x3e, 0x71, 0x68, + 0x43, 0x5a, 0xdd, 0xc4, 0xef, 0xf6, 0xb9, 0xa0, 0x8b, 0x92, + 0x98, 0x81, 0xaa, 0xb3, 0xfc, 0xe5, 0xce, 0xd7, 0x50, 0x49, + 0x62, 0x7b, 0x34, 0x2d, 0x06, 0x1f, 0x00, 0x1a, 0x34, 0x2e, + 0x68, 0x72, 0x5c, 0x46, 0xd0, 0xca, 0xe4, 0xfe, 0xb8, 0xa2, + 0x8c, 0x96, 0xbd, 0xa7, 0x89, 0x93, 0xd5, 0xcf, 0xe1, 0xfb, + 0x6d, 0x77, 0x59, 0x43, 0x05, 0x1f, 0x31, 0x2b, 0x67, 0x7d, + 0x53, 0x49, 0x0f, 0x15, 0x3b, 0x21, 0xb7, 0xad, 0x83, 0x99, + 0xdf, 0xc5, 0xeb, 0xf1, 0xda, 0xc0, 0xee, 0xf4, 0xb2, 0xa8, + 0x86, 0x9c, 0x0a, 0x10, 0x3e, 0x24, 0x62, 0x78, 0x56, 0x4c, + 0xce, 0xd4, 0xfa, 0xe0, 0xa6, 0xbc, 0x92, 0x88, 0x1e, 0x04, + 0x2a, 0x30, 0x76, 0x6c, 0x42, 0x58, 0x73, 0x69, 0x47, 0x5d, + 0x1b, 0x01, 0x2f, 0x35, 0xa3, 0xb9, 0x97, 0x8d, 0xcb, 0xd1, + 0xff, 0xe5, 0xa9, 0xb3, 0x9d, 0x87, 0xc1, 0xdb, 0xf5, 0xef, + 0x79, 0x63, 0x4d, 0x57, 0x11, 0x0b, 0x25, 0x3f, 0x14, 0x0e, + 0x20, 0x3a, 0x7c, 0x66, 0x48, 0x52, 0xc4, 0xde, 0xf0, 0xea, + 0xac, 0xb6, 0x98, 0x82, 0x81, 0x9b, 0xb5, 0xaf, 0xe9, 0xf3, + 0xdd, 0xc7, 0x51, 0x4b, 0x65, 0x7f, 0x39, 0x23, 0x0d, 0x17, + 0x3c, 0x26, 0x08, 0x12, 0x54, 0x4e, 0x60, 0x7a, 0xec, 0xf6, + 0xd8, 0xc2, 0x84, 0x9e, 0xb0, 0xaa, 0xe6, 0xfc, 0xd2, 0xc8, + 0x8e, 0x94, 0xba, 0xa0, 0x36, 0x2c, 0x02, 0x18, 0x5e, 0x44, + 0x6a, 0x70, 0x5b, 0x41, 0x6f, 0x75, 0x33, 0x29, 0x07, 0x1d, + 0x8b, 0x91, 0xbf, 0xa5, 0xe3, 0xf9, 0xd7, 0xcd, 0x4f, 0x55, + 0x7b, 0x61, 0x27, 0x3d, 0x13, 0x09, 0x9f, 0x85, 0xab, 0xb1, + 0xf7, 0xed, 0xc3, 0xd9, 0xf2, 0xe8, 0xc6, 0xdc, 0x9a, 0x80, + 0xae, 0xb4, 0x22, 0x38, 0x16, 0x0c, 0x4a, 0x50, 0x7e, 0x64, + 0x28, 0x32, 0x1c, 0x06, 0x40, 0x5a, 0x74, 0x6e, 0xf8, 0xe2, + 0xcc, 0xd6, 0x90, 0x8a, 0xa4, 0xbe, 0x95, 0x8f, 0xa1, 0xbb, + 0xfd, 0xe7, 0xc9, 0xd3, 0x45, 0x5f, 0x71, 0x6b, 0x2d, 0x37, + 0x19, 0x03, 0x00, 0x1b, 0x36, 0x2d, 0x6c, 0x77, 0x5a, 0x41, + 0xd8, 0xc3, 0xee, 0xf5, 0xb4, 0xaf, 0x82, 0x99, 0xad, 0xb6, + 0x9b, 0x80, 0xc1, 0xda, 0xf7, 0xec, 0x75, 0x6e, 0x43, 0x58, + 0x19, 0x02, 0x2f, 0x34, 0x47, 0x5c, 0x71, 0x6a, 0x2b, 0x30, + 0x1d, 0x06, 0x9f, 0x84, 0xa9, 0xb2, 0xf3, 0xe8, 0xc5, 0xde, + 0xea, 0xf1, 0xdc, 0xc7, 0x86, 0x9d, 0xb0, 0xab, 0x32, 0x29, + 0x04, 0x1f, 0x5e, 0x45, 0x68, 0x73, 0x8e, 0x95, 0xb8, 0xa3, + 0xe2, 0xf9, 0xd4, 0xcf, 0x56, 0x4d, 0x60, 0x7b, 0x3a, 0x21, + 0x0c, 0x17, 0x23, 0x38, 0x15, 0x0e, 0x4f, 0x54, 0x79, 0x62, + 0xfb, 0xe0, 0xcd, 0xd6, 0x97, 0x8c, 0xa1, 0xba, 0xc9, 0xd2, + 0xff, 0xe4, 0xa5, 0xbe, 0x93, 0x88, 0x11, 0x0a, 0x27, 0x3c, + 0x7d, 0x66, 0x4b, 0x50, 0x64, 0x7f, 0x52, 0x49, 0x08, 0x13, + 0x3e, 0x25, 0xbc, 0xa7, 0x8a, 0x91, 0xd0, 0xcb, 0xe6, 0xfd, + 0x01, 0x1a, 0x37, 0x2c, 0x6d, 0x76, 0x5b, 0x40, 0xd9, 0xc2, + 0xef, 0xf4, 0xb5, 0xae, 0x83, 0x98, 0xac, 0xb7, 0x9a, 0x81, + 0xc0, 0xdb, 0xf6, 0xed, 0x74, 0x6f, 0x42, 0x59, 0x18, 0x03, + 0x2e, 0x35, 0x46, 0x5d, 0x70, 0x6b, 0x2a, 0x31, 0x1c, 0x07, + 0x9e, 0x85, 0xa8, 0xb3, 0xf2, 0xe9, 0xc4, 0xdf, 0xeb, 0xf0, + 0xdd, 0xc6, 0x87, 0x9c, 0xb1, 0xaa, 0x33, 0x28, 0x05, 0x1e, + 0x5f, 0x44, 0x69, 0x72, 0x8f, 0x94, 0xb9, 0xa2, 0xe3, 0xf8, + 0xd5, 0xce, 0x57, 0x4c, 0x61, 0x7a, 0x3b, 0x20, 0x0d, 0x16, + 0x22, 0x39, 0x14, 0x0f, 0x4e, 0x55, 0x78, 0x63, 0xfa, 0xe1, + 0xcc, 0xd7, 0x96, 0x8d, 0xa0, 0xbb, 0xc8, 0xd3, 0xfe, 0xe5, + 0xa4, 0xbf, 0x92, 0x89, 0x10, 0x0b, 0x26, 0x3d, 0x7c, 0x67, + 0x4a, 0x51, 0x65, 0x7e, 0x53, 0x48, 0x09, 0x12, 0x3f, 0x24, + 0xbd, 0xa6, 0x8b, 0x90, 0xd1, 0xca, 0xe7, 0xfc, 0x00, 0x1c, + 0x38, 0x24, 0x70, 0x6c, 0x48, 0x54, 0xe0, 0xfc, 0xd8, 0xc4, + 0x90, 0x8c, 0xa8, 0xb4, 0xdd, 0xc1, 0xe5, 0xf9, 0xad, 0xb1, + 0x95, 0x89, 0x3d, 0x21, 0x05, 0x19, 0x4d, 0x51, 0x75, 0x69, + 0xa7, 0xbb, 0x9f, 0x83, 0xd7, 0xcb, 0xef, 0xf3, 0x47, 0x5b, + 0x7f, 0x63, 0x37, 0x2b, 0x0f, 0x13, 0x7a, 0x66, 0x42, 0x5e, + 0x0a, 0x16, 0x32, 0x2e, 0x9a, 0x86, 0xa2, 0xbe, 0xea, 0xf6, + 0xd2, 0xce, 0x53, 0x4f, 0x6b, 0x77, 0x23, 0x3f, 0x1b, 0x07, + 0xb3, 0xaf, 0x8b, 0x97, 0xc3, 0xdf, 0xfb, 0xe7, 0x8e, 0x92, + 0xb6, 0xaa, 0xfe, 0xe2, 0xc6, 0xda, 0x6e, 0x72, 0x56, 0x4a, + 0x1e, 0x02, 0x26, 0x3a, 0xf4, 0xe8, 0xcc, 0xd0, 0x84, 0x98, + 0xbc, 0xa0, 0x14, 0x08, 0x2c, 0x30, 0x64, 0x78, 0x5c, 0x40, + 0x29, 0x35, 0x11, 0x0d, 0x59, 0x45, 0x61, 0x7d, 0xc9, 0xd5, + 0xf1, 0xed, 0xb9, 0xa5, 0x81, 0x9d, 0xa6, 0xba, 0x9e, 0x82, + 0xd6, 0xca, 0xee, 0xf2, 0x46, 0x5a, 0x7e, 0x62, 0x36, 0x2a, + 0x0e, 0x12, 0x7b, 0x67, 0x43, 0x5f, 0x0b, 0x17, 0x33, 0x2f, + 0x9b, 0x87, 0xa3, 0xbf, 0xeb, 0xf7, 0xd3, 0xcf, 0x01, 0x1d, + 0x39, 0x25, 0x71, 0x6d, 0x49, 0x55, 0xe1, 0xfd, 0xd9, 0xc5, + 0x91, 0x8d, 0xa9, 0xb5, 0xdc, 0xc0, 0xe4, 0xf8, 0xac, 0xb0, + 0x94, 0x88, 0x3c, 0x20, 0x04, 0x18, 0x4c, 0x50, 0x74, 0x68, + 0xf5, 0xe9, 0xcd, 0xd1, 0x85, 0x99, 0xbd, 0xa1, 0x15, 0x09, + 0x2d, 0x31, 0x65, 0x79, 0x5d, 0x41, 0x28, 0x34, 0x10, 0x0c, + 0x58, 0x44, 0x60, 0x7c, 0xc8, 0xd4, 0xf0, 0xec, 0xb8, 0xa4, + 0x80, 0x9c, 0x52, 0x4e, 0x6a, 0x76, 0x22, 0x3e, 0x1a, 0x06, + 0xb2, 0xae, 0x8a, 0x96, 0xc2, 0xde, 0xfa, 0xe6, 0x8f, 0x93, + 0xb7, 0xab, 0xff, 0xe3, 0xc7, 0xdb, 0x6f, 0x73, 0x57, 0x4b, + 0x1f, 0x03, 0x27, 0x3b, 0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, + 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb, + 0xcd, 0xd0, 0xf7, 0xea, 0xb9, 0xa4, 0x83, 0x9e, 0x25, 0x38, + 0x1f, 0x02, 0x51, 0x4c, 0x6b, 0x76, 0x87, 0x9a, 0xbd, 0xa0, + 0xf3, 0xee, 0xc9, 0xd4, 0x6f, 0x72, 0x55, 0x48, 0x1b, 0x06, + 0x21, 0x3c, 0x4a, 0x57, 0x70, 0x6d, 0x3e, 0x23, 0x04, 0x19, + 0xa2, 0xbf, 0x98, 0x85, 0xd6, 0xcb, 0xec, 0xf1, 0x13, 0x0e, + 0x29, 0x34, 0x67, 0x7a, 0x5d, 0x40, 0xfb, 0xe6, 0xc1, 0xdc, + 0x8f, 0x92, 0xb5, 0xa8, 0xde, 0xc3, 0xe4, 0xf9, 0xaa, 0xb7, + 0x90, 0x8d, 0x36, 0x2b, 0x0c, 0x11, 0x42, 0x5f, 0x78, 0x65, + 0x94, 0x89, 0xae, 0xb3, 0xe0, 0xfd, 0xda, 0xc7, 0x7c, 0x61, + 0x46, 0x5b, 0x08, 0x15, 0x32, 0x2f, 0x59, 0x44, 0x63, 0x7e, + 0x2d, 0x30, 0x17, 0x0a, 0xb1, 0xac, 0x8b, 0x96, 0xc5, 0xd8, + 0xff, 0xe2, 0x26, 0x3b, 0x1c, 0x01, 0x52, 0x4f, 0x68, 0x75, + 0xce, 0xd3, 0xf4, 0xe9, 0xba, 0xa7, 0x80, 0x9d, 0xeb, 0xf6, + 0xd1, 0xcc, 0x9f, 0x82, 0xa5, 0xb8, 0x03, 0x1e, 0x39, 0x24, + 0x77, 0x6a, 0x4d, 0x50, 0xa1, 0xbc, 0x9b, 0x86, 0xd5, 0xc8, + 0xef, 0xf2, 0x49, 0x54, 0x73, 0x6e, 0x3d, 0x20, 0x07, 0x1a, + 0x6c, 0x71, 0x56, 0x4b, 0x18, 0x05, 0x22, 0x3f, 0x84, 0x99, + 0xbe, 0xa3, 0xf0, 0xed, 0xca, 0xd7, 0x35, 0x28, 0x0f, 0x12, + 0x41, 0x5c, 0x7b, 0x66, 0xdd, 0xc0, 0xe7, 0xfa, 0xa9, 0xb4, + 0x93, 0x8e, 0xf8, 0xe5, 0xc2, 0xdf, 0x8c, 0x91, 0xb6, 0xab, + 0x10, 0x0d, 0x2a, 0x37, 0x64, 0x79, 0x5e, 0x43, 0xb2, 0xaf, + 0x88, 0x95, 0xc6, 0xdb, 0xfc, 0xe1, 0x5a, 0x47, 0x60, 0x7d, + 0x2e, 0x33, 0x14, 0x09, 0x7f, 0x62, 0x45, 0x58, 0x0b, 0x16, + 0x31, 0x2c, 0x97, 0x8a, 0xad, 0xb0, 0xe3, 0xfe, 0xd9, 0xc4, + 0x00, 0x1e, 0x3c, 0x22, 0x78, 0x66, 0x44, 0x5a, 0xf0, 0xee, + 0xcc, 0xd2, 0x88, 0x96, 0xb4, 0xaa, 0xfd, 0xe3, 0xc1, 0xdf, + 0x85, 0x9b, 0xb9, 0xa7, 0x0d, 0x13, 0x31, 0x2f, 0x75, 0x6b, + 0x49, 0x57, 0xe7, 0xf9, 0xdb, 0xc5, 0x9f, 0x81, 0xa3, 0xbd, + 0x17, 0x09, 0x2b, 0x35, 0x6f, 0x71, 0x53, 0x4d, 0x1a, 0x04, + 0x26, 0x38, 0x62, 0x7c, 0x5e, 0x40, 0xea, 0xf4, 0xd6, 0xc8, + 0x92, 0x8c, 0xae, 0xb0, 0xd3, 0xcd, 0xef, 0xf1, 0xab, 0xb5, + 0x97, 0x89, 0x23, 0x3d, 0x1f, 0x01, 0x5b, 0x45, 0x67, 0x79, + 0x2e, 0x30, 0x12, 0x0c, 0x56, 0x48, 0x6a, 0x74, 0xde, 0xc0, + 0xe2, 0xfc, 0xa6, 0xb8, 0x9a, 0x84, 0x34, 0x2a, 0x08, 0x16, + 0x4c, 0x52, 0x70, 0x6e, 0xc4, 0xda, 0xf8, 0xe6, 0xbc, 0xa2, + 0x80, 0x9e, 0xc9, 0xd7, 0xf5, 0xeb, 0xb1, 0xaf, 0x8d, 0x93, + 0x39, 0x27, 0x05, 0x1b, 0x41, 0x5f, 0x7d, 0x63, 0xbb, 0xa5, + 0x87, 0x99, 0xc3, 0xdd, 0xff, 0xe1, 0x4b, 0x55, 0x77, 0x69, + 0x33, 0x2d, 0x0f, 0x11, 0x46, 0x58, 0x7a, 0x64, 0x3e, 0x20, + 0x02, 0x1c, 0xb6, 0xa8, 0x8a, 0x94, 0xce, 0xd0, 0xf2, 0xec, + 0x5c, 0x42, 0x60, 0x7e, 0x24, 0x3a, 0x18, 0x06, 0xac, 0xb2, + 0x90, 0x8e, 0xd4, 0xca, 0xe8, 0xf6, 0xa1, 0xbf, 0x9d, 0x83, + 0xd9, 0xc7, 0xe5, 0xfb, 0x51, 0x4f, 0x6d, 0x73, 0x29, 0x37, + 0x15, 0x0b, 0x68, 0x76, 0x54, 0x4a, 0x10, 0x0e, 0x2c, 0x32, + 0x98, 0x86, 0xa4, 0xba, 0xe0, 0xfe, 0xdc, 0xc2, 0x95, 0x8b, + 0xa9, 0xb7, 0xed, 0xf3, 0xd1, 0xcf, 0x65, 0x7b, 0x59, 0x47, + 0x1d, 0x03, 0x21, 0x3f, 0x8f, 0x91, 0xb3, 0xad, 0xf7, 0xe9, + 0xcb, 0xd5, 0x7f, 0x61, 0x43, 0x5d, 0x07, 0x19, 0x3b, 0x25, + 0x72, 0x6c, 0x4e, 0x50, 0x0a, 0x14, 0x36, 0x28, 0x82, 0x9c, + 0xbe, 0xa0, 0xfa, 0xe4, 0xc6, 0xd8, 0x00, 0x1f, 0x3e, 0x21, + 0x7c, 0x63, 0x42, 0x5d, 0xf8, 0xe7, 0xc6, 0xd9, 0x84, 0x9b, + 0xba, 0xa5, 0xed, 0xf2, 0xd3, 0xcc, 0x91, 0x8e, 0xaf, 0xb0, + 0x15, 0x0a, 0x2b, 0x34, 0x69, 0x76, 0x57, 0x48, 0xc7, 0xd8, + 0xf9, 0xe6, 0xbb, 0xa4, 0x85, 0x9a, 0x3f, 0x20, 0x01, 0x1e, + 0x43, 0x5c, 0x7d, 0x62, 0x2a, 0x35, 0x14, 0x0b, 0x56, 0x49, + 0x68, 0x77, 0xd2, 0xcd, 0xec, 0xf3, 0xae, 0xb1, 0x90, 0x8f, + 0x93, 0x8c, 0xad, 0xb2, 0xef, 0xf0, 0xd1, 0xce, 0x6b, 0x74, + 0x55, 0x4a, 0x17, 0x08, 0x29, 0x36, 0x7e, 0x61, 0x40, 0x5f, + 0x02, 0x1d, 0x3c, 0x23, 0x86, 0x99, 0xb8, 0xa7, 0xfa, 0xe5, + 0xc4, 0xdb, 0x54, 0x4b, 0x6a, 0x75, 0x28, 0x37, 0x16, 0x09, + 0xac, 0xb3, 0x92, 0x8d, 0xd0, 0xcf, 0xee, 0xf1, 0xb9, 0xa6, + 0x87, 0x98, 0xc5, 0xda, 0xfb, 0xe4, 0x41, 0x5e, 0x7f, 0x60, + 0x3d, 0x22, 0x03, 0x1c, 0x3b, 0x24, 0x05, 0x1a, 0x47, 0x58, + 0x79, 0x66, 0xc3, 0xdc, 0xfd, 0xe2, 0xbf, 0xa0, 0x81, 0x9e, + 0xd6, 0xc9, 0xe8, 0xf7, 0xaa, 0xb5, 0x94, 0x8b, 0x2e, 0x31, + 0x10, 0x0f, 0x52, 0x4d, 0x6c, 0x73, 0xfc, 0xe3, 0xc2, 0xdd, + 0x80, 0x9f, 0xbe, 0xa1, 0x04, 0x1b, 0x3a, 0x25, 0x78, 0x67, + 0x46, 0x59, 0x11, 0x0e, 0x2f, 0x30, 0x6d, 0x72, 0x53, 0x4c, + 0xe9, 0xf6, 0xd7, 0xc8, 0x95, 0x8a, 0xab, 0xb4, 0xa8, 0xb7, + 0x96, 0x89, 0xd4, 0xcb, 0xea, 0xf5, 0x50, 0x4f, 0x6e, 0x71, + 0x2c, 0x33, 0x12, 0x0d, 0x45, 0x5a, 0x7b, 0x64, 0x39, 0x26, + 0x07, 0x18, 0xbd, 0xa2, 0x83, 0x9c, 0xc1, 0xde, 0xff, 0xe0, + 0x6f, 0x70, 0x51, 0x4e, 0x13, 0x0c, 0x2d, 0x32, 0x97, 0x88, + 0xa9, 0xb6, 0xeb, 0xf4, 0xd5, 0xca, 0x82, 0x9d, 0xbc, 0xa3, + 0xfe, 0xe1, 0xc0, 0xdf, 0x7a, 0x65, 0x44, 0x5b, 0x06, 0x19, + 0x38, 0x27, 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, + 0x1d, 0x3d, 0x5d, 0x7d, 0x9d, 0xbd, 0xdd, 0xfd, 0x3a, 0x1a, + 0x7a, 0x5a, 0xba, 0x9a, 0xfa, 0xda, 0x27, 0x07, 0x67, 0x47, + 0xa7, 0x87, 0xe7, 0xc7, 0x74, 0x54, 0x34, 0x14, 0xf4, 0xd4, + 0xb4, 0x94, 0x69, 0x49, 0x29, 0x09, 0xe9, 0xc9, 0xa9, 0x89, + 0x4e, 0x6e, 0x0e, 0x2e, 0xce, 0xee, 0x8e, 0xae, 0x53, 0x73, + 0x13, 0x33, 0xd3, 0xf3, 0x93, 0xb3, 0xe8, 0xc8, 0xa8, 0x88, + 0x68, 0x48, 0x28, 0x08, 0xf5, 0xd5, 0xb5, 0x95, 0x75, 0x55, + 0x35, 0x15, 0xd2, 0xf2, 0x92, 0xb2, 0x52, 0x72, 0x12, 0x32, + 0xcf, 0xef, 0x8f, 0xaf, 0x4f, 0x6f, 0x0f, 0x2f, 0x9c, 0xbc, + 0xdc, 0xfc, 0x1c, 0x3c, 0x5c, 0x7c, 0x81, 0xa1, 0xc1, 0xe1, + 0x01, 0x21, 0x41, 0x61, 0xa6, 0x86, 0xe6, 0xc6, 0x26, 0x06, + 0x66, 0x46, 0xbb, 0x9b, 0xfb, 0xdb, 0x3b, 0x1b, 0x7b, 0x5b, + 0xcd, 0xed, 0x8d, 0xad, 0x4d, 0x6d, 0x0d, 0x2d, 0xd0, 0xf0, + 0x90, 0xb0, 0x50, 0x70, 0x10, 0x30, 0xf7, 0xd7, 0xb7, 0x97, + 0x77, 0x57, 0x37, 0x17, 0xea, 0xca, 0xaa, 0x8a, 0x6a, 0x4a, + 0x2a, 0x0a, 0xb9, 0x99, 0xf9, 0xd9, 0x39, 0x19, 0x79, 0x59, + 0xa4, 0x84, 0xe4, 0xc4, 0x24, 0x04, 0x64, 0x44, 0x83, 0xa3, + 0xc3, 0xe3, 0x03, 0x23, 0x43, 0x63, 0x9e, 0xbe, 0xde, 0xfe, + 0x1e, 0x3e, 0x5e, 0x7e, 0x25, 0x05, 0x65, 0x45, 0xa5, 0x85, + 0xe5, 0xc5, 0x38, 0x18, 0x78, 0x58, 0xb8, 0x98, 0xf8, 0xd8, + 0x1f, 0x3f, 0x5f, 0x7f, 0x9f, 0xbf, 0xdf, 0xff, 0x02, 0x22, + 0x42, 0x62, 0x82, 0xa2, 0xc2, 0xe2, 0x51, 0x71, 0x11, 0x31, + 0xd1, 0xf1, 0x91, 0xb1, 0x4c, 0x6c, 0x0c, 0x2c, 0xcc, 0xec, + 0x8c, 0xac, 0x6b, 0x4b, 0x2b, 0x0b, 0xeb, 0xcb, 0xab, 0x8b, + 0x76, 0x56, 0x36, 0x16, 0xf6, 0xd6, 0xb6, 0x96, 0x00, 0x21, + 0x42, 0x63, 0x84, 0xa5, 0xc6, 0xe7, 0x15, 0x34, 0x57, 0x76, + 0x91, 0xb0, 0xd3, 0xf2, 0x2a, 0x0b, 0x68, 0x49, 0xae, 0x8f, + 0xec, 0xcd, 0x3f, 0x1e, 0x7d, 0x5c, 0xbb, 0x9a, 0xf9, 0xd8, + 0x54, 0x75, 0x16, 0x37, 0xd0, 0xf1, 0x92, 0xb3, 0x41, 0x60, + 0x03, 0x22, 0xc5, 0xe4, 0x87, 0xa6, 0x7e, 0x5f, 0x3c, 0x1d, + 0xfa, 0xdb, 0xb8, 0x99, 0x6b, 0x4a, 0x29, 0x08, 0xef, 0xce, + 0xad, 0x8c, 0xa8, 0x89, 0xea, 0xcb, 0x2c, 0x0d, 0x6e, 0x4f, + 0xbd, 0x9c, 0xff, 0xde, 0x39, 0x18, 0x7b, 0x5a, 0x82, 0xa3, + 0xc0, 0xe1, 0x06, 0x27, 0x44, 0x65, 0x97, 0xb6, 0xd5, 0xf4, + 0x13, 0x32, 0x51, 0x70, 0xfc, 0xdd, 0xbe, 0x9f, 0x78, 0x59, + 0x3a, 0x1b, 0xe9, 0xc8, 0xab, 0x8a, 0x6d, 0x4c, 0x2f, 0x0e, + 0xd6, 0xf7, 0x94, 0xb5, 0x52, 0x73, 0x10, 0x31, 0xc3, 0xe2, + 0x81, 0xa0, 0x47, 0x66, 0x05, 0x24, 0x4d, 0x6c, 0x0f, 0x2e, + 0xc9, 0xe8, 0x8b, 0xaa, 0x58, 0x79, 0x1a, 0x3b, 0xdc, 0xfd, + 0x9e, 0xbf, 0x67, 0x46, 0x25, 0x04, 0xe3, 0xc2, 0xa1, 0x80, + 0x72, 0x53, 0x30, 0x11, 0xf6, 0xd7, 0xb4, 0x95, 0x19, 0x38, + 0x5b, 0x7a, 0x9d, 0xbc, 0xdf, 0xfe, 0x0c, 0x2d, 0x4e, 0x6f, + 0x88, 0xa9, 0xca, 0xeb, 0x33, 0x12, 0x71, 0x50, 0xb7, 0x96, + 0xf5, 0xd4, 0x26, 0x07, 0x64, 0x45, 0xa2, 0x83, 0xe0, 0xc1, + 0xe5, 0xc4, 0xa7, 0x86, 0x61, 0x40, 0x23, 0x02, 0xf0, 0xd1, + 0xb2, 0x93, 0x74, 0x55, 0x36, 0x17, 0xcf, 0xee, 0x8d, 0xac, + 0x4b, 0x6a, 0x09, 0x28, 0xda, 0xfb, 0x98, 0xb9, 0x5e, 0x7f, + 0x1c, 0x3d, 0xb1, 0x90, 0xf3, 0xd2, 0x35, 0x14, 0x77, 0x56, + 0xa4, 0x85, 0xe6, 0xc7, 0x20, 0x01, 0x62, 0x43, 0x9b, 0xba, + 0xd9, 0xf8, 0x1f, 0x3e, 0x5d, 0x7c, 0x8e, 0xaf, 0xcc, 0xed, + 0x0a, 0x2b, 0x48, 0x69, 0x00, 0x22, 0x44, 0x66, 0x88, 0xaa, + 0xcc, 0xee, 0x0d, 0x2f, 0x49, 0x6b, 0x85, 0xa7, 0xc1, 0xe3, + 0x1a, 0x38, 0x5e, 0x7c, 0x92, 0xb0, 0xd6, 0xf4, 0x17, 0x35, + 0x53, 0x71, 0x9f, 0xbd, 0xdb, 0xf9, 0x34, 0x16, 0x70, 0x52, + 0xbc, 0x9e, 0xf8, 0xda, 0x39, 0x1b, 0x7d, 0x5f, 0xb1, 0x93, + 0xf5, 0xd7, 0x2e, 0x0c, 0x6a, 0x48, 0xa6, 0x84, 0xe2, 0xc0, + 0x23, 0x01, 0x67, 0x45, 0xab, 0x89, 0xef, 0xcd, 0x68, 0x4a, + 0x2c, 0x0e, 0xe0, 0xc2, 0xa4, 0x86, 0x65, 0x47, 0x21, 0x03, + 0xed, 0xcf, 0xa9, 0x8b, 0x72, 0x50, 0x36, 0x14, 0xfa, 0xd8, + 0xbe, 0x9c, 0x7f, 0x5d, 0x3b, 0x19, 0xf7, 0xd5, 0xb3, 0x91, + 0x5c, 0x7e, 0x18, 0x3a, 0xd4, 0xf6, 0x90, 0xb2, 0x51, 0x73, + 0x15, 0x37, 0xd9, 0xfb, 0x9d, 0xbf, 0x46, 0x64, 0x02, 0x20, + 0xce, 0xec, 0x8a, 0xa8, 0x4b, 0x69, 0x0f, 0x2d, 0xc3, 0xe1, + 0x87, 0xa5, 0xd0, 0xf2, 0x94, 0xb6, 0x58, 0x7a, 0x1c, 0x3e, + 0xdd, 0xff, 0x99, 0xbb, 0x55, 0x77, 0x11, 0x33, 0xca, 0xe8, + 0x8e, 0xac, 0x42, 0x60, 0x06, 0x24, 0xc7, 0xe5, 0x83, 0xa1, + 0x4f, 0x6d, 0x0b, 0x29, 0xe4, 0xc6, 0xa0, 0x82, 0x6c, 0x4e, + 0x28, 0x0a, 0xe9, 0xcb, 0xad, 0x8f, 0x61, 0x43, 0x25, 0x07, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xf3, 0xd1, + 0xb7, 0x95, 0x7b, 0x59, 0x3f, 0x1d, 0xb8, 0x9a, 0xfc, 0xde, + 0x30, 0x12, 0x74, 0x56, 0xb5, 0x97, 0xf1, 0xd3, 0x3d, 0x1f, + 0x79, 0x5b, 0xa2, 0x80, 0xe6, 0xc4, 0x2a, 0x08, 0x6e, 0x4c, + 0xaf, 0x8d, 0xeb, 0xc9, 0x27, 0x05, 0x63, 0x41, 0x8c, 0xae, + 0xc8, 0xea, 0x04, 0x26, 0x40, 0x62, 0x81, 0xa3, 0xc5, 0xe7, + 0x09, 0x2b, 0x4d, 0x6f, 0x96, 0xb4, 0xd2, 0xf0, 0x1e, 0x3c, + 0x5a, 0x78, 0x9b, 0xb9, 0xdf, 0xfd, 0x13, 0x31, 0x57, 0x75, + 0x00, 0x23, 0x46, 0x65, 0x8c, 0xaf, 0xca, 0xe9, 0x05, 0x26, + 0x43, 0x60, 0x89, 0xaa, 0xcf, 0xec, 0x0a, 0x29, 0x4c, 0x6f, + 0x86, 0xa5, 0xc0, 0xe3, 0x0f, 0x2c, 0x49, 0x6a, 0x83, 0xa0, + 0xc5, 0xe6, 0x14, 0x37, 0x52, 0x71, 0x98, 0xbb, 0xde, 0xfd, + 0x11, 0x32, 0x57, 0x74, 0x9d, 0xbe, 0xdb, 0xf8, 0x1e, 0x3d, + 0x58, 0x7b, 0x92, 0xb1, 0xd4, 0xf7, 0x1b, 0x38, 0x5d, 0x7e, + 0x97, 0xb4, 0xd1, 0xf2, 0x28, 0x0b, 0x6e, 0x4d, 0xa4, 0x87, + 0xe2, 0xc1, 0x2d, 0x0e, 0x6b, 0x48, 0xa1, 0x82, 0xe7, 0xc4, + 0x22, 0x01, 0x64, 0x47, 0xae, 0x8d, 0xe8, 0xcb, 0x27, 0x04, + 0x61, 0x42, 0xab, 0x88, 0xed, 0xce, 0x3c, 0x1f, 0x7a, 0x59, + 0xb0, 0x93, 0xf6, 0xd5, 0x39, 0x1a, 0x7f, 0x5c, 0xb5, 0x96, + 0xf3, 0xd0, 0x36, 0x15, 0x70, 0x53, 0xba, 0x99, 0xfc, 0xdf, + 0x33, 0x10, 0x75, 0x56, 0xbf, 0x9c, 0xf9, 0xda, 0x50, 0x73, + 0x16, 0x35, 0xdc, 0xff, 0x9a, 0xb9, 0x55, 0x76, 0x13, 0x30, + 0xd9, 0xfa, 0x9f, 0xbc, 0x5a, 0x79, 0x1c, 0x3f, 0xd6, 0xf5, + 0x90, 0xb3, 0x5f, 0x7c, 0x19, 0x3a, 0xd3, 0xf0, 0x95, 0xb6, + 0x44, 0x67, 0x02, 0x21, 0xc8, 0xeb, 0x8e, 0xad, 0x41, 0x62, + 0x07, 0x24, 0xcd, 0xee, 0x8b, 0xa8, 0x4e, 0x6d, 0x08, 0x2b, + 0xc2, 0xe1, 0x84, 0xa7, 0x4b, 0x68, 0x0d, 0x2e, 0xc7, 0xe4, + 0x81, 0xa2, 0x78, 0x5b, 0x3e, 0x1d, 0xf4, 0xd7, 0xb2, 0x91, + 0x7d, 0x5e, 0x3b, 0x18, 0xf1, 0xd2, 0xb7, 0x94, 0x72, 0x51, + 0x34, 0x17, 0xfe, 0xdd, 0xb8, 0x9b, 0x77, 0x54, 0x31, 0x12, + 0xfb, 0xd8, 0xbd, 0x9e, 0x6c, 0x4f, 0x2a, 0x09, 0xe0, 0xc3, + 0xa6, 0x85, 0x69, 0x4a, 0x2f, 0x0c, 0xe5, 0xc6, 0xa3, 0x80, + 0x66, 0x45, 0x20, 0x03, 0xea, 0xc9, 0xac, 0x8f, 0x63, 0x40, + 0x25, 0x06, 0xef, 0xcc, 0xa9, 0x8a, 0x00, 0x24, 0x48, 0x6c, + 0x90, 0xb4, 0xd8, 0xfc, 0x3d, 0x19, 0x75, 0x51, 0xad, 0x89, + 0xe5, 0xc1, 0x7a, 0x5e, 0x32, 0x16, 0xea, 0xce, 0xa2, 0x86, + 0x47, 0x63, 0x0f, 0x2b, 0xd7, 0xf3, 0x9f, 0xbb, 0xf4, 0xd0, + 0xbc, 0x98, 0x64, 0x40, 0x2c, 0x08, 0xc9, 0xed, 0x81, 0xa5, + 0x59, 0x7d, 0x11, 0x35, 0x8e, 0xaa, 0xc6, 0xe2, 0x1e, 0x3a, + 0x56, 0x72, 0xb3, 0x97, 0xfb, 0xdf, 0x23, 0x07, 0x6b, 0x4f, + 0xf5, 0xd1, 0xbd, 0x99, 0x65, 0x41, 0x2d, 0x09, 0xc8, 0xec, + 0x80, 0xa4, 0x58, 0x7c, 0x10, 0x34, 0x8f, 0xab, 0xc7, 0xe3, + 0x1f, 0x3b, 0x57, 0x73, 0xb2, 0x96, 0xfa, 0xde, 0x22, 0x06, + 0x6a, 0x4e, 0x01, 0x25, 0x49, 0x6d, 0x91, 0xb5, 0xd9, 0xfd, + 0x3c, 0x18, 0x74, 0x50, 0xac, 0x88, 0xe4, 0xc0, 0x7b, 0x5f, + 0x33, 0x17, 0xeb, 0xcf, 0xa3, 0x87, 0x46, 0x62, 0x0e, 0x2a, + 0xd6, 0xf2, 0x9e, 0xba, 0xf7, 0xd3, 0xbf, 0x9b, 0x67, 0x43, + 0x2f, 0x0b, 0xca, 0xee, 0x82, 0xa6, 0x5a, 0x7e, 0x12, 0x36, + 0x8d, 0xa9, 0xc5, 0xe1, 0x1d, 0x39, 0x55, 0x71, 0xb0, 0x94, + 0xf8, 0xdc, 0x20, 0x04, 0x68, 0x4c, 0x03, 0x27, 0x4b, 0x6f, + 0x93, 0xb7, 0xdb, 0xff, 0x3e, 0x1a, 0x76, 0x52, 0xae, 0x8a, + 0xe6, 0xc2, 0x79, 0x5d, 0x31, 0x15, 0xe9, 0xcd, 0xa1, 0x85, + 0x44, 0x60, 0x0c, 0x28, 0xd4, 0xf0, 0x9c, 0xb8, 0x02, 0x26, + 0x4a, 0x6e, 0x92, 0xb6, 0xda, 0xfe, 0x3f, 0x1b, 0x77, 0x53, + 0xaf, 0x8b, 0xe7, 0xc3, 0x78, 0x5c, 0x30, 0x14, 0xe8, 0xcc, + 0xa0, 0x84, 0x45, 0x61, 0x0d, 0x29, 0xd5, 0xf1, 0x9d, 0xb9, + 0xf6, 0xd2, 0xbe, 0x9a, 0x66, 0x42, 0x2e, 0x0a, 0xcb, 0xef, + 0x83, 0xa7, 0x5b, 0x7f, 0x13, 0x37, 0x8c, 0xa8, 0xc4, 0xe0, + 0x1c, 0x38, 0x54, 0x70, 0xb1, 0x95, 0xf9, 0xdd, 0x21, 0x05, + 0x69, 0x4d, 0x00, 0x25, 0x4a, 0x6f, 0x94, 0xb1, 0xde, 0xfb, + 0x35, 0x10, 0x7f, 0x5a, 0xa1, 0x84, 0xeb, 0xce, 0x6a, 0x4f, + 0x20, 0x05, 0xfe, 0xdb, 0xb4, 0x91, 0x5f, 0x7a, 0x15, 0x30, + 0xcb, 0xee, 0x81, 0xa4, 0xd4, 0xf1, 0x9e, 0xbb, 0x40, 0x65, + 0x0a, 0x2f, 0xe1, 0xc4, 0xab, 0x8e, 0x75, 0x50, 0x3f, 0x1a, + 0xbe, 0x9b, 0xf4, 0xd1, 0x2a, 0x0f, 0x60, 0x45, 0x8b, 0xae, + 0xc1, 0xe4, 0x1f, 0x3a, 0x55, 0x70, 0xb5, 0x90, 0xff, 0xda, + 0x21, 0x04, 0x6b, 0x4e, 0x80, 0xa5, 0xca, 0xef, 0x14, 0x31, + 0x5e, 0x7b, 0xdf, 0xfa, 0x95, 0xb0, 0x4b, 0x6e, 0x01, 0x24, + 0xea, 0xcf, 0xa0, 0x85, 0x7e, 0x5b, 0x34, 0x11, 0x61, 0x44, + 0x2b, 0x0e, 0xf5, 0xd0, 0xbf, 0x9a, 0x54, 0x71, 0x1e, 0x3b, + 0xc0, 0xe5, 0x8a, 0xaf, 0x0b, 0x2e, 0x41, 0x64, 0x9f, 0xba, + 0xd5, 0xf0, 0x3e, 0x1b, 0x74, 0x51, 0xaa, 0x8f, 0xe0, 0xc5, + 0x77, 0x52, 0x3d, 0x18, 0xe3, 0xc6, 0xa9, 0x8c, 0x42, 0x67, + 0x08, 0x2d, 0xd6, 0xf3, 0x9c, 0xb9, 0x1d, 0x38, 0x57, 0x72, + 0x89, 0xac, 0xc3, 0xe6, 0x28, 0x0d, 0x62, 0x47, 0xbc, 0x99, + 0xf6, 0xd3, 0xa3, 0x86, 0xe9, 0xcc, 0x37, 0x12, 0x7d, 0x58, + 0x96, 0xb3, 0xdc, 0xf9, 0x02, 0x27, 0x48, 0x6d, 0xc9, 0xec, + 0x83, 0xa6, 0x5d, 0x78, 0x17, 0x32, 0xfc, 0xd9, 0xb6, 0x93, + 0x68, 0x4d, 0x22, 0x07, 0xc2, 0xe7, 0x88, 0xad, 0x56, 0x73, + 0x1c, 0x39, 0xf7, 0xd2, 0xbd, 0x98, 0x63, 0x46, 0x29, 0x0c, + 0xa8, 0x8d, 0xe2, 0xc7, 0x3c, 0x19, 0x76, 0x53, 0x9d, 0xb8, + 0xd7, 0xf2, 0x09, 0x2c, 0x43, 0x66, 0x16, 0x33, 0x5c, 0x79, + 0x82, 0xa7, 0xc8, 0xed, 0x23, 0x06, 0x69, 0x4c, 0xb7, 0x92, + 0xfd, 0xd8, 0x7c, 0x59, 0x36, 0x13, 0xe8, 0xcd, 0xa2, 0x87, + 0x49, 0x6c, 0x03, 0x26, 0xdd, 0xf8, 0x97, 0xb2, 0x00, 0x26, + 0x4c, 0x6a, 0x98, 0xbe, 0xd4, 0xf2, 0x2d, 0x0b, 0x61, 0x47, + 0xb5, 0x93, 0xf9, 0xdf, 0x5a, 0x7c, 0x16, 0x30, 0xc2, 0xe4, + 0x8e, 0xa8, 0x77, 0x51, 0x3b, 0x1d, 0xef, 0xc9, 0xa3, 0x85, + 0xb4, 0x92, 0xf8, 0xde, 0x2c, 0x0a, 0x60, 0x46, 0x99, 0xbf, + 0xd5, 0xf3, 0x01, 0x27, 0x4d, 0x6b, 0xee, 0xc8, 0xa2, 0x84, + 0x76, 0x50, 0x3a, 0x1c, 0xc3, 0xe5, 0x8f, 0xa9, 0x5b, 0x7d, + 0x17, 0x31, 0x75, 0x53, 0x39, 0x1f, 0xed, 0xcb, 0xa1, 0x87, + 0x58, 0x7e, 0x14, 0x32, 0xc0, 0xe6, 0x8c, 0xaa, 0x2f, 0x09, + 0x63, 0x45, 0xb7, 0x91, 0xfb, 0xdd, 0x02, 0x24, 0x4e, 0x68, + 0x9a, 0xbc, 0xd6, 0xf0, 0xc1, 0xe7, 0x8d, 0xab, 0x59, 0x7f, + 0x15, 0x33, 0xec, 0xca, 0xa0, 0x86, 0x74, 0x52, 0x38, 0x1e, + 0x9b, 0xbd, 0xd7, 0xf1, 0x03, 0x25, 0x4f, 0x69, 0xb6, 0x90, + 0xfa, 0xdc, 0x2e, 0x08, 0x62, 0x44, 0xea, 0xcc, 0xa6, 0x80, + 0x72, 0x54, 0x3e, 0x18, 0xc7, 0xe1, 0x8b, 0xad, 0x5f, 0x79, + 0x13, 0x35, 0xb0, 0x96, 0xfc, 0xda, 0x28, 0x0e, 0x64, 0x42, + 0x9d, 0xbb, 0xd1, 0xf7, 0x05, 0x23, 0x49, 0x6f, 0x5e, 0x78, + 0x12, 0x34, 0xc6, 0xe0, 0x8a, 0xac, 0x73, 0x55, 0x3f, 0x19, + 0xeb, 0xcd, 0xa7, 0x81, 0x04, 0x22, 0x48, 0x6e, 0x9c, 0xba, + 0xd0, 0xf6, 0x29, 0x0f, 0x65, 0x43, 0xb1, 0x97, 0xfd, 0xdb, + 0x9f, 0xb9, 0xd3, 0xf5, 0x07, 0x21, 0x4b, 0x6d, 0xb2, 0x94, + 0xfe, 0xd8, 0x2a, 0x0c, 0x66, 0x40, 0xc5, 0xe3, 0x89, 0xaf, + 0x5d, 0x7b, 0x11, 0x37, 0xe8, 0xce, 0xa4, 0x82, 0x70, 0x56, + 0x3c, 0x1a, 0x2b, 0x0d, 0x67, 0x41, 0xb3, 0x95, 0xff, 0xd9, + 0x06, 0x20, 0x4a, 0x6c, 0x9e, 0xb8, 0xd2, 0xf4, 0x71, 0x57, + 0x3d, 0x1b, 0xe9, 0xcf, 0xa5, 0x83, 0x5c, 0x7a, 0x10, 0x36, + 0xc4, 0xe2, 0x88, 0xae, 0x00, 0x27, 0x4e, 0x69, 0x9c, 0xbb, + 0xd2, 0xf5, 0x25, 0x02, 0x6b, 0x4c, 0xb9, 0x9e, 0xf7, 0xd0, + 0x4a, 0x6d, 0x04, 0x23, 0xd6, 0xf1, 0x98, 0xbf, 0x6f, 0x48, + 0x21, 0x06, 0xf3, 0xd4, 0xbd, 0x9a, 0x94, 0xb3, 0xda, 0xfd, + 0x08, 0x2f, 0x46, 0x61, 0xb1, 0x96, 0xff, 0xd8, 0x2d, 0x0a, + 0x63, 0x44, 0xde, 0xf9, 0x90, 0xb7, 0x42, 0x65, 0x0c, 0x2b, + 0xfb, 0xdc, 0xb5, 0x92, 0x67, 0x40, 0x29, 0x0e, 0x35, 0x12, + 0x7b, 0x5c, 0xa9, 0x8e, 0xe7, 0xc0, 0x10, 0x37, 0x5e, 0x79, + 0x8c, 0xab, 0xc2, 0xe5, 0x7f, 0x58, 0x31, 0x16, 0xe3, 0xc4, + 0xad, 0x8a, 0x5a, 0x7d, 0x14, 0x33, 0xc6, 0xe1, 0x88, 0xaf, + 0xa1, 0x86, 0xef, 0xc8, 0x3d, 0x1a, 0x73, 0x54, 0x84, 0xa3, + 0xca, 0xed, 0x18, 0x3f, 0x56, 0x71, 0xeb, 0xcc, 0xa5, 0x82, + 0x77, 0x50, 0x39, 0x1e, 0xce, 0xe9, 0x80, 0xa7, 0x52, 0x75, + 0x1c, 0x3b, 0x6a, 0x4d, 0x24, 0x03, 0xf6, 0xd1, 0xb8, 0x9f, + 0x4f, 0x68, 0x01, 0x26, 0xd3, 0xf4, 0x9d, 0xba, 0x20, 0x07, + 0x6e, 0x49, 0xbc, 0x9b, 0xf2, 0xd5, 0x05, 0x22, 0x4b, 0x6c, + 0x99, 0xbe, 0xd7, 0xf0, 0xfe, 0xd9, 0xb0, 0x97, 0x62, 0x45, + 0x2c, 0x0b, 0xdb, 0xfc, 0x95, 0xb2, 0x47, 0x60, 0x09, 0x2e, + 0xb4, 0x93, 0xfa, 0xdd, 0x28, 0x0f, 0x66, 0x41, 0x91, 0xb6, + 0xdf, 0xf8, 0x0d, 0x2a, 0x43, 0x64, 0x5f, 0x78, 0x11, 0x36, + 0xc3, 0xe4, 0x8d, 0xaa, 0x7a, 0x5d, 0x34, 0x13, 0xe6, 0xc1, + 0xa8, 0x8f, 0x15, 0x32, 0x5b, 0x7c, 0x89, 0xae, 0xc7, 0xe0, + 0x30, 0x17, 0x7e, 0x59, 0xac, 0x8b, 0xe2, 0xc5, 0xcb, 0xec, + 0x85, 0xa2, 0x57, 0x70, 0x19, 0x3e, 0xee, 0xc9, 0xa0, 0x87, + 0x72, 0x55, 0x3c, 0x1b, 0x81, 0xa6, 0xcf, 0xe8, 0x1d, 0x3a, + 0x53, 0x74, 0xa4, 0x83, 0xea, 0xcd, 0x38, 0x1f, 0x76, 0x51, + 0x00, 0x28, 0x50, 0x78, 0xa0, 0x88, 0xf0, 0xd8, 0x5d, 0x75, + 0x0d, 0x25, 0xfd, 0xd5, 0xad, 0x85, 0xba, 0x92, 0xea, 0xc2, + 0x1a, 0x32, 0x4a, 0x62, 0xe7, 0xcf, 0xb7, 0x9f, 0x47, 0x6f, + 0x17, 0x3f, 0x69, 0x41, 0x39, 0x11, 0xc9, 0xe1, 0x99, 0xb1, + 0x34, 0x1c, 0x64, 0x4c, 0x94, 0xbc, 0xc4, 0xec, 0xd3, 0xfb, + 0x83, 0xab, 0x73, 0x5b, 0x23, 0x0b, 0x8e, 0xa6, 0xde, 0xf6, + 0x2e, 0x06, 0x7e, 0x56, 0xd2, 0xfa, 0x82, 0xaa, 0x72, 0x5a, + 0x22, 0x0a, 0x8f, 0xa7, 0xdf, 0xf7, 0x2f, 0x07, 0x7f, 0x57, + 0x68, 0x40, 0x38, 0x10, 0xc8, 0xe0, 0x98, 0xb0, 0x35, 0x1d, + 0x65, 0x4d, 0x95, 0xbd, 0xc5, 0xed, 0xbb, 0x93, 0xeb, 0xc3, + 0x1b, 0x33, 0x4b, 0x63, 0xe6, 0xce, 0xb6, 0x9e, 0x46, 0x6e, + 0x16, 0x3e, 0x01, 0x29, 0x51, 0x79, 0xa1, 0x89, 0xf1, 0xd9, + 0x5c, 0x74, 0x0c, 0x24, 0xfc, 0xd4, 0xac, 0x84, 0xb9, 0x91, + 0xe9, 0xc1, 0x19, 0x31, 0x49, 0x61, 0xe4, 0xcc, 0xb4, 0x9c, + 0x44, 0x6c, 0x14, 0x3c, 0x03, 0x2b, 0x53, 0x7b, 0xa3, 0x8b, + 0xf3, 0xdb, 0x5e, 0x76, 0x0e, 0x26, 0xfe, 0xd6, 0xae, 0x86, + 0xd0, 0xf8, 0x80, 0xa8, 0x70, 0x58, 0x20, 0x08, 0x8d, 0xa5, + 0xdd, 0xf5, 0x2d, 0x05, 0x7d, 0x55, 0x6a, 0x42, 0x3a, 0x12, + 0xca, 0xe2, 0x9a, 0xb2, 0x37, 0x1f, 0x67, 0x4f, 0x97, 0xbf, + 0xc7, 0xef, 0x6b, 0x43, 0x3b, 0x13, 0xcb, 0xe3, 0x9b, 0xb3, + 0x36, 0x1e, 0x66, 0x4e, 0x96, 0xbe, 0xc6, 0xee, 0xd1, 0xf9, + 0x81, 0xa9, 0x71, 0x59, 0x21, 0x09, 0x8c, 0xa4, 0xdc, 0xf4, + 0x2c, 0x04, 0x7c, 0x54, 0x02, 0x2a, 0x52, 0x7a, 0xa2, 0x8a, + 0xf2, 0xda, 0x5f, 0x77, 0x0f, 0x27, 0xff, 0xd7, 0xaf, 0x87, + 0xb8, 0x90, 0xe8, 0xc0, 0x18, 0x30, 0x48, 0x60, 0xe5, 0xcd, + 0xb5, 0x9d, 0x45, 0x6d, 0x15, 0x3d, 0x00, 0x29, 0x52, 0x7b, + 0xa4, 0x8d, 0xf6, 0xdf, 0x55, 0x7c, 0x07, 0x2e, 0xf1, 0xd8, + 0xa3, 0x8a, 0xaa, 0x83, 0xf8, 0xd1, 0x0e, 0x27, 0x5c, 0x75, + 0xff, 0xd6, 0xad, 0x84, 0x5b, 0x72, 0x09, 0x20, 0x49, 0x60, + 0x1b, 0x32, 0xed, 0xc4, 0xbf, 0x96, 0x1c, 0x35, 0x4e, 0x67, + 0xb8, 0x91, 0xea, 0xc3, 0xe3, 0xca, 0xb1, 0x98, 0x47, 0x6e, + 0x15, 0x3c, 0xb6, 0x9f, 0xe4, 0xcd, 0x12, 0x3b, 0x40, 0x69, + 0x92, 0xbb, 0xc0, 0xe9, 0x36, 0x1f, 0x64, 0x4d, 0xc7, 0xee, + 0x95, 0xbc, 0x63, 0x4a, 0x31, 0x18, 0x38, 0x11, 0x6a, 0x43, + 0x9c, 0xb5, 0xce, 0xe7, 0x6d, 0x44, 0x3f, 0x16, 0xc9, 0xe0, + 0x9b, 0xb2, 0xdb, 0xf2, 0x89, 0xa0, 0x7f, 0x56, 0x2d, 0x04, + 0x8e, 0xa7, 0xdc, 0xf5, 0x2a, 0x03, 0x78, 0x51, 0x71, 0x58, + 0x23, 0x0a, 0xd5, 0xfc, 0x87, 0xae, 0x24, 0x0d, 0x76, 0x5f, + 0x80, 0xa9, 0xd2, 0xfb, 0x39, 0x10, 0x6b, 0x42, 0x9d, 0xb4, + 0xcf, 0xe6, 0x6c, 0x45, 0x3e, 0x17, 0xc8, 0xe1, 0x9a, 0xb3, + 0x93, 0xba, 0xc1, 0xe8, 0x37, 0x1e, 0x65, 0x4c, 0xc6, 0xef, + 0x94, 0xbd, 0x62, 0x4b, 0x30, 0x19, 0x70, 0x59, 0x22, 0x0b, + 0xd4, 0xfd, 0x86, 0xaf, 0x25, 0x0c, 0x77, 0x5e, 0x81, 0xa8, + 0xd3, 0xfa, 0xda, 0xf3, 0x88, 0xa1, 0x7e, 0x57, 0x2c, 0x05, + 0x8f, 0xa6, 0xdd, 0xf4, 0x2b, 0x02, 0x79, 0x50, 0xab, 0x82, + 0xf9, 0xd0, 0x0f, 0x26, 0x5d, 0x74, 0xfe, 0xd7, 0xac, 0x85, + 0x5a, 0x73, 0x08, 0x21, 0x01, 0x28, 0x53, 0x7a, 0xa5, 0x8c, + 0xf7, 0xde, 0x54, 0x7d, 0x06, 0x2f, 0xf0, 0xd9, 0xa2, 0x8b, + 0xe2, 0xcb, 0xb0, 0x99, 0x46, 0x6f, 0x14, 0x3d, 0xb7, 0x9e, + 0xe5, 0xcc, 0x13, 0x3a, 0x41, 0x68, 0x48, 0x61, 0x1a, 0x33, + 0xec, 0xc5, 0xbe, 0x97, 0x1d, 0x34, 0x4f, 0x66, 0xb9, 0x90, + 0xeb, 0xc2, 0x00, 0x2a, 0x54, 0x7e, 0xa8, 0x82, 0xfc, 0xd6, + 0x4d, 0x67, 0x19, 0x33, 0xe5, 0xcf, 0xb1, 0x9b, 0x9a, 0xb0, + 0xce, 0xe4, 0x32, 0x18, 0x66, 0x4c, 0xd7, 0xfd, 0x83, 0xa9, + 0x7f, 0x55, 0x2b, 0x01, 0x29, 0x03, 0x7d, 0x57, 0x81, 0xab, + 0xd5, 0xff, 0x64, 0x4e, 0x30, 0x1a, 0xcc, 0xe6, 0x98, 0xb2, + 0xb3, 0x99, 0xe7, 0xcd, 0x1b, 0x31, 0x4f, 0x65, 0xfe, 0xd4, + 0xaa, 0x80, 0x56, 0x7c, 0x02, 0x28, 0x52, 0x78, 0x06, 0x2c, + 0xfa, 0xd0, 0xae, 0x84, 0x1f, 0x35, 0x4b, 0x61, 0xb7, 0x9d, + 0xe3, 0xc9, 0xc8, 0xe2, 0x9c, 0xb6, 0x60, 0x4a, 0x34, 0x1e, + 0x85, 0xaf, 0xd1, 0xfb, 0x2d, 0x07, 0x79, 0x53, 0x7b, 0x51, + 0x2f, 0x05, 0xd3, 0xf9, 0x87, 0xad, 0x36, 0x1c, 0x62, 0x48, + 0x9e, 0xb4, 0xca, 0xe0, 0xe1, 0xcb, 0xb5, 0x9f, 0x49, 0x63, + 0x1d, 0x37, 0xac, 0x86, 0xf8, 0xd2, 0x04, 0x2e, 0x50, 0x7a, + 0xa4, 0x8e, 0xf0, 0xda, 0x0c, 0x26, 0x58, 0x72, 0xe9, 0xc3, + 0xbd, 0x97, 0x41, 0x6b, 0x15, 0x3f, 0x3e, 0x14, 0x6a, 0x40, + 0x96, 0xbc, 0xc2, 0xe8, 0x73, 0x59, 0x27, 0x0d, 0xdb, 0xf1, + 0x8f, 0xa5, 0x8d, 0xa7, 0xd9, 0xf3, 0x25, 0x0f, 0x71, 0x5b, + 0xc0, 0xea, 0x94, 0xbe, 0x68, 0x42, 0x3c, 0x16, 0x17, 0x3d, + 0x43, 0x69, 0xbf, 0x95, 0xeb, 0xc1, 0x5a, 0x70, 0x0e, 0x24, + 0xf2, 0xd8, 0xa6, 0x8c, 0xf6, 0xdc, 0xa2, 0x88, 0x5e, 0x74, + 0x0a, 0x20, 0xbb, 0x91, 0xef, 0xc5, 0x13, 0x39, 0x47, 0x6d, + 0x6c, 0x46, 0x38, 0x12, 0xc4, 0xee, 0x90, 0xba, 0x21, 0x0b, + 0x75, 0x5f, 0x89, 0xa3, 0xdd, 0xf7, 0xdf, 0xf5, 0x8b, 0xa1, + 0x77, 0x5d, 0x23, 0x09, 0x92, 0xb8, 0xc6, 0xec, 0x3a, 0x10, + 0x6e, 0x44, 0x45, 0x6f, 0x11, 0x3b, 0xed, 0xc7, 0xb9, 0x93, + 0x08, 0x22, 0x5c, 0x76, 0xa0, 0x8a, 0xf4, 0xde, 0x00, 0x2b, + 0x56, 0x7d, 0xac, 0x87, 0xfa, 0xd1, 0x45, 0x6e, 0x13, 0x38, + 0xe9, 0xc2, 0xbf, 0x94, 0x8a, 0xa1, 0xdc, 0xf7, 0x26, 0x0d, + 0x70, 0x5b, 0xcf, 0xe4, 0x99, 0xb2, 0x63, 0x48, 0x35, 0x1e, + 0x09, 0x22, 0x5f, 0x74, 0xa5, 0x8e, 0xf3, 0xd8, 0x4c, 0x67, + 0x1a, 0x31, 0xe0, 0xcb, 0xb6, 0x9d, 0x83, 0xa8, 0xd5, 0xfe, + 0x2f, 0x04, 0x79, 0x52, 0xc6, 0xed, 0x90, 0xbb, 0x6a, 0x41, + 0x3c, 0x17, 0x12, 0x39, 0x44, 0x6f, 0xbe, 0x95, 0xe8, 0xc3, + 0x57, 0x7c, 0x01, 0x2a, 0xfb, 0xd0, 0xad, 0x86, 0x98, 0xb3, + 0xce, 0xe5, 0x34, 0x1f, 0x62, 0x49, 0xdd, 0xf6, 0x8b, 0xa0, + 0x71, 0x5a, 0x27, 0x0c, 0x1b, 0x30, 0x4d, 0x66, 0xb7, 0x9c, + 0xe1, 0xca, 0x5e, 0x75, 0x08, 0x23, 0xf2, 0xd9, 0xa4, 0x8f, + 0x91, 0xba, 0xc7, 0xec, 0x3d, 0x16, 0x6b, 0x40, 0xd4, 0xff, + 0x82, 0xa9, 0x78, 0x53, 0x2e, 0x05, 0x24, 0x0f, 0x72, 0x59, + 0x88, 0xa3, 0xde, 0xf5, 0x61, 0x4a, 0x37, 0x1c, 0xcd, 0xe6, + 0x9b, 0xb0, 0xae, 0x85, 0xf8, 0xd3, 0x02, 0x29, 0x54, 0x7f, + 0xeb, 0xc0, 0xbd, 0x96, 0x47, 0x6c, 0x11, 0x3a, 0x2d, 0x06, + 0x7b, 0x50, 0x81, 0xaa, 0xd7, 0xfc, 0x68, 0x43, 0x3e, 0x15, + 0xc4, 0xef, 0x92, 0xb9, 0xa7, 0x8c, 0xf1, 0xda, 0x0b, 0x20, + 0x5d, 0x76, 0xe2, 0xc9, 0xb4, 0x9f, 0x4e, 0x65, 0x18, 0x33, + 0x36, 0x1d, 0x60, 0x4b, 0x9a, 0xb1, 0xcc, 0xe7, 0x73, 0x58, + 0x25, 0x0e, 0xdf, 0xf4, 0x89, 0xa2, 0xbc, 0x97, 0xea, 0xc1, + 0x10, 0x3b, 0x46, 0x6d, 0xf9, 0xd2, 0xaf, 0x84, 0x55, 0x7e, + 0x03, 0x28, 0x3f, 0x14, 0x69, 0x42, 0x93, 0xb8, 0xc5, 0xee, + 0x7a, 0x51, 0x2c, 0x07, 0xd6, 0xfd, 0x80, 0xab, 0xb5, 0x9e, + 0xe3, 0xc8, 0x19, 0x32, 0x4f, 0x64, 0xf0, 0xdb, 0xa6, 0x8d, + 0x5c, 0x77, 0x0a, 0x21, 0x00, 0x2c, 0x58, 0x74, 0xb0, 0x9c, + 0xe8, 0xc4, 0x7d, 0x51, 0x25, 0x09, 0xcd, 0xe1, 0x95, 0xb9, + 0xfa, 0xd6, 0xa2, 0x8e, 0x4a, 0x66, 0x12, 0x3e, 0x87, 0xab, + 0xdf, 0xf3, 0x37, 0x1b, 0x6f, 0x43, 0xe9, 0xc5, 0xb1, 0x9d, + 0x59, 0x75, 0x01, 0x2d, 0x94, 0xb8, 0xcc, 0xe0, 0x24, 0x08, + 0x7c, 0x50, 0x13, 0x3f, 0x4b, 0x67, 0xa3, 0x8f, 0xfb, 0xd7, + 0x6e, 0x42, 0x36, 0x1a, 0xde, 0xf2, 0x86, 0xaa, 0xcf, 0xe3, + 0x97, 0xbb, 0x7f, 0x53, 0x27, 0x0b, 0xb2, 0x9e, 0xea, 0xc6, + 0x02, 0x2e, 0x5a, 0x76, 0x35, 0x19, 0x6d, 0x41, 0x85, 0xa9, + 0xdd, 0xf1, 0x48, 0x64, 0x10, 0x3c, 0xf8, 0xd4, 0xa0, 0x8c, + 0x26, 0x0a, 0x7e, 0x52, 0x96, 0xba, 0xce, 0xe2, 0x5b, 0x77, + 0x03, 0x2f, 0xeb, 0xc7, 0xb3, 0x9f, 0xdc, 0xf0, 0x84, 0xa8, + 0x6c, 0x40, 0x34, 0x18, 0xa1, 0x8d, 0xf9, 0xd5, 0x11, 0x3d, + 0x49, 0x65, 0x83, 0xaf, 0xdb, 0xf7, 0x33, 0x1f, 0x6b, 0x47, + 0xfe, 0xd2, 0xa6, 0x8a, 0x4e, 0x62, 0x16, 0x3a, 0x79, 0x55, + 0x21, 0x0d, 0xc9, 0xe5, 0x91, 0xbd, 0x04, 0x28, 0x5c, 0x70, + 0xb4, 0x98, 0xec, 0xc0, 0x6a, 0x46, 0x32, 0x1e, 0xda, 0xf6, + 0x82, 0xae, 0x17, 0x3b, 0x4f, 0x63, 0xa7, 0x8b, 0xff, 0xd3, + 0x90, 0xbc, 0xc8, 0xe4, 0x20, 0x0c, 0x78, 0x54, 0xed, 0xc1, + 0xb5, 0x99, 0x5d, 0x71, 0x05, 0x29, 0x4c, 0x60, 0x14, 0x38, + 0xfc, 0xd0, 0xa4, 0x88, 0x31, 0x1d, 0x69, 0x45, 0x81, 0xad, + 0xd9, 0xf5, 0xb6, 0x9a, 0xee, 0xc2, 0x06, 0x2a, 0x5e, 0x72, + 0xcb, 0xe7, 0x93, 0xbf, 0x7b, 0x57, 0x23, 0x0f, 0xa5, 0x89, + 0xfd, 0xd1, 0x15, 0x39, 0x4d, 0x61, 0xd8, 0xf4, 0x80, 0xac, + 0x68, 0x44, 0x30, 0x1c, 0x5f, 0x73, 0x07, 0x2b, 0xef, 0xc3, + 0xb7, 0x9b, 0x22, 0x0e, 0x7a, 0x56, 0x92, 0xbe, 0xca, 0xe6, + 0x00, 0x2d, 0x5a, 0x77, 0xb4, 0x99, 0xee, 0xc3, 0x75, 0x58, + 0x2f, 0x02, 0xc1, 0xec, 0x9b, 0xb6, 0xea, 0xc7, 0xb0, 0x9d, + 0x5e, 0x73, 0x04, 0x29, 0x9f, 0xb2, 0xc5, 0xe8, 0x2b, 0x06, + 0x71, 0x5c, 0xc9, 0xe4, 0x93, 0xbe, 0x7d, 0x50, 0x27, 0x0a, + 0xbc, 0x91, 0xe6, 0xcb, 0x08, 0x25, 0x52, 0x7f, 0x23, 0x0e, + 0x79, 0x54, 0x97, 0xba, 0xcd, 0xe0, 0x56, 0x7b, 0x0c, 0x21, + 0xe2, 0xcf, 0xb8, 0x95, 0x8f, 0xa2, 0xd5, 0xf8, 0x3b, 0x16, + 0x61, 0x4c, 0xfa, 0xd7, 0xa0, 0x8d, 0x4e, 0x63, 0x14, 0x39, + 0x65, 0x48, 0x3f, 0x12, 0xd1, 0xfc, 0x8b, 0xa6, 0x10, 0x3d, + 0x4a, 0x67, 0xa4, 0x89, 0xfe, 0xd3, 0x46, 0x6b, 0x1c, 0x31, + 0xf2, 0xdf, 0xa8, 0x85, 0x33, 0x1e, 0x69, 0x44, 0x87, 0xaa, + 0xdd, 0xf0, 0xac, 0x81, 0xf6, 0xdb, 0x18, 0x35, 0x42, 0x6f, + 0xd9, 0xf4, 0x83, 0xae, 0x6d, 0x40, 0x37, 0x1a, 0x03, 0x2e, + 0x59, 0x74, 0xb7, 0x9a, 0xed, 0xc0, 0x76, 0x5b, 0x2c, 0x01, + 0xc2, 0xef, 0x98, 0xb5, 0xe9, 0xc4, 0xb3, 0x9e, 0x5d, 0x70, + 0x07, 0x2a, 0x9c, 0xb1, 0xc6, 0xeb, 0x28, 0x05, 0x72, 0x5f, + 0xca, 0xe7, 0x90, 0xbd, 0x7e, 0x53, 0x24, 0x09, 0xbf, 0x92, + 0xe5, 0xc8, 0x0b, 0x26, 0x51, 0x7c, 0x20, 0x0d, 0x7a, 0x57, + 0x94, 0xb9, 0xce, 0xe3, 0x55, 0x78, 0x0f, 0x22, 0xe1, 0xcc, + 0xbb, 0x96, 0x8c, 0xa1, 0xd6, 0xfb, 0x38, 0x15, 0x62, 0x4f, + 0xf9, 0xd4, 0xa3, 0x8e, 0x4d, 0x60, 0x17, 0x3a, 0x66, 0x4b, + 0x3c, 0x11, 0xd2, 0xff, 0x88, 0xa5, 0x13, 0x3e, 0x49, 0x64, + 0xa7, 0x8a, 0xfd, 0xd0, 0x45, 0x68, 0x1f, 0x32, 0xf1, 0xdc, + 0xab, 0x86, 0x30, 0x1d, 0x6a, 0x47, 0x84, 0xa9, 0xde, 0xf3, + 0xaf, 0x82, 0xf5, 0xd8, 0x1b, 0x36, 0x41, 0x6c, 0xda, 0xf7, + 0x80, 0xad, 0x6e, 0x43, 0x34, 0x19, 0x00, 0x2e, 0x5c, 0x72, + 0xb8, 0x96, 0xe4, 0xca, 0x6d, 0x43, 0x31, 0x1f, 0xd5, 0xfb, + 0x89, 0xa7, 0xda, 0xf4, 0x86, 0xa8, 0x62, 0x4c, 0x3e, 0x10, + 0xb7, 0x99, 0xeb, 0xc5, 0x0f, 0x21, 0x53, 0x7d, 0xa9, 0x87, + 0xf5, 0xdb, 0x11, 0x3f, 0x4d, 0x63, 0xc4, 0xea, 0x98, 0xb6, + 0x7c, 0x52, 0x20, 0x0e, 0x73, 0x5d, 0x2f, 0x01, 0xcb, 0xe5, + 0x97, 0xb9, 0x1e, 0x30, 0x42, 0x6c, 0xa6, 0x88, 0xfa, 0xd4, + 0x4f, 0x61, 0x13, 0x3d, 0xf7, 0xd9, 0xab, 0x85, 0x22, 0x0c, + 0x7e, 0x50, 0x9a, 0xb4, 0xc6, 0xe8, 0x95, 0xbb, 0xc9, 0xe7, + 0x2d, 0x03, 0x71, 0x5f, 0xf8, 0xd6, 0xa4, 0x8a, 0x40, 0x6e, + 0x1c, 0x32, 0xe6, 0xc8, 0xba, 0x94, 0x5e, 0x70, 0x02, 0x2c, + 0x8b, 0xa5, 0xd7, 0xf9, 0x33, 0x1d, 0x6f, 0x41, 0x3c, 0x12, + 0x60, 0x4e, 0x84, 0xaa, 0xd8, 0xf6, 0x51, 0x7f, 0x0d, 0x23, + 0xe9, 0xc7, 0xb5, 0x9b, 0x9e, 0xb0, 0xc2, 0xec, 0x26, 0x08, + 0x7a, 0x54, 0xf3, 0xdd, 0xaf, 0x81, 0x4b, 0x65, 0x17, 0x39, + 0x44, 0x6a, 0x18, 0x36, 0xfc, 0xd2, 0xa0, 0x8e, 0x29, 0x07, + 0x75, 0x5b, 0x91, 0xbf, 0xcd, 0xe3, 0x37, 0x19, 0x6b, 0x45, + 0x8f, 0xa1, 0xd3, 0xfd, 0x5a, 0x74, 0x06, 0x28, 0xe2, 0xcc, + 0xbe, 0x90, 0xed, 0xc3, 0xb1, 0x9f, 0x55, 0x7b, 0x09, 0x27, + 0x80, 0xae, 0xdc, 0xf2, 0x38, 0x16, 0x64, 0x4a, 0xd1, 0xff, + 0x8d, 0xa3, 0x69, 0x47, 0x35, 0x1b, 0xbc, 0x92, 0xe0, 0xce, + 0x04, 0x2a, 0x58, 0x76, 0x0b, 0x25, 0x57, 0x79, 0xb3, 0x9d, + 0xef, 0xc1, 0x66, 0x48, 0x3a, 0x14, 0xde, 0xf0, 0x82, 0xac, + 0x78, 0x56, 0x24, 0x0a, 0xc0, 0xee, 0x9c, 0xb2, 0x15, 0x3b, + 0x49, 0x67, 0xad, 0x83, 0xf1, 0xdf, 0xa2, 0x8c, 0xfe, 0xd0, + 0x1a, 0x34, 0x46, 0x68, 0xcf, 0xe1, 0x93, 0xbd, 0x77, 0x59, + 0x2b, 0x05, 0x00, 0x2f, 0x5e, 0x71, 0xbc, 0x93, 0xe2, 0xcd, + 0x65, 0x4a, 0x3b, 0x14, 0xd9, 0xf6, 0x87, 0xa8, 0xca, 0xe5, + 0x94, 0xbb, 0x76, 0x59, 0x28, 0x07, 0xaf, 0x80, 0xf1, 0xde, + 0x13, 0x3c, 0x4d, 0x62, 0x89, 0xa6, 0xd7, 0xf8, 0x35, 0x1a, + 0x6b, 0x44, 0xec, 0xc3, 0xb2, 0x9d, 0x50, 0x7f, 0x0e, 0x21, + 0x43, 0x6c, 0x1d, 0x32, 0xff, 0xd0, 0xa1, 0x8e, 0x26, 0x09, + 0x78, 0x57, 0x9a, 0xb5, 0xc4, 0xeb, 0x0f, 0x20, 0x51, 0x7e, + 0xb3, 0x9c, 0xed, 0xc2, 0x6a, 0x45, 0x34, 0x1b, 0xd6, 0xf9, + 0x88, 0xa7, 0xc5, 0xea, 0x9b, 0xb4, 0x79, 0x56, 0x27, 0x08, + 0xa0, 0x8f, 0xfe, 0xd1, 0x1c, 0x33, 0x42, 0x6d, 0x86, 0xa9, + 0xd8, 0xf7, 0x3a, 0x15, 0x64, 0x4b, 0xe3, 0xcc, 0xbd, 0x92, + 0x5f, 0x70, 0x01, 0x2e, 0x4c, 0x63, 0x12, 0x3d, 0xf0, 0xdf, + 0xae, 0x81, 0x29, 0x06, 0x77, 0x58, 0x95, 0xba, 0xcb, 0xe4, + 0x1e, 0x31, 0x40, 0x6f, 0xa2, 0x8d, 0xfc, 0xd3, 0x7b, 0x54, + 0x25, 0x0a, 0xc7, 0xe8, 0x99, 0xb6, 0xd4, 0xfb, 0x8a, 0xa5, + 0x68, 0x47, 0x36, 0x19, 0xb1, 0x9e, 0xef, 0xc0, 0x0d, 0x22, + 0x53, 0x7c, 0x97, 0xb8, 0xc9, 0xe6, 0x2b, 0x04, 0x75, 0x5a, + 0xf2, 0xdd, 0xac, 0x83, 0x4e, 0x61, 0x10, 0x3f, 0x5d, 0x72, + 0x03, 0x2c, 0xe1, 0xce, 0xbf, 0x90, 0x38, 0x17, 0x66, 0x49, + 0x84, 0xab, 0xda, 0xf5, 0x11, 0x3e, 0x4f, 0x60, 0xad, 0x82, + 0xf3, 0xdc, 0x74, 0x5b, 0x2a, 0x05, 0xc8, 0xe7, 0x96, 0xb9, + 0xdb, 0xf4, 0x85, 0xaa, 0x67, 0x48, 0x39, 0x16, 0xbe, 0x91, + 0xe0, 0xcf, 0x02, 0x2d, 0x5c, 0x73, 0x98, 0xb7, 0xc6, 0xe9, + 0x24, 0x0b, 0x7a, 0x55, 0xfd, 0xd2, 0xa3, 0x8c, 0x41, 0x6e, + 0x1f, 0x30, 0x52, 0x7d, 0x0c, 0x23, 0xee, 0xc1, 0xb0, 0x9f, + 0x37, 0x18, 0x69, 0x46, 0x8b, 0xa4, 0xd5, 0xfa, 0x00, 0x30, + 0x60, 0x50, 0xc0, 0xf0, 0xa0, 0x90, 0x9d, 0xad, 0xfd, 0xcd, + 0x5d, 0x6d, 0x3d, 0x0d, 0x27, 0x17, 0x47, 0x77, 0xe7, 0xd7, + 0x87, 0xb7, 0xba, 0x8a, 0xda, 0xea, 0x7a, 0x4a, 0x1a, 0x2a, + 0x4e, 0x7e, 0x2e, 0x1e, 0x8e, 0xbe, 0xee, 0xde, 0xd3, 0xe3, + 0xb3, 0x83, 0x13, 0x23, 0x73, 0x43, 0x69, 0x59, 0x09, 0x39, + 0xa9, 0x99, 0xc9, 0xf9, 0xf4, 0xc4, 0x94, 0xa4, 0x34, 0x04, + 0x54, 0x64, 0x9c, 0xac, 0xfc, 0xcc, 0x5c, 0x6c, 0x3c, 0x0c, + 0x01, 0x31, 0x61, 0x51, 0xc1, 0xf1, 0xa1, 0x91, 0xbb, 0x8b, + 0xdb, 0xeb, 0x7b, 0x4b, 0x1b, 0x2b, 0x26, 0x16, 0x46, 0x76, + 0xe6, 0xd6, 0x86, 0xb6, 0xd2, 0xe2, 0xb2, 0x82, 0x12, 0x22, + 0x72, 0x42, 0x4f, 0x7f, 0x2f, 0x1f, 0x8f, 0xbf, 0xef, 0xdf, + 0xf5, 0xc5, 0x95, 0xa5, 0x35, 0x05, 0x55, 0x65, 0x68, 0x58, + 0x08, 0x38, 0xa8, 0x98, 0xc8, 0xf8, 0x25, 0x15, 0x45, 0x75, + 0xe5, 0xd5, 0x85, 0xb5, 0xb8, 0x88, 0xd8, 0xe8, 0x78, 0x48, + 0x18, 0x28, 0x02, 0x32, 0x62, 0x52, 0xc2, 0xf2, 0xa2, 0x92, + 0x9f, 0xaf, 0xff, 0xcf, 0x5f, 0x6f, 0x3f, 0x0f, 0x6b, 0x5b, + 0x0b, 0x3b, 0xab, 0x9b, 0xcb, 0xfb, 0xf6, 0xc6, 0x96, 0xa6, + 0x36, 0x06, 0x56, 0x66, 0x4c, 0x7c, 0x2c, 0x1c, 0x8c, 0xbc, + 0xec, 0xdc, 0xd1, 0xe1, 0xb1, 0x81, 0x11, 0x21, 0x71, 0x41, + 0xb9, 0x89, 0xd9, 0xe9, 0x79, 0x49, 0x19, 0x29, 0x24, 0x14, + 0x44, 0x74, 0xe4, 0xd4, 0x84, 0xb4, 0x9e, 0xae, 0xfe, 0xce, + 0x5e, 0x6e, 0x3e, 0x0e, 0x03, 0x33, 0x63, 0x53, 0xc3, 0xf3, + 0xa3, 0x93, 0xf7, 0xc7, 0x97, 0xa7, 0x37, 0x07, 0x57, 0x67, + 0x6a, 0x5a, 0x0a, 0x3a, 0xaa, 0x9a, 0xca, 0xfa, 0xd0, 0xe0, + 0xb0, 0x80, 0x10, 0x20, 0x70, 0x40, 0x4d, 0x7d, 0x2d, 0x1d, + 0x8d, 0xbd, 0xed, 0xdd, 0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, + 0xa6, 0x97, 0x95, 0xa4, 0xf7, 0xc6, 0x51, 0x60, 0x33, 0x02, + 0x37, 0x06, 0x55, 0x64, 0xf3, 0xc2, 0x91, 0xa0, 0xa2, 0x93, + 0xc0, 0xf1, 0x66, 0x57, 0x04, 0x35, 0x6e, 0x5f, 0x0c, 0x3d, + 0xaa, 0x9b, 0xc8, 0xf9, 0xfb, 0xca, 0x99, 0xa8, 0x3f, 0x0e, + 0x5d, 0x6c, 0x59, 0x68, 0x3b, 0x0a, 0x9d, 0xac, 0xff, 0xce, + 0xcc, 0xfd, 0xae, 0x9f, 0x08, 0x39, 0x6a, 0x5b, 0xdc, 0xed, + 0xbe, 0x8f, 0x18, 0x29, 0x7a, 0x4b, 0x49, 0x78, 0x2b, 0x1a, + 0x8d, 0xbc, 0xef, 0xde, 0xeb, 0xda, 0x89, 0xb8, 0x2f, 0x1e, + 0x4d, 0x7c, 0x7e, 0x4f, 0x1c, 0x2d, 0xba, 0x8b, 0xd8, 0xe9, + 0xb2, 0x83, 0xd0, 0xe1, 0x76, 0x47, 0x14, 0x25, 0x27, 0x16, + 0x45, 0x74, 0xe3, 0xd2, 0x81, 0xb0, 0x85, 0xb4, 0xe7, 0xd6, + 0x41, 0x70, 0x23, 0x12, 0x10, 0x21, 0x72, 0x43, 0xd4, 0xe5, + 0xb6, 0x87, 0xa5, 0x94, 0xc7, 0xf6, 0x61, 0x50, 0x03, 0x32, + 0x30, 0x01, 0x52, 0x63, 0xf4, 0xc5, 0x96, 0xa7, 0x92, 0xa3, + 0xf0, 0xc1, 0x56, 0x67, 0x34, 0x05, 0x07, 0x36, 0x65, 0x54, + 0xc3, 0xf2, 0xa1, 0x90, 0xcb, 0xfa, 0xa9, 0x98, 0x0f, 0x3e, + 0x6d, 0x5c, 0x5e, 0x6f, 0x3c, 0x0d, 0x9a, 0xab, 0xf8, 0xc9, + 0xfc, 0xcd, 0x9e, 0xaf, 0x38, 0x09, 0x5a, 0x6b, 0x69, 0x58, + 0x0b, 0x3a, 0xad, 0x9c, 0xcf, 0xfe, 0x79, 0x48, 0x1b, 0x2a, + 0xbd, 0x8c, 0xdf, 0xee, 0xec, 0xdd, 0x8e, 0xbf, 0x28, 0x19, + 0x4a, 0x7b, 0x4e, 0x7f, 0x2c, 0x1d, 0x8a, 0xbb, 0xe8, 0xd9, + 0xdb, 0xea, 0xb9, 0x88, 0x1f, 0x2e, 0x7d, 0x4c, 0x17, 0x26, + 0x75, 0x44, 0xd3, 0xe2, 0xb1, 0x80, 0x82, 0xb3, 0xe0, 0xd1, + 0x46, 0x77, 0x24, 0x15, 0x20, 0x11, 0x42, 0x73, 0xe4, 0xd5, + 0x86, 0xb7, 0xb5, 0x84, 0xd7, 0xe6, 0x71, 0x40, 0x13, 0x22, + 0x00, 0x32, 0x64, 0x56, 0xc8, 0xfa, 0xac, 0x9e, 0x8d, 0xbf, + 0xe9, 0xdb, 0x45, 0x77, 0x21, 0x13, 0x07, 0x35, 0x63, 0x51, + 0xcf, 0xfd, 0xab, 0x99, 0x8a, 0xb8, 0xee, 0xdc, 0x42, 0x70, + 0x26, 0x14, 0x0e, 0x3c, 0x6a, 0x58, 0xc6, 0xf4, 0xa2, 0x90, + 0x83, 0xb1, 0xe7, 0xd5, 0x4b, 0x79, 0x2f, 0x1d, 0x09, 0x3b, + 0x6d, 0x5f, 0xc1, 0xf3, 0xa5, 0x97, 0x84, 0xb6, 0xe0, 0xd2, + 0x4c, 0x7e, 0x28, 0x1a, 0x1c, 0x2e, 0x78, 0x4a, 0xd4, 0xe6, + 0xb0, 0x82, 0x91, 0xa3, 0xf5, 0xc7, 0x59, 0x6b, 0x3d, 0x0f, + 0x1b, 0x29, 0x7f, 0x4d, 0xd3, 0xe1, 0xb7, 0x85, 0x96, 0xa4, + 0xf2, 0xc0, 0x5e, 0x6c, 0x3a, 0x08, 0x12, 0x20, 0x76, 0x44, + 0xda, 0xe8, 0xbe, 0x8c, 0x9f, 0xad, 0xfb, 0xc9, 0x57, 0x65, + 0x33, 0x01, 0x15, 0x27, 0x71, 0x43, 0xdd, 0xef, 0xb9, 0x8b, + 0x98, 0xaa, 0xfc, 0xce, 0x50, 0x62, 0x34, 0x06, 0x38, 0x0a, + 0x5c, 0x6e, 0xf0, 0xc2, 0x94, 0xa6, 0xb5, 0x87, 0xd1, 0xe3, + 0x7d, 0x4f, 0x19, 0x2b, 0x3f, 0x0d, 0x5b, 0x69, 0xf7, 0xc5, + 0x93, 0xa1, 0xb2, 0x80, 0xd6, 0xe4, 0x7a, 0x48, 0x1e, 0x2c, + 0x36, 0x04, 0x52, 0x60, 0xfe, 0xcc, 0x9a, 0xa8, 0xbb, 0x89, + 0xdf, 0xed, 0x73, 0x41, 0x17, 0x25, 0x31, 0x03, 0x55, 0x67, + 0xf9, 0xcb, 0x9d, 0xaf, 0xbc, 0x8e, 0xd8, 0xea, 0x74, 0x46, + 0x10, 0x22, 0x24, 0x16, 0x40, 0x72, 0xec, 0xde, 0x88, 0xba, + 0xa9, 0x9b, 0xcd, 0xff, 0x61, 0x53, 0x05, 0x37, 0x23, 0x11, + 0x47, 0x75, 0xeb, 0xd9, 0x8f, 0xbd, 0xae, 0x9c, 0xca, 0xf8, + 0x66, 0x54, 0x02, 0x30, 0x2a, 0x18, 0x4e, 0x7c, 0xe2, 0xd0, + 0x86, 0xb4, 0xa7, 0x95, 0xc3, 0xf1, 0x6f, 0x5d, 0x0b, 0x39, + 0x2d, 0x1f, 0x49, 0x7b, 0xe5, 0xd7, 0x81, 0xb3, 0xa0, 0x92, + 0xc4, 0xf6, 0x68, 0x5a, 0x0c, 0x3e, 0x00, 0x33, 0x66, 0x55, + 0xcc, 0xff, 0xaa, 0x99, 0x85, 0xb6, 0xe3, 0xd0, 0x49, 0x7a, + 0x2f, 0x1c, 0x17, 0x24, 0x71, 0x42, 0xdb, 0xe8, 0xbd, 0x8e, + 0x92, 0xa1, 0xf4, 0xc7, 0x5e, 0x6d, 0x38, 0x0b, 0x2e, 0x1d, + 0x48, 0x7b, 0xe2, 0xd1, 0x84, 0xb7, 0xab, 0x98, 0xcd, 0xfe, + 0x67, 0x54, 0x01, 0x32, 0x39, 0x0a, 0x5f, 0x6c, 0xf5, 0xc6, + 0x93, 0xa0, 0xbc, 0x8f, 0xda, 0xe9, 0x70, 0x43, 0x16, 0x25, + 0x5c, 0x6f, 0x3a, 0x09, 0x90, 0xa3, 0xf6, 0xc5, 0xd9, 0xea, + 0xbf, 0x8c, 0x15, 0x26, 0x73, 0x40, 0x4b, 0x78, 0x2d, 0x1e, + 0x87, 0xb4, 0xe1, 0xd2, 0xce, 0xfd, 0xa8, 0x9b, 0x02, 0x31, + 0x64, 0x57, 0x72, 0x41, 0x14, 0x27, 0xbe, 0x8d, 0xd8, 0xeb, + 0xf7, 0xc4, 0x91, 0xa2, 0x3b, 0x08, 0x5d, 0x6e, 0x65, 0x56, + 0x03, 0x30, 0xa9, 0x9a, 0xcf, 0xfc, 0xe0, 0xd3, 0x86, 0xb5, + 0x2c, 0x1f, 0x4a, 0x79, 0xb8, 0x8b, 0xde, 0xed, 0x74, 0x47, + 0x12, 0x21, 0x3d, 0x0e, 0x5b, 0x68, 0xf1, 0xc2, 0x97, 0xa4, + 0xaf, 0x9c, 0xc9, 0xfa, 0x63, 0x50, 0x05, 0x36, 0x2a, 0x19, + 0x4c, 0x7f, 0xe6, 0xd5, 0x80, 0xb3, 0x96, 0xa5, 0xf0, 0xc3, + 0x5a, 0x69, 0x3c, 0x0f, 0x13, 0x20, 0x75, 0x46, 0xdf, 0xec, + 0xb9, 0x8a, 0x81, 0xb2, 0xe7, 0xd4, 0x4d, 0x7e, 0x2b, 0x18, + 0x04, 0x37, 0x62, 0x51, 0xc8, 0xfb, 0xae, 0x9d, 0xe4, 0xd7, + 0x82, 0xb1, 0x28, 0x1b, 0x4e, 0x7d, 0x61, 0x52, 0x07, 0x34, + 0xad, 0x9e, 0xcb, 0xf8, 0xf3, 0xc0, 0x95, 0xa6, 0x3f, 0x0c, + 0x59, 0x6a, 0x76, 0x45, 0x10, 0x23, 0xba, 0x89, 0xdc, 0xef, + 0xca, 0xf9, 0xac, 0x9f, 0x06, 0x35, 0x60, 0x53, 0x4f, 0x7c, + 0x29, 0x1a, 0x83, 0xb0, 0xe5, 0xd6, 0xdd, 0xee, 0xbb, 0x88, + 0x11, 0x22, 0x77, 0x44, 0x58, 0x6b, 0x3e, 0x0d, 0x94, 0xa7, + 0xf2, 0xc1, 0x00, 0x34, 0x68, 0x5c, 0xd0, 0xe4, 0xb8, 0x8c, + 0xbd, 0x89, 0xd5, 0xe1, 0x6d, 0x59, 0x05, 0x31, 0x67, 0x53, + 0x0f, 0x3b, 0xb7, 0x83, 0xdf, 0xeb, 0xda, 0xee, 0xb2, 0x86, + 0x0a, 0x3e, 0x62, 0x56, 0xce, 0xfa, 0xa6, 0x92, 0x1e, 0x2a, + 0x76, 0x42, 0x73, 0x47, 0x1b, 0x2f, 0xa3, 0x97, 0xcb, 0xff, + 0xa9, 0x9d, 0xc1, 0xf5, 0x79, 0x4d, 0x11, 0x25, 0x14, 0x20, + 0x7c, 0x48, 0xc4, 0xf0, 0xac, 0x98, 0x81, 0xb5, 0xe9, 0xdd, + 0x51, 0x65, 0x39, 0x0d, 0x3c, 0x08, 0x54, 0x60, 0xec, 0xd8, + 0x84, 0xb0, 0xe6, 0xd2, 0x8e, 0xba, 0x36, 0x02, 0x5e, 0x6a, + 0x5b, 0x6f, 0x33, 0x07, 0x8b, 0xbf, 0xe3, 0xd7, 0x4f, 0x7b, + 0x27, 0x13, 0x9f, 0xab, 0xf7, 0xc3, 0xf2, 0xc6, 0x9a, 0xae, + 0x22, 0x16, 0x4a, 0x7e, 0x28, 0x1c, 0x40, 0x74, 0xf8, 0xcc, + 0x90, 0xa4, 0x95, 0xa1, 0xfd, 0xc9, 0x45, 0x71, 0x2d, 0x19, + 0x1f, 0x2b, 0x77, 0x43, 0xcf, 0xfb, 0xa7, 0x93, 0xa2, 0x96, + 0xca, 0xfe, 0x72, 0x46, 0x1a, 0x2e, 0x78, 0x4c, 0x10, 0x24, + 0xa8, 0x9c, 0xc0, 0xf4, 0xc5, 0xf1, 0xad, 0x99, 0x15, 0x21, + 0x7d, 0x49, 0xd1, 0xe5, 0xb9, 0x8d, 0x01, 0x35, 0x69, 0x5d, + 0x6c, 0x58, 0x04, 0x30, 0xbc, 0x88, 0xd4, 0xe0, 0xb6, 0x82, + 0xde, 0xea, 0x66, 0x52, 0x0e, 0x3a, 0x0b, 0x3f, 0x63, 0x57, + 0xdb, 0xef, 0xb3, 0x87, 0x9e, 0xaa, 0xf6, 0xc2, 0x4e, 0x7a, + 0x26, 0x12, 0x23, 0x17, 0x4b, 0x7f, 0xf3, 0xc7, 0x9b, 0xaf, + 0xf9, 0xcd, 0x91, 0xa5, 0x29, 0x1d, 0x41, 0x75, 0x44, 0x70, + 0x2c, 0x18, 0x94, 0xa0, 0xfc, 0xc8, 0x50, 0x64, 0x38, 0x0c, + 0x80, 0xb4, 0xe8, 0xdc, 0xed, 0xd9, 0x85, 0xb1, 0x3d, 0x09, + 0x55, 0x61, 0x37, 0x03, 0x5f, 0x6b, 0xe7, 0xd3, 0x8f, 0xbb, + 0x8a, 0xbe, 0xe2, 0xd6, 0x5a, 0x6e, 0x32, 0x06, 0x00, 0x35, + 0x6a, 0x5f, 0xd4, 0xe1, 0xbe, 0x8b, 0xb5, 0x80, 0xdf, 0xea, + 0x61, 0x54, 0x0b, 0x3e, 0x77, 0x42, 0x1d, 0x28, 0xa3, 0x96, + 0xc9, 0xfc, 0xc2, 0xf7, 0xa8, 0x9d, 0x16, 0x23, 0x7c, 0x49, + 0xee, 0xdb, 0x84, 0xb1, 0x3a, 0x0f, 0x50, 0x65, 0x5b, 0x6e, + 0x31, 0x04, 0x8f, 0xba, 0xe5, 0xd0, 0x99, 0xac, 0xf3, 0xc6, + 0x4d, 0x78, 0x27, 0x12, 0x2c, 0x19, 0x46, 0x73, 0xf8, 0xcd, + 0x92, 0xa7, 0xc1, 0xf4, 0xab, 0x9e, 0x15, 0x20, 0x7f, 0x4a, + 0x74, 0x41, 0x1e, 0x2b, 0xa0, 0x95, 0xca, 0xff, 0xb6, 0x83, + 0xdc, 0xe9, 0x62, 0x57, 0x08, 0x3d, 0x03, 0x36, 0x69, 0x5c, + 0xd7, 0xe2, 0xbd, 0x88, 0x2f, 0x1a, 0x45, 0x70, 0xfb, 0xce, + 0x91, 0xa4, 0x9a, 0xaf, 0xf0, 0xc5, 0x4e, 0x7b, 0x24, 0x11, + 0x58, 0x6d, 0x32, 0x07, 0x8c, 0xb9, 0xe6, 0xd3, 0xed, 0xd8, + 0x87, 0xb2, 0x39, 0x0c, 0x53, 0x66, 0x9f, 0xaa, 0xf5, 0xc0, + 0x4b, 0x7e, 0x21, 0x14, 0x2a, 0x1f, 0x40, 0x75, 0xfe, 0xcb, + 0x94, 0xa1, 0xe8, 0xdd, 0x82, 0xb7, 0x3c, 0x09, 0x56, 0x63, + 0x5d, 0x68, 0x37, 0x02, 0x89, 0xbc, 0xe3, 0xd6, 0x71, 0x44, + 0x1b, 0x2e, 0xa5, 0x90, 0xcf, 0xfa, 0xc4, 0xf1, 0xae, 0x9b, + 0x10, 0x25, 0x7a, 0x4f, 0x06, 0x33, 0x6c, 0x59, 0xd2, 0xe7, + 0xb8, 0x8d, 0xb3, 0x86, 0xd9, 0xec, 0x67, 0x52, 0x0d, 0x38, + 0x5e, 0x6b, 0x34, 0x01, 0x8a, 0xbf, 0xe0, 0xd5, 0xeb, 0xde, + 0x81, 0xb4, 0x3f, 0x0a, 0x55, 0x60, 0x29, 0x1c, 0x43, 0x76, + 0xfd, 0xc8, 0x97, 0xa2, 0x9c, 0xa9, 0xf6, 0xc3, 0x48, 0x7d, + 0x22, 0x17, 0xb0, 0x85, 0xda, 0xef, 0x64, 0x51, 0x0e, 0x3b, + 0x05, 0x30, 0x6f, 0x5a, 0xd1, 0xe4, 0xbb, 0x8e, 0xc7, 0xf2, + 0xad, 0x98, 0x13, 0x26, 0x79, 0x4c, 0x72, 0x47, 0x18, 0x2d, + 0xa6, 0x93, 0xcc, 0xf9, 0x00, 0x36, 0x6c, 0x5a, 0xd8, 0xee, + 0xb4, 0x82, 0xad, 0x9b, 0xc1, 0xf7, 0x75, 0x43, 0x19, 0x2f, + 0x47, 0x71, 0x2b, 0x1d, 0x9f, 0xa9, 0xf3, 0xc5, 0xea, 0xdc, + 0x86, 0xb0, 0x32, 0x04, 0x5e, 0x68, 0x8e, 0xb8, 0xe2, 0xd4, + 0x56, 0x60, 0x3a, 0x0c, 0x23, 0x15, 0x4f, 0x79, 0xfb, 0xcd, + 0x97, 0xa1, 0xc9, 0xff, 0xa5, 0x93, 0x11, 0x27, 0x7d, 0x4b, + 0x64, 0x52, 0x08, 0x3e, 0xbc, 0x8a, 0xd0, 0xe6, 0x01, 0x37, + 0x6d, 0x5b, 0xd9, 0xef, 0xb5, 0x83, 0xac, 0x9a, 0xc0, 0xf6, + 0x74, 0x42, 0x18, 0x2e, 0x46, 0x70, 0x2a, 0x1c, 0x9e, 0xa8, + 0xf2, 0xc4, 0xeb, 0xdd, 0x87, 0xb1, 0x33, 0x05, 0x5f, 0x69, + 0x8f, 0xb9, 0xe3, 0xd5, 0x57, 0x61, 0x3b, 0x0d, 0x22, 0x14, + 0x4e, 0x78, 0xfa, 0xcc, 0x96, 0xa0, 0xc8, 0xfe, 0xa4, 0x92, + 0x10, 0x26, 0x7c, 0x4a, 0x65, 0x53, 0x09, 0x3f, 0xbd, 0x8b, + 0xd1, 0xe7, 0x02, 0x34, 0x6e, 0x58, 0xda, 0xec, 0xb6, 0x80, + 0xaf, 0x99, 0xc3, 0xf5, 0x77, 0x41, 0x1b, 0x2d, 0x45, 0x73, + 0x29, 0x1f, 0x9d, 0xab, 0xf1, 0xc7, 0xe8, 0xde, 0x84, 0xb2, + 0x30, 0x06, 0x5c, 0x6a, 0x8c, 0xba, 0xe0, 0xd6, 0x54, 0x62, + 0x38, 0x0e, 0x21, 0x17, 0x4d, 0x7b, 0xf9, 0xcf, 0x95, 0xa3, + 0xcb, 0xfd, 0xa7, 0x91, 0x13, 0x25, 0x7f, 0x49, 0x66, 0x50, + 0x0a, 0x3c, 0xbe, 0x88, 0xd2, 0xe4, 0x03, 0x35, 0x6f, 0x59, + 0xdb, 0xed, 0xb7, 0x81, 0xae, 0x98, 0xc2, 0xf4, 0x76, 0x40, + 0x1a, 0x2c, 0x44, 0x72, 0x28, 0x1e, 0x9c, 0xaa, 0xf0, 0xc6, + 0xe9, 0xdf, 0x85, 0xb3, 0x31, 0x07, 0x5d, 0x6b, 0x8d, 0xbb, + 0xe1, 0xd7, 0x55, 0x63, 0x39, 0x0f, 0x20, 0x16, 0x4c, 0x7a, + 0xf8, 0xce, 0x94, 0xa2, 0xca, 0xfc, 0xa6, 0x90, 0x12, 0x24, + 0x7e, 0x48, 0x67, 0x51, 0x0b, 0x3d, 0xbf, 0x89, 0xd3, 0xe5, + 0x00, 0x37, 0x6e, 0x59, 0xdc, 0xeb, 0xb2, 0x85, 0xa5, 0x92, + 0xcb, 0xfc, 0x79, 0x4e, 0x17, 0x20, 0x57, 0x60, 0x39, 0x0e, + 0x8b, 0xbc, 0xe5, 0xd2, 0xf2, 0xc5, 0x9c, 0xab, 0x2e, 0x19, + 0x40, 0x77, 0xae, 0x99, 0xc0, 0xf7, 0x72, 0x45, 0x1c, 0x2b, + 0x0b, 0x3c, 0x65, 0x52, 0xd7, 0xe0, 0xb9, 0x8e, 0xf9, 0xce, + 0x97, 0xa0, 0x25, 0x12, 0x4b, 0x7c, 0x5c, 0x6b, 0x32, 0x05, + 0x80, 0xb7, 0xee, 0xd9, 0x41, 0x76, 0x2f, 0x18, 0x9d, 0xaa, + 0xf3, 0xc4, 0xe4, 0xd3, 0x8a, 0xbd, 0x38, 0x0f, 0x56, 0x61, + 0x16, 0x21, 0x78, 0x4f, 0xca, 0xfd, 0xa4, 0x93, 0xb3, 0x84, + 0xdd, 0xea, 0x6f, 0x58, 0x01, 0x36, 0xef, 0xd8, 0x81, 0xb6, + 0x33, 0x04, 0x5d, 0x6a, 0x4a, 0x7d, 0x24, 0x13, 0x96, 0xa1, + 0xf8, 0xcf, 0xb8, 0x8f, 0xd6, 0xe1, 0x64, 0x53, 0x0a, 0x3d, + 0x1d, 0x2a, 0x73, 0x44, 0xc1, 0xf6, 0xaf, 0x98, 0x82, 0xb5, + 0xec, 0xdb, 0x5e, 0x69, 0x30, 0x07, 0x27, 0x10, 0x49, 0x7e, + 0xfb, 0xcc, 0x95, 0xa2, 0xd5, 0xe2, 0xbb, 0x8c, 0x09, 0x3e, + 0x67, 0x50, 0x70, 0x47, 0x1e, 0x29, 0xac, 0x9b, 0xc2, 0xf5, + 0x2c, 0x1b, 0x42, 0x75, 0xf0, 0xc7, 0x9e, 0xa9, 0x89, 0xbe, + 0xe7, 0xd0, 0x55, 0x62, 0x3b, 0x0c, 0x7b, 0x4c, 0x15, 0x22, + 0xa7, 0x90, 0xc9, 0xfe, 0xde, 0xe9, 0xb0, 0x87, 0x02, 0x35, + 0x6c, 0x5b, 0xc3, 0xf4, 0xad, 0x9a, 0x1f, 0x28, 0x71, 0x46, + 0x66, 0x51, 0x08, 0x3f, 0xba, 0x8d, 0xd4, 0xe3, 0x94, 0xa3, + 0xfa, 0xcd, 0x48, 0x7f, 0x26, 0x11, 0x31, 0x06, 0x5f, 0x68, + 0xed, 0xda, 0x83, 0xb4, 0x6d, 0x5a, 0x03, 0x34, 0xb1, 0x86, + 0xdf, 0xe8, 0xc8, 0xff, 0xa6, 0x91, 0x14, 0x23, 0x7a, 0x4d, + 0x3a, 0x0d, 0x54, 0x63, 0xe6, 0xd1, 0x88, 0xbf, 0x9f, 0xa8, + 0xf1, 0xc6, 0x43, 0x74, 0x2d, 0x1a, 0x00, 0x38, 0x70, 0x48, + 0xe0, 0xd8, 0x90, 0xa8, 0xdd, 0xe5, 0xad, 0x95, 0x3d, 0x05, + 0x4d, 0x75, 0xa7, 0x9f, 0xd7, 0xef, 0x47, 0x7f, 0x37, 0x0f, + 0x7a, 0x42, 0x0a, 0x32, 0x9a, 0xa2, 0xea, 0xd2, 0x53, 0x6b, + 0x23, 0x1b, 0xb3, 0x8b, 0xc3, 0xfb, 0x8e, 0xb6, 0xfe, 0xc6, + 0x6e, 0x56, 0x1e, 0x26, 0xf4, 0xcc, 0x84, 0xbc, 0x14, 0x2c, + 0x64, 0x5c, 0x29, 0x11, 0x59, 0x61, 0xc9, 0xf1, 0xb9, 0x81, + 0xa6, 0x9e, 0xd6, 0xee, 0x46, 0x7e, 0x36, 0x0e, 0x7b, 0x43, + 0x0b, 0x33, 0x9b, 0xa3, 0xeb, 0xd3, 0x01, 0x39, 0x71, 0x49, + 0xe1, 0xd9, 0x91, 0xa9, 0xdc, 0xe4, 0xac, 0x94, 0x3c, 0x04, + 0x4c, 0x74, 0xf5, 0xcd, 0x85, 0xbd, 0x15, 0x2d, 0x65, 0x5d, + 0x28, 0x10, 0x58, 0x60, 0xc8, 0xf0, 0xb8, 0x80, 0x52, 0x6a, + 0x22, 0x1a, 0xb2, 0x8a, 0xc2, 0xfa, 0x8f, 0xb7, 0xff, 0xc7, + 0x6f, 0x57, 0x1f, 0x27, 0x51, 0x69, 0x21, 0x19, 0xb1, 0x89, + 0xc1, 0xf9, 0x8c, 0xb4, 0xfc, 0xc4, 0x6c, 0x54, 0x1c, 0x24, + 0xf6, 0xce, 0x86, 0xbe, 0x16, 0x2e, 0x66, 0x5e, 0x2b, 0x13, + 0x5b, 0x63, 0xcb, 0xf3, 0xbb, 0x83, 0x02, 0x3a, 0x72, 0x4a, + 0xe2, 0xda, 0x92, 0xaa, 0xdf, 0xe7, 0xaf, 0x97, 0x3f, 0x07, + 0x4f, 0x77, 0xa5, 0x9d, 0xd5, 0xed, 0x45, 0x7d, 0x35, 0x0d, + 0x78, 0x40, 0x08, 0x30, 0x98, 0xa0, 0xe8, 0xd0, 0xf7, 0xcf, + 0x87, 0xbf, 0x17, 0x2f, 0x67, 0x5f, 0x2a, 0x12, 0x5a, 0x62, + 0xca, 0xf2, 0xba, 0x82, 0x50, 0x68, 0x20, 0x18, 0xb0, 0x88, + 0xc0, 0xf8, 0x8d, 0xb5, 0xfd, 0xc5, 0x6d, 0x55, 0x1d, 0x25, + 0xa4, 0x9c, 0xd4, 0xec, 0x44, 0x7c, 0x34, 0x0c, 0x79, 0x41, + 0x09, 0x31, 0x99, 0xa1, 0xe9, 0xd1, 0x03, 0x3b, 0x73, 0x4b, + 0xe3, 0xdb, 0x93, 0xab, 0xde, 0xe6, 0xae, 0x96, 0x3e, 0x06, + 0x4e, 0x76, 0x00, 0x39, 0x72, 0x4b, 0xe4, 0xdd, 0x96, 0xaf, + 0xd5, 0xec, 0xa7, 0x9e, 0x31, 0x08, 0x43, 0x7a, 0xb7, 0x8e, + 0xc5, 0xfc, 0x53, 0x6a, 0x21, 0x18, 0x62, 0x5b, 0x10, 0x29, + 0x86, 0xbf, 0xf4, 0xcd, 0x73, 0x4a, 0x01, 0x38, 0x97, 0xae, + 0xe5, 0xdc, 0xa6, 0x9f, 0xd4, 0xed, 0x42, 0x7b, 0x30, 0x09, + 0xc4, 0xfd, 0xb6, 0x8f, 0x20, 0x19, 0x52, 0x6b, 0x11, 0x28, + 0x63, 0x5a, 0xf5, 0xcc, 0x87, 0xbe, 0xe6, 0xdf, 0x94, 0xad, + 0x02, 0x3b, 0x70, 0x49, 0x33, 0x0a, 0x41, 0x78, 0xd7, 0xee, + 0xa5, 0x9c, 0x51, 0x68, 0x23, 0x1a, 0xb5, 0x8c, 0xc7, 0xfe, + 0x84, 0xbd, 0xf6, 0xcf, 0x60, 0x59, 0x12, 0x2b, 0x95, 0xac, + 0xe7, 0xde, 0x71, 0x48, 0x03, 0x3a, 0x40, 0x79, 0x32, 0x0b, + 0xa4, 0x9d, 0xd6, 0xef, 0x22, 0x1b, 0x50, 0x69, 0xc6, 0xff, + 0xb4, 0x8d, 0xf7, 0xce, 0x85, 0xbc, 0x13, 0x2a, 0x61, 0x58, + 0xd1, 0xe8, 0xa3, 0x9a, 0x35, 0x0c, 0x47, 0x7e, 0x04, 0x3d, + 0x76, 0x4f, 0xe0, 0xd9, 0x92, 0xab, 0x66, 0x5f, 0x14, 0x2d, + 0x82, 0xbb, 0xf0, 0xc9, 0xb3, 0x8a, 0xc1, 0xf8, 0x57, 0x6e, + 0x25, 0x1c, 0xa2, 0x9b, 0xd0, 0xe9, 0x46, 0x7f, 0x34, 0x0d, + 0x77, 0x4e, 0x05, 0x3c, 0x93, 0xaa, 0xe1, 0xd8, 0x15, 0x2c, + 0x67, 0x5e, 0xf1, 0xc8, 0x83, 0xba, 0xc0, 0xf9, 0xb2, 0x8b, + 0x24, 0x1d, 0x56, 0x6f, 0x37, 0x0e, 0x45, 0x7c, 0xd3, 0xea, + 0xa1, 0x98, 0xe2, 0xdb, 0x90, 0xa9, 0x06, 0x3f, 0x74, 0x4d, + 0x80, 0xb9, 0xf2, 0xcb, 0x64, 0x5d, 0x16, 0x2f, 0x55, 0x6c, + 0x27, 0x1e, 0xb1, 0x88, 0xc3, 0xfa, 0x44, 0x7d, 0x36, 0x0f, + 0xa0, 0x99, 0xd2, 0xeb, 0x91, 0xa8, 0xe3, 0xda, 0x75, 0x4c, + 0x07, 0x3e, 0xf3, 0xca, 0x81, 0xb8, 0x17, 0x2e, 0x65, 0x5c, + 0x26, 0x1f, 0x54, 0x6d, 0xc2, 0xfb, 0xb0, 0x89, 0x00, 0x3a, + 0x74, 0x4e, 0xe8, 0xd2, 0x9c, 0xa6, 0xcd, 0xf7, 0xb9, 0x83, + 0x25, 0x1f, 0x51, 0x6b, 0x87, 0xbd, 0xf3, 0xc9, 0x6f, 0x55, + 0x1b, 0x21, 0x4a, 0x70, 0x3e, 0x04, 0xa2, 0x98, 0xd6, 0xec, + 0x13, 0x29, 0x67, 0x5d, 0xfb, 0xc1, 0x8f, 0xb5, 0xde, 0xe4, + 0xaa, 0x90, 0x36, 0x0c, 0x42, 0x78, 0x94, 0xae, 0xe0, 0xda, + 0x7c, 0x46, 0x08, 0x32, 0x59, 0x63, 0x2d, 0x17, 0xb1, 0x8b, + 0xc5, 0xff, 0x26, 0x1c, 0x52, 0x68, 0xce, 0xf4, 0xba, 0x80, + 0xeb, 0xd1, 0x9f, 0xa5, 0x03, 0x39, 0x77, 0x4d, 0xa1, 0x9b, + 0xd5, 0xef, 0x49, 0x73, 0x3d, 0x07, 0x6c, 0x56, 0x18, 0x22, + 0x84, 0xbe, 0xf0, 0xca, 0x35, 0x0f, 0x41, 0x7b, 0xdd, 0xe7, + 0xa9, 0x93, 0xf8, 0xc2, 0x8c, 0xb6, 0x10, 0x2a, 0x64, 0x5e, + 0xb2, 0x88, 0xc6, 0xfc, 0x5a, 0x60, 0x2e, 0x14, 0x7f, 0x45, + 0x0b, 0x31, 0x97, 0xad, 0xe3, 0xd9, 0x4c, 0x76, 0x38, 0x02, + 0xa4, 0x9e, 0xd0, 0xea, 0x81, 0xbb, 0xf5, 0xcf, 0x69, 0x53, + 0x1d, 0x27, 0xcb, 0xf1, 0xbf, 0x85, 0x23, 0x19, 0x57, 0x6d, + 0x06, 0x3c, 0x72, 0x48, 0xee, 0xd4, 0x9a, 0xa0, 0x5f, 0x65, + 0x2b, 0x11, 0xb7, 0x8d, 0xc3, 0xf9, 0x92, 0xa8, 0xe6, 0xdc, + 0x7a, 0x40, 0x0e, 0x34, 0xd8, 0xe2, 0xac, 0x96, 0x30, 0x0a, + 0x44, 0x7e, 0x15, 0x2f, 0x61, 0x5b, 0xfd, 0xc7, 0x89, 0xb3, + 0x6a, 0x50, 0x1e, 0x24, 0x82, 0xb8, 0xf6, 0xcc, 0xa7, 0x9d, + 0xd3, 0xe9, 0x4f, 0x75, 0x3b, 0x01, 0xed, 0xd7, 0x99, 0xa3, + 0x05, 0x3f, 0x71, 0x4b, 0x20, 0x1a, 0x54, 0x6e, 0xc8, 0xf2, + 0xbc, 0x86, 0x79, 0x43, 0x0d, 0x37, 0x91, 0xab, 0xe5, 0xdf, + 0xb4, 0x8e, 0xc0, 0xfa, 0x5c, 0x66, 0x28, 0x12, 0xfe, 0xc4, + 0x8a, 0xb0, 0x16, 0x2c, 0x62, 0x58, 0x33, 0x09, 0x47, 0x7d, + 0xdb, 0xe1, 0xaf, 0x95, 0x00, 0x3b, 0x76, 0x4d, 0xec, 0xd7, + 0x9a, 0xa1, 0xc5, 0xfe, 0xb3, 0x88, 0x29, 0x12, 0x5f, 0x64, + 0x97, 0xac, 0xe1, 0xda, 0x7b, 0x40, 0x0d, 0x36, 0x52, 0x69, + 0x24, 0x1f, 0xbe, 0x85, 0xc8, 0xf3, 0x33, 0x08, 0x45, 0x7e, + 0xdf, 0xe4, 0xa9, 0x92, 0xf6, 0xcd, 0x80, 0xbb, 0x1a, 0x21, + 0x6c, 0x57, 0xa4, 0x9f, 0xd2, 0xe9, 0x48, 0x73, 0x3e, 0x05, + 0x61, 0x5a, 0x17, 0x2c, 0x8d, 0xb6, 0xfb, 0xc0, 0x66, 0x5d, + 0x10, 0x2b, 0x8a, 0xb1, 0xfc, 0xc7, 0xa3, 0x98, 0xd5, 0xee, + 0x4f, 0x74, 0x39, 0x02, 0xf1, 0xca, 0x87, 0xbc, 0x1d, 0x26, + 0x6b, 0x50, 0x34, 0x0f, 0x42, 0x79, 0xd8, 0xe3, 0xae, 0x95, + 0x55, 0x6e, 0x23, 0x18, 0xb9, 0x82, 0xcf, 0xf4, 0x90, 0xab, + 0xe6, 0xdd, 0x7c, 0x47, 0x0a, 0x31, 0xc2, 0xf9, 0xb4, 0x8f, + 0x2e, 0x15, 0x58, 0x63, 0x07, 0x3c, 0x71, 0x4a, 0xeb, 0xd0, + 0x9d, 0xa6, 0xcc, 0xf7, 0xba, 0x81, 0x20, 0x1b, 0x56, 0x6d, + 0x09, 0x32, 0x7f, 0x44, 0xe5, 0xde, 0x93, 0xa8, 0x5b, 0x60, + 0x2d, 0x16, 0xb7, 0x8c, 0xc1, 0xfa, 0x9e, 0xa5, 0xe8, 0xd3, + 0x72, 0x49, 0x04, 0x3f, 0xff, 0xc4, 0x89, 0xb2, 0x13, 0x28, + 0x65, 0x5e, 0x3a, 0x01, 0x4c, 0x77, 0xd6, 0xed, 0xa0, 0x9b, + 0x68, 0x53, 0x1e, 0x25, 0x84, 0xbf, 0xf2, 0xc9, 0xad, 0x96, + 0xdb, 0xe0, 0x41, 0x7a, 0x37, 0x0c, 0xaa, 0x91, 0xdc, 0xe7, + 0x46, 0x7d, 0x30, 0x0b, 0x6f, 0x54, 0x19, 0x22, 0x83, 0xb8, + 0xf5, 0xce, 0x3d, 0x06, 0x4b, 0x70, 0xd1, 0xea, 0xa7, 0x9c, + 0xf8, 0xc3, 0x8e, 0xb5, 0x14, 0x2f, 0x62, 0x59, 0x99, 0xa2, + 0xef, 0xd4, 0x75, 0x4e, 0x03, 0x38, 0x5c, 0x67, 0x2a, 0x11, + 0xb0, 0x8b, 0xc6, 0xfd, 0x0e, 0x35, 0x78, 0x43, 0xe2, 0xd9, + 0x94, 0xaf, 0xcb, 0xf0, 0xbd, 0x86, 0x27, 0x1c, 0x51, 0x6a, + 0x00, 0x3c, 0x78, 0x44, 0xf0, 0xcc, 0x88, 0xb4, 0xfd, 0xc1, + 0x85, 0xb9, 0x0d, 0x31, 0x75, 0x49, 0xe7, 0xdb, 0x9f, 0xa3, + 0x17, 0x2b, 0x6f, 0x53, 0x1a, 0x26, 0x62, 0x5e, 0xea, 0xd6, + 0x92, 0xae, 0xd3, 0xef, 0xab, 0x97, 0x23, 0x1f, 0x5b, 0x67, + 0x2e, 0x12, 0x56, 0x6a, 0xde, 0xe2, 0xa6, 0x9a, 0x34, 0x08, + 0x4c, 0x70, 0xc4, 0xf8, 0xbc, 0x80, 0xc9, 0xf5, 0xb1, 0x8d, + 0x39, 0x05, 0x41, 0x7d, 0xbb, 0x87, 0xc3, 0xff, 0x4b, 0x77, + 0x33, 0x0f, 0x46, 0x7a, 0x3e, 0x02, 0xb6, 0x8a, 0xce, 0xf2, + 0x5c, 0x60, 0x24, 0x18, 0xac, 0x90, 0xd4, 0xe8, 0xa1, 0x9d, + 0xd9, 0xe5, 0x51, 0x6d, 0x29, 0x15, 0x68, 0x54, 0x10, 0x2c, + 0x98, 0xa4, 0xe0, 0xdc, 0x95, 0xa9, 0xed, 0xd1, 0x65, 0x59, + 0x1d, 0x21, 0x8f, 0xb3, 0xf7, 0xcb, 0x7f, 0x43, 0x07, 0x3b, + 0x72, 0x4e, 0x0a, 0x36, 0x82, 0xbe, 0xfa, 0xc6, 0x6b, 0x57, + 0x13, 0x2f, 0x9b, 0xa7, 0xe3, 0xdf, 0x96, 0xaa, 0xee, 0xd2, + 0x66, 0x5a, 0x1e, 0x22, 0x8c, 0xb0, 0xf4, 0xc8, 0x7c, 0x40, + 0x04, 0x38, 0x71, 0x4d, 0x09, 0x35, 0x81, 0xbd, 0xf9, 0xc5, + 0xb8, 0x84, 0xc0, 0xfc, 0x48, 0x74, 0x30, 0x0c, 0x45, 0x79, + 0x3d, 0x01, 0xb5, 0x89, 0xcd, 0xf1, 0x5f, 0x63, 0x27, 0x1b, + 0xaf, 0x93, 0xd7, 0xeb, 0xa2, 0x9e, 0xda, 0xe6, 0x52, 0x6e, + 0x2a, 0x16, 0xd0, 0xec, 0xa8, 0x94, 0x20, 0x1c, 0x58, 0x64, + 0x2d, 0x11, 0x55, 0x69, 0xdd, 0xe1, 0xa5, 0x99, 0x37, 0x0b, + 0x4f, 0x73, 0xc7, 0xfb, 0xbf, 0x83, 0xca, 0xf6, 0xb2, 0x8e, + 0x3a, 0x06, 0x42, 0x7e, 0x03, 0x3f, 0x7b, 0x47, 0xf3, 0xcf, + 0x8b, 0xb7, 0xfe, 0xc2, 0x86, 0xba, 0x0e, 0x32, 0x76, 0x4a, + 0xe4, 0xd8, 0x9c, 0xa0, 0x14, 0x28, 0x6c, 0x50, 0x19, 0x25, + 0x61, 0x5d, 0xe9, 0xd5, 0x91, 0xad, 0x00, 0x3d, 0x7a, 0x47, + 0xf4, 0xc9, 0x8e, 0xb3, 0xf5, 0xc8, 0x8f, 0xb2, 0x01, 0x3c, + 0x7b, 0x46, 0xf7, 0xca, 0x8d, 0xb0, 0x03, 0x3e, 0x79, 0x44, + 0x02, 0x3f, 0x78, 0x45, 0xf6, 0xcb, 0x8c, 0xb1, 0xf3, 0xce, + 0x89, 0xb4, 0x07, 0x3a, 0x7d, 0x40, 0x06, 0x3b, 0x7c, 0x41, + 0xf2, 0xcf, 0x88, 0xb5, 0x04, 0x39, 0x7e, 0x43, 0xf0, 0xcd, + 0x8a, 0xb7, 0xf1, 0xcc, 0x8b, 0xb6, 0x05, 0x38, 0x7f, 0x42, + 0xfb, 0xc6, 0x81, 0xbc, 0x0f, 0x32, 0x75, 0x48, 0x0e, 0x33, + 0x74, 0x49, 0xfa, 0xc7, 0x80, 0xbd, 0x0c, 0x31, 0x76, 0x4b, + 0xf8, 0xc5, 0x82, 0xbf, 0xf9, 0xc4, 0x83, 0xbe, 0x0d, 0x30, + 0x77, 0x4a, 0x08, 0x35, 0x72, 0x4f, 0xfc, 0xc1, 0x86, 0xbb, + 0xfd, 0xc0, 0x87, 0xba, 0x09, 0x34, 0x73, 0x4e, 0xff, 0xc2, + 0x85, 0xb8, 0x0b, 0x36, 0x71, 0x4c, 0x0a, 0x37, 0x70, 0x4d, + 0xfe, 0xc3, 0x84, 0xb9, 0xeb, 0xd6, 0x91, 0xac, 0x1f, 0x22, + 0x65, 0x58, 0x1e, 0x23, 0x64, 0x59, 0xea, 0xd7, 0x90, 0xad, + 0x1c, 0x21, 0x66, 0x5b, 0xe8, 0xd5, 0x92, 0xaf, 0xe9, 0xd4, + 0x93, 0xae, 0x1d, 0x20, 0x67, 0x5a, 0x18, 0x25, 0x62, 0x5f, + 0xec, 0xd1, 0x96, 0xab, 0xed, 0xd0, 0x97, 0xaa, 0x19, 0x24, + 0x63, 0x5e, 0xef, 0xd2, 0x95, 0xa8, 0x1b, 0x26, 0x61, 0x5c, + 0x1a, 0x27, 0x60, 0x5d, 0xee, 0xd3, 0x94, 0xa9, 0x10, 0x2d, + 0x6a, 0x57, 0xe4, 0xd9, 0x9e, 0xa3, 0xe5, 0xd8, 0x9f, 0xa2, + 0x11, 0x2c, 0x6b, 0x56, 0xe7, 0xda, 0x9d, 0xa0, 0x13, 0x2e, + 0x69, 0x54, 0x12, 0x2f, 0x68, 0x55, 0xe6, 0xdb, 0x9c, 0xa1, + 0xe3, 0xde, 0x99, 0xa4, 0x17, 0x2a, 0x6d, 0x50, 0x16, 0x2b, + 0x6c, 0x51, 0xe2, 0xdf, 0x98, 0xa5, 0x14, 0x29, 0x6e, 0x53, + 0xe0, 0xdd, 0x9a, 0xa7, 0xe1, 0xdc, 0x9b, 0xa6, 0x15, 0x28, + 0x6f, 0x52, 0x00, 0x3e, 0x7c, 0x42, 0xf8, 0xc6, 0x84, 0xba, + 0xed, 0xd3, 0x91, 0xaf, 0x15, 0x2b, 0x69, 0x57, 0xc7, 0xf9, + 0xbb, 0x85, 0x3f, 0x01, 0x43, 0x7d, 0x2a, 0x14, 0x56, 0x68, + 0xd2, 0xec, 0xae, 0x90, 0x93, 0xad, 0xef, 0xd1, 0x6b, 0x55, + 0x17, 0x29, 0x7e, 0x40, 0x02, 0x3c, 0x86, 0xb8, 0xfa, 0xc4, + 0x54, 0x6a, 0x28, 0x16, 0xac, 0x92, 0xd0, 0xee, 0xb9, 0x87, + 0xc5, 0xfb, 0x41, 0x7f, 0x3d, 0x03, 0x3b, 0x05, 0x47, 0x79, + 0xc3, 0xfd, 0xbf, 0x81, 0xd6, 0xe8, 0xaa, 0x94, 0x2e, 0x10, + 0x52, 0x6c, 0xfc, 0xc2, 0x80, 0xbe, 0x04, 0x3a, 0x78, 0x46, + 0x11, 0x2f, 0x6d, 0x53, 0xe9, 0xd7, 0x95, 0xab, 0xa8, 0x96, + 0xd4, 0xea, 0x50, 0x6e, 0x2c, 0x12, 0x45, 0x7b, 0x39, 0x07, + 0xbd, 0x83, 0xc1, 0xff, 0x6f, 0x51, 0x13, 0x2d, 0x97, 0xa9, + 0xeb, 0xd5, 0x82, 0xbc, 0xfe, 0xc0, 0x7a, 0x44, 0x06, 0x38, + 0x76, 0x48, 0x0a, 0x34, 0x8e, 0xb0, 0xf2, 0xcc, 0x9b, 0xa5, + 0xe7, 0xd9, 0x63, 0x5d, 0x1f, 0x21, 0xb1, 0x8f, 0xcd, 0xf3, + 0x49, 0x77, 0x35, 0x0b, 0x5c, 0x62, 0x20, 0x1e, 0xa4, 0x9a, + 0xd8, 0xe6, 0xe5, 0xdb, 0x99, 0xa7, 0x1d, 0x23, 0x61, 0x5f, + 0x08, 0x36, 0x74, 0x4a, 0xf0, 0xce, 0x8c, 0xb2, 0x22, 0x1c, + 0x5e, 0x60, 0xda, 0xe4, 0xa6, 0x98, 0xcf, 0xf1, 0xb3, 0x8d, + 0x37, 0x09, 0x4b, 0x75, 0x4d, 0x73, 0x31, 0x0f, 0xb5, 0x8b, + 0xc9, 0xf7, 0xa0, 0x9e, 0xdc, 0xe2, 0x58, 0x66, 0x24, 0x1a, + 0x8a, 0xb4, 0xf6, 0xc8, 0x72, 0x4c, 0x0e, 0x30, 0x67, 0x59, + 0x1b, 0x25, 0x9f, 0xa1, 0xe3, 0xdd, 0xde, 0xe0, 0xa2, 0x9c, + 0x26, 0x18, 0x5a, 0x64, 0x33, 0x0d, 0x4f, 0x71, 0xcb, 0xf5, + 0xb7, 0x89, 0x19, 0x27, 0x65, 0x5b, 0xe1, 0xdf, 0x9d, 0xa3, + 0xf4, 0xca, 0x88, 0xb6, 0x0c, 0x32, 0x70, 0x4e, 0x00, 0x3f, + 0x7e, 0x41, 0xfc, 0xc3, 0x82, 0xbd, 0xe5, 0xda, 0x9b, 0xa4, + 0x19, 0x26, 0x67, 0x58, 0xd7, 0xe8, 0xa9, 0x96, 0x2b, 0x14, + 0x55, 0x6a, 0x32, 0x0d, 0x4c, 0x73, 0xce, 0xf1, 0xb0, 0x8f, + 0xb3, 0x8c, 0xcd, 0xf2, 0x4f, 0x70, 0x31, 0x0e, 0x56, 0x69, + 0x28, 0x17, 0xaa, 0x95, 0xd4, 0xeb, 0x64, 0x5b, 0x1a, 0x25, + 0x98, 0xa7, 0xe6, 0xd9, 0x81, 0xbe, 0xff, 0xc0, 0x7d, 0x42, + 0x03, 0x3c, 0x7b, 0x44, 0x05, 0x3a, 0x87, 0xb8, 0xf9, 0xc6, + 0x9e, 0xa1, 0xe0, 0xdf, 0x62, 0x5d, 0x1c, 0x23, 0xac, 0x93, + 0xd2, 0xed, 0x50, 0x6f, 0x2e, 0x11, 0x49, 0x76, 0x37, 0x08, + 0xb5, 0x8a, 0xcb, 0xf4, 0xc8, 0xf7, 0xb6, 0x89, 0x34, 0x0b, + 0x4a, 0x75, 0x2d, 0x12, 0x53, 0x6c, 0xd1, 0xee, 0xaf, 0x90, + 0x1f, 0x20, 0x61, 0x5e, 0xe3, 0xdc, 0x9d, 0xa2, 0xfa, 0xc5, + 0x84, 0xbb, 0x06, 0x39, 0x78, 0x47, 0xf6, 0xc9, 0x88, 0xb7, + 0x0a, 0x35, 0x74, 0x4b, 0x13, 0x2c, 0x6d, 0x52, 0xef, 0xd0, + 0x91, 0xae, 0x21, 0x1e, 0x5f, 0x60, 0xdd, 0xe2, 0xa3, 0x9c, + 0xc4, 0xfb, 0xba, 0x85, 0x38, 0x07, 0x46, 0x79, 0x45, 0x7a, + 0x3b, 0x04, 0xb9, 0x86, 0xc7, 0xf8, 0xa0, 0x9f, 0xde, 0xe1, + 0x5c, 0x63, 0x22, 0x1d, 0x92, 0xad, 0xec, 0xd3, 0x6e, 0x51, + 0x10, 0x2f, 0x77, 0x48, 0x09, 0x36, 0x8b, 0xb4, 0xf5, 0xca, + 0x8d, 0xb2, 0xf3, 0xcc, 0x71, 0x4e, 0x0f, 0x30, 0x68, 0x57, + 0x16, 0x29, 0x94, 0xab, 0xea, 0xd5, 0x5a, 0x65, 0x24, 0x1b, + 0xa6, 0x99, 0xd8, 0xe7, 0xbf, 0x80, 0xc1, 0xfe, 0x43, 0x7c, + 0x3d, 0x02, 0x3e, 0x01, 0x40, 0x7f, 0xc2, 0xfd, 0xbc, 0x83, + 0xdb, 0xe4, 0xa5, 0x9a, 0x27, 0x18, 0x59, 0x66, 0xe9, 0xd6, + 0x97, 0xa8, 0x15, 0x2a, 0x6b, 0x54, 0x0c, 0x33, 0x72, 0x4d, + 0xf0, 0xcf, 0x8e, 0xb1, 0x00, 0x40, 0x80, 0xc0, 0x1d, 0x5d, + 0x9d, 0xdd, 0x3a, 0x7a, 0xba, 0xfa, 0x27, 0x67, 0xa7, 0xe7, + 0x74, 0x34, 0xf4, 0xb4, 0x69, 0x29, 0xe9, 0xa9, 0x4e, 0x0e, + 0xce, 0x8e, 0x53, 0x13, 0xd3, 0x93, 0xe8, 0xa8, 0x68, 0x28, + 0xf5, 0xb5, 0x75, 0x35, 0xd2, 0x92, 0x52, 0x12, 0xcf, 0x8f, + 0x4f, 0x0f, 0x9c, 0xdc, 0x1c, 0x5c, 0x81, 0xc1, 0x01, 0x41, + 0xa6, 0xe6, 0x26, 0x66, 0xbb, 0xfb, 0x3b, 0x7b, 0xcd, 0x8d, + 0x4d, 0x0d, 0xd0, 0x90, 0x50, 0x10, 0xf7, 0xb7, 0x77, 0x37, + 0xea, 0xaa, 0x6a, 0x2a, 0xb9, 0xf9, 0x39, 0x79, 0xa4, 0xe4, + 0x24, 0x64, 0x83, 0xc3, 0x03, 0x43, 0x9e, 0xde, 0x1e, 0x5e, + 0x25, 0x65, 0xa5, 0xe5, 0x38, 0x78, 0xb8, 0xf8, 0x1f, 0x5f, + 0x9f, 0xdf, 0x02, 0x42, 0x82, 0xc2, 0x51, 0x11, 0xd1, 0x91, + 0x4c, 0x0c, 0xcc, 0x8c, 0x6b, 0x2b, 0xeb, 0xab, 0x76, 0x36, + 0xf6, 0xb6, 0x87, 0xc7, 0x07, 0x47, 0x9a, 0xda, 0x1a, 0x5a, + 0xbd, 0xfd, 0x3d, 0x7d, 0xa0, 0xe0, 0x20, 0x60, 0xf3, 0xb3, + 0x73, 0x33, 0xee, 0xae, 0x6e, 0x2e, 0xc9, 0x89, 0x49, 0x09, + 0xd4, 0x94, 0x54, 0x14, 0x6f, 0x2f, 0xef, 0xaf, 0x72, 0x32, + 0xf2, 0xb2, 0x55, 0x15, 0xd5, 0x95, 0x48, 0x08, 0xc8, 0x88, + 0x1b, 0x5b, 0x9b, 0xdb, 0x06, 0x46, 0x86, 0xc6, 0x21, 0x61, + 0xa1, 0xe1, 0x3c, 0x7c, 0xbc, 0xfc, 0x4a, 0x0a, 0xca, 0x8a, + 0x57, 0x17, 0xd7, 0x97, 0x70, 0x30, 0xf0, 0xb0, 0x6d, 0x2d, + 0xed, 0xad, 0x3e, 0x7e, 0xbe, 0xfe, 0x23, 0x63, 0xa3, 0xe3, + 0x04, 0x44, 0x84, 0xc4, 0x19, 0x59, 0x99, 0xd9, 0xa2, 0xe2, + 0x22, 0x62, 0xbf, 0xff, 0x3f, 0x7f, 0x98, 0xd8, 0x18, 0x58, + 0x85, 0xc5, 0x05, 0x45, 0xd6, 0x96, 0x56, 0x16, 0xcb, 0x8b, + 0x4b, 0x0b, 0xec, 0xac, 0x6c, 0x2c, 0xf1, 0xb1, 0x71, 0x31, + 0x00, 0x41, 0x82, 0xc3, 0x19, 0x58, 0x9b, 0xda, 0x32, 0x73, + 0xb0, 0xf1, 0x2b, 0x6a, 0xa9, 0xe8, 0x64, 0x25, 0xe6, 0xa7, + 0x7d, 0x3c, 0xff, 0xbe, 0x56, 0x17, 0xd4, 0x95, 0x4f, 0x0e, + 0xcd, 0x8c, 0xc8, 0x89, 0x4a, 0x0b, 0xd1, 0x90, 0x53, 0x12, + 0xfa, 0xbb, 0x78, 0x39, 0xe3, 0xa2, 0x61, 0x20, 0xac, 0xed, + 0x2e, 0x6f, 0xb5, 0xf4, 0x37, 0x76, 0x9e, 0xdf, 0x1c, 0x5d, + 0x87, 0xc6, 0x05, 0x44, 0x8d, 0xcc, 0x0f, 0x4e, 0x94, 0xd5, + 0x16, 0x57, 0xbf, 0xfe, 0x3d, 0x7c, 0xa6, 0xe7, 0x24, 0x65, + 0xe9, 0xa8, 0x6b, 0x2a, 0xf0, 0xb1, 0x72, 0x33, 0xdb, 0x9a, + 0x59, 0x18, 0xc2, 0x83, 0x40, 0x01, 0x45, 0x04, 0xc7, 0x86, + 0x5c, 0x1d, 0xde, 0x9f, 0x77, 0x36, 0xf5, 0xb4, 0x6e, 0x2f, + 0xec, 0xad, 0x21, 0x60, 0xa3, 0xe2, 0x38, 0x79, 0xba, 0xfb, + 0x13, 0x52, 0x91, 0xd0, 0x0a, 0x4b, 0x88, 0xc9, 0x07, 0x46, + 0x85, 0xc4, 0x1e, 0x5f, 0x9c, 0xdd, 0x35, 0x74, 0xb7, 0xf6, + 0x2c, 0x6d, 0xae, 0xef, 0x63, 0x22, 0xe1, 0xa0, 0x7a, 0x3b, + 0xf8, 0xb9, 0x51, 0x10, 0xd3, 0x92, 0x48, 0x09, 0xca, 0x8b, + 0xcf, 0x8e, 0x4d, 0x0c, 0xd6, 0x97, 0x54, 0x15, 0xfd, 0xbc, + 0x7f, 0x3e, 0xe4, 0xa5, 0x66, 0x27, 0xab, 0xea, 0x29, 0x68, + 0xb2, 0xf3, 0x30, 0x71, 0x99, 0xd8, 0x1b, 0x5a, 0x80, 0xc1, + 0x02, 0x43, 0x8a, 0xcb, 0x08, 0x49, 0x93, 0xd2, 0x11, 0x50, + 0xb8, 0xf9, 0x3a, 0x7b, 0xa1, 0xe0, 0x23, 0x62, 0xee, 0xaf, + 0x6c, 0x2d, 0xf7, 0xb6, 0x75, 0x34, 0xdc, 0x9d, 0x5e, 0x1f, + 0xc5, 0x84, 0x47, 0x06, 0x42, 0x03, 0xc0, 0x81, 0x5b, 0x1a, + 0xd9, 0x98, 0x70, 0x31, 0xf2, 0xb3, 0x69, 0x28, 0xeb, 0xaa, + 0x26, 0x67, 0xa4, 0xe5, 0x3f, 0x7e, 0xbd, 0xfc, 0x14, 0x55, + 0x96, 0xd7, 0x0d, 0x4c, 0x8f, 0xce, 0x00, 0x42, 0x84, 0xc6, + 0x15, 0x57, 0x91, 0xd3, 0x2a, 0x68, 0xae, 0xec, 0x3f, 0x7d, + 0xbb, 0xf9, 0x54, 0x16, 0xd0, 0x92, 0x41, 0x03, 0xc5, 0x87, + 0x7e, 0x3c, 0xfa, 0xb8, 0x6b, 0x29, 0xef, 0xad, 0xa8, 0xea, + 0x2c, 0x6e, 0xbd, 0xff, 0x39, 0x7b, 0x82, 0xc0, 0x06, 0x44, + 0x97, 0xd5, 0x13, 0x51, 0xfc, 0xbe, 0x78, 0x3a, 0xe9, 0xab, + 0x6d, 0x2f, 0xd6, 0x94, 0x52, 0x10, 0xc3, 0x81, 0x47, 0x05, + 0x4d, 0x0f, 0xc9, 0x8b, 0x58, 0x1a, 0xdc, 0x9e, 0x67, 0x25, + 0xe3, 0xa1, 0x72, 0x30, 0xf6, 0xb4, 0x19, 0x5b, 0x9d, 0xdf, + 0x0c, 0x4e, 0x88, 0xca, 0x33, 0x71, 0xb7, 0xf5, 0x26, 0x64, + 0xa2, 0xe0, 0xe5, 0xa7, 0x61, 0x23, 0xf0, 0xb2, 0x74, 0x36, + 0xcf, 0x8d, 0x4b, 0x09, 0xda, 0x98, 0x5e, 0x1c, 0xb1, 0xf3, + 0x35, 0x77, 0xa4, 0xe6, 0x20, 0x62, 0x9b, 0xd9, 0x1f, 0x5d, + 0x8e, 0xcc, 0x0a, 0x48, 0x9a, 0xd8, 0x1e, 0x5c, 0x8f, 0xcd, + 0x0b, 0x49, 0xb0, 0xf2, 0x34, 0x76, 0xa5, 0xe7, 0x21, 0x63, + 0xce, 0x8c, 0x4a, 0x08, 0xdb, 0x99, 0x5f, 0x1d, 0xe4, 0xa6, + 0x60, 0x22, 0xf1, 0xb3, 0x75, 0x37, 0x32, 0x70, 0xb6, 0xf4, + 0x27, 0x65, 0xa3, 0xe1, 0x18, 0x5a, 0x9c, 0xde, 0x0d, 0x4f, + 0x89, 0xcb, 0x66, 0x24, 0xe2, 0xa0, 0x73, 0x31, 0xf7, 0xb5, + 0x4c, 0x0e, 0xc8, 0x8a, 0x59, 0x1b, 0xdd, 0x9f, 0xd7, 0x95, + 0x53, 0x11, 0xc2, 0x80, 0x46, 0x04, 0xfd, 0xbf, 0x79, 0x3b, + 0xe8, 0xaa, 0x6c, 0x2e, 0x83, 0xc1, 0x07, 0x45, 0x96, 0xd4, + 0x12, 0x50, 0xa9, 0xeb, 0x2d, 0x6f, 0xbc, 0xfe, 0x38, 0x7a, + 0x7f, 0x3d, 0xfb, 0xb9, 0x6a, 0x28, 0xee, 0xac, 0x55, 0x17, + 0xd1, 0x93, 0x40, 0x02, 0xc4, 0x86, 0x2b, 0x69, 0xaf, 0xed, + 0x3e, 0x7c, 0xba, 0xf8, 0x01, 0x43, 0x85, 0xc7, 0x14, 0x56, + 0x90, 0xd2, 0x00, 0x43, 0x86, 0xc5, 0x11, 0x52, 0x97, 0xd4, + 0x22, 0x61, 0xa4, 0xe7, 0x33, 0x70, 0xb5, 0xf6, 0x44, 0x07, + 0xc2, 0x81, 0x55, 0x16, 0xd3, 0x90, 0x66, 0x25, 0xe0, 0xa3, + 0x77, 0x34, 0xf1, 0xb2, 0x88, 0xcb, 0x0e, 0x4d, 0x99, 0xda, + 0x1f, 0x5c, 0xaa, 0xe9, 0x2c, 0x6f, 0xbb, 0xf8, 0x3d, 0x7e, + 0xcc, 0x8f, 0x4a, 0x09, 0xdd, 0x9e, 0x5b, 0x18, 0xee, 0xad, + 0x68, 0x2b, 0xff, 0xbc, 0x79, 0x3a, 0x0d, 0x4e, 0x8b, 0xc8, + 0x1c, 0x5f, 0x9a, 0xd9, 0x2f, 0x6c, 0xa9, 0xea, 0x3e, 0x7d, + 0xb8, 0xfb, 0x49, 0x0a, 0xcf, 0x8c, 0x58, 0x1b, 0xde, 0x9d, + 0x6b, 0x28, 0xed, 0xae, 0x7a, 0x39, 0xfc, 0xbf, 0x85, 0xc6, + 0x03, 0x40, 0x94, 0xd7, 0x12, 0x51, 0xa7, 0xe4, 0x21, 0x62, + 0xb6, 0xf5, 0x30, 0x73, 0xc1, 0x82, 0x47, 0x04, 0xd0, 0x93, + 0x56, 0x15, 0xe3, 0xa0, 0x65, 0x26, 0xf2, 0xb1, 0x74, 0x37, + 0x1a, 0x59, 0x9c, 0xdf, 0x0b, 0x48, 0x8d, 0xce, 0x38, 0x7b, + 0xbe, 0xfd, 0x29, 0x6a, 0xaf, 0xec, 0x5e, 0x1d, 0xd8, 0x9b, + 0x4f, 0x0c, 0xc9, 0x8a, 0x7c, 0x3f, 0xfa, 0xb9, 0x6d, 0x2e, + 0xeb, 0xa8, 0x92, 0xd1, 0x14, 0x57, 0x83, 0xc0, 0x05, 0x46, + 0xb0, 0xf3, 0x36, 0x75, 0xa1, 0xe2, 0x27, 0x64, 0xd6, 0x95, + 0x50, 0x13, 0xc7, 0x84, 0x41, 0x02, 0xf4, 0xb7, 0x72, 0x31, + 0xe5, 0xa6, 0x63, 0x20, 0x17, 0x54, 0x91, 0xd2, 0x06, 0x45, + 0x80, 0xc3, 0x35, 0x76, 0xb3, 0xf0, 0x24, 0x67, 0xa2, 0xe1, + 0x53, 0x10, 0xd5, 0x96, 0x42, 0x01, 0xc4, 0x87, 0x71, 0x32, + 0xf7, 0xb4, 0x60, 0x23, 0xe6, 0xa5, 0x9f, 0xdc, 0x19, 0x5a, + 0x8e, 0xcd, 0x08, 0x4b, 0xbd, 0xfe, 0x3b, 0x78, 0xac, 0xef, + 0x2a, 0x69, 0xdb, 0x98, 0x5d, 0x1e, 0xca, 0x89, 0x4c, 0x0f, + 0xf9, 0xba, 0x7f, 0x3c, 0xe8, 0xab, 0x6e, 0x2d, 0x00, 0x44, + 0x88, 0xcc, 0x0d, 0x49, 0x85, 0xc1, 0x1a, 0x5e, 0x92, 0xd6, + 0x17, 0x53, 0x9f, 0xdb, 0x34, 0x70, 0xbc, 0xf8, 0x39, 0x7d, + 0xb1, 0xf5, 0x2e, 0x6a, 0xa6, 0xe2, 0x23, 0x67, 0xab, 0xef, + 0x68, 0x2c, 0xe0, 0xa4, 0x65, 0x21, 0xed, 0xa9, 0x72, 0x36, + 0xfa, 0xbe, 0x7f, 0x3b, 0xf7, 0xb3, 0x5c, 0x18, 0xd4, 0x90, + 0x51, 0x15, 0xd9, 0x9d, 0x46, 0x02, 0xce, 0x8a, 0x4b, 0x0f, + 0xc3, 0x87, 0xd0, 0x94, 0x58, 0x1c, 0xdd, 0x99, 0x55, 0x11, + 0xca, 0x8e, 0x42, 0x06, 0xc7, 0x83, 0x4f, 0x0b, 0xe4, 0xa0, + 0x6c, 0x28, 0xe9, 0xad, 0x61, 0x25, 0xfe, 0xba, 0x76, 0x32, + 0xf3, 0xb7, 0x7b, 0x3f, 0xb8, 0xfc, 0x30, 0x74, 0xb5, 0xf1, + 0x3d, 0x79, 0xa2, 0xe6, 0x2a, 0x6e, 0xaf, 0xeb, 0x27, 0x63, + 0x8c, 0xc8, 0x04, 0x40, 0x81, 0xc5, 0x09, 0x4d, 0x96, 0xd2, + 0x1e, 0x5a, 0x9b, 0xdf, 0x13, 0x57, 0xbd, 0xf9, 0x35, 0x71, + 0xb0, 0xf4, 0x38, 0x7c, 0xa7, 0xe3, 0x2f, 0x6b, 0xaa, 0xee, + 0x22, 0x66, 0x89, 0xcd, 0x01, 0x45, 0x84, 0xc0, 0x0c, 0x48, + 0x93, 0xd7, 0x1b, 0x5f, 0x9e, 0xda, 0x16, 0x52, 0xd5, 0x91, + 0x5d, 0x19, 0xd8, 0x9c, 0x50, 0x14, 0xcf, 0x8b, 0x47, 0x03, + 0xc2, 0x86, 0x4a, 0x0e, 0xe1, 0xa5, 0x69, 0x2d, 0xec, 0xa8, + 0x64, 0x20, 0xfb, 0xbf, 0x73, 0x37, 0xf6, 0xb2, 0x7e, 0x3a, + 0x6d, 0x29, 0xe5, 0xa1, 0x60, 0x24, 0xe8, 0xac, 0x77, 0x33, + 0xff, 0xbb, 0x7a, 0x3e, 0xf2, 0xb6, 0x59, 0x1d, 0xd1, 0x95, + 0x54, 0x10, 0xdc, 0x98, 0x43, 0x07, 0xcb, 0x8f, 0x4e, 0x0a, + 0xc6, 0x82, 0x05, 0x41, 0x8d, 0xc9, 0x08, 0x4c, 0x80, 0xc4, + 0x1f, 0x5b, 0x97, 0xd3, 0x12, 0x56, 0x9a, 0xde, 0x31, 0x75, + 0xb9, 0xfd, 0x3c, 0x78, 0xb4, 0xf0, 0x2b, 0x6f, 0xa3, 0xe7, + 0x26, 0x62, 0xae, 0xea, 0x00, 0x45, 0x8a, 0xcf, 0x09, 0x4c, + 0x83, 0xc6, 0x12, 0x57, 0x98, 0xdd, 0x1b, 0x5e, 0x91, 0xd4, + 0x24, 0x61, 0xae, 0xeb, 0x2d, 0x68, 0xa7, 0xe2, 0x36, 0x73, + 0xbc, 0xf9, 0x3f, 0x7a, 0xb5, 0xf0, 0x48, 0x0d, 0xc2, 0x87, + 0x41, 0x04, 0xcb, 0x8e, 0x5a, 0x1f, 0xd0, 0x95, 0x53, 0x16, + 0xd9, 0x9c, 0x6c, 0x29, 0xe6, 0xa3, 0x65, 0x20, 0xef, 0xaa, + 0x7e, 0x3b, 0xf4, 0xb1, 0x77, 0x32, 0xfd, 0xb8, 0x90, 0xd5, + 0x1a, 0x5f, 0x99, 0xdc, 0x13, 0x56, 0x82, 0xc7, 0x08, 0x4d, + 0x8b, 0xce, 0x01, 0x44, 0xb4, 0xf1, 0x3e, 0x7b, 0xbd, 0xf8, + 0x37, 0x72, 0xa6, 0xe3, 0x2c, 0x69, 0xaf, 0xea, 0x25, 0x60, + 0xd8, 0x9d, 0x52, 0x17, 0xd1, 0x94, 0x5b, 0x1e, 0xca, 0x8f, + 0x40, 0x05, 0xc3, 0x86, 0x49, 0x0c, 0xfc, 0xb9, 0x76, 0x33, + 0xf5, 0xb0, 0x7f, 0x3a, 0xee, 0xab, 0x64, 0x21, 0xe7, 0xa2, + 0x6d, 0x28, 0x3d, 0x78, 0xb7, 0xf2, 0x34, 0x71, 0xbe, 0xfb, + 0x2f, 0x6a, 0xa5, 0xe0, 0x26, 0x63, 0xac, 0xe9, 0x19, 0x5c, + 0x93, 0xd6, 0x10, 0x55, 0x9a, 0xdf, 0x0b, 0x4e, 0x81, 0xc4, + 0x02, 0x47, 0x88, 0xcd, 0x75, 0x30, 0xff, 0xba, 0x7c, 0x39, + 0xf6, 0xb3, 0x67, 0x22, 0xed, 0xa8, 0x6e, 0x2b, 0xe4, 0xa1, + 0x51, 0x14, 0xdb, 0x9e, 0x58, 0x1d, 0xd2, 0x97, 0x43, 0x06, + 0xc9, 0x8c, 0x4a, 0x0f, 0xc0, 0x85, 0xad, 0xe8, 0x27, 0x62, + 0xa4, 0xe1, 0x2e, 0x6b, 0xbf, 0xfa, 0x35, 0x70, 0xb6, 0xf3, + 0x3c, 0x79, 0x89, 0xcc, 0x03, 0x46, 0x80, 0xc5, 0x0a, 0x4f, + 0x9b, 0xde, 0x11, 0x54, 0x92, 0xd7, 0x18, 0x5d, 0xe5, 0xa0, + 0x6f, 0x2a, 0xec, 0xa9, 0x66, 0x23, 0xf7, 0xb2, 0x7d, 0x38, + 0xfe, 0xbb, 0x74, 0x31, 0xc1, 0x84, 0x4b, 0x0e, 0xc8, 0x8d, + 0x42, 0x07, 0xd3, 0x96, 0x59, 0x1c, 0xda, 0x9f, 0x50, 0x15, + 0x00, 0x46, 0x8c, 0xca, 0x05, 0x43, 0x89, 0xcf, 0x0a, 0x4c, + 0x86, 0xc0, 0x0f, 0x49, 0x83, 0xc5, 0x14, 0x52, 0x98, 0xde, + 0x11, 0x57, 0x9d, 0xdb, 0x1e, 0x58, 0x92, 0xd4, 0x1b, 0x5d, + 0x97, 0xd1, 0x28, 0x6e, 0xa4, 0xe2, 0x2d, 0x6b, 0xa1, 0xe7, + 0x22, 0x64, 0xae, 0xe8, 0x27, 0x61, 0xab, 0xed, 0x3c, 0x7a, + 0xb0, 0xf6, 0x39, 0x7f, 0xb5, 0xf3, 0x36, 0x70, 0xba, 0xfc, + 0x33, 0x75, 0xbf, 0xf9, 0x50, 0x16, 0xdc, 0x9a, 0x55, 0x13, + 0xd9, 0x9f, 0x5a, 0x1c, 0xd6, 0x90, 0x5f, 0x19, 0xd3, 0x95, + 0x44, 0x02, 0xc8, 0x8e, 0x41, 0x07, 0xcd, 0x8b, 0x4e, 0x08, + 0xc2, 0x84, 0x4b, 0x0d, 0xc7, 0x81, 0x78, 0x3e, 0xf4, 0xb2, + 0x7d, 0x3b, 0xf1, 0xb7, 0x72, 0x34, 0xfe, 0xb8, 0x77, 0x31, + 0xfb, 0xbd, 0x6c, 0x2a, 0xe0, 0xa6, 0x69, 0x2f, 0xe5, 0xa3, + 0x66, 0x20, 0xea, 0xac, 0x63, 0x25, 0xef, 0xa9, 0xa0, 0xe6, + 0x2c, 0x6a, 0xa5, 0xe3, 0x29, 0x6f, 0xaa, 0xec, 0x26, 0x60, + 0xaf, 0xe9, 0x23, 0x65, 0xb4, 0xf2, 0x38, 0x7e, 0xb1, 0xf7, + 0x3d, 0x7b, 0xbe, 0xf8, 0x32, 0x74, 0xbb, 0xfd, 0x37, 0x71, + 0x88, 0xce, 0x04, 0x42, 0x8d, 0xcb, 0x01, 0x47, 0x82, 0xc4, + 0x0e, 0x48, 0x87, 0xc1, 0x0b, 0x4d, 0x9c, 0xda, 0x10, 0x56, + 0x99, 0xdf, 0x15, 0x53, 0x96, 0xd0, 0x1a, 0x5c, 0x93, 0xd5, + 0x1f, 0x59, 0xf0, 0xb6, 0x7c, 0x3a, 0xf5, 0xb3, 0x79, 0x3f, + 0xfa, 0xbc, 0x76, 0x30, 0xff, 0xb9, 0x73, 0x35, 0xe4, 0xa2, + 0x68, 0x2e, 0xe1, 0xa7, 0x6d, 0x2b, 0xee, 0xa8, 0x62, 0x24, + 0xeb, 0xad, 0x67, 0x21, 0xd8, 0x9e, 0x54, 0x12, 0xdd, 0x9b, + 0x51, 0x17, 0xd2, 0x94, 0x5e, 0x18, 0xd7, 0x91, 0x5b, 0x1d, + 0xcc, 0x8a, 0x40, 0x06, 0xc9, 0x8f, 0x45, 0x03, 0xc6, 0x80, + 0x4a, 0x0c, 0xc3, 0x85, 0x4f, 0x09, 0x00, 0x47, 0x8e, 0xc9, + 0x01, 0x46, 0x8f, 0xc8, 0x02, 0x45, 0x8c, 0xcb, 0x03, 0x44, + 0x8d, 0xca, 0x04, 0x43, 0x8a, 0xcd, 0x05, 0x42, 0x8b, 0xcc, + 0x06, 0x41, 0x88, 0xcf, 0x07, 0x40, 0x89, 0xce, 0x08, 0x4f, + 0x86, 0xc1, 0x09, 0x4e, 0x87, 0xc0, 0x0a, 0x4d, 0x84, 0xc3, + 0x0b, 0x4c, 0x85, 0xc2, 0x0c, 0x4b, 0x82, 0xc5, 0x0d, 0x4a, + 0x83, 0xc4, 0x0e, 0x49, 0x80, 0xc7, 0x0f, 0x48, 0x81, 0xc6, + 0x10, 0x57, 0x9e, 0xd9, 0x11, 0x56, 0x9f, 0xd8, 0x12, 0x55, + 0x9c, 0xdb, 0x13, 0x54, 0x9d, 0xda, 0x14, 0x53, 0x9a, 0xdd, + 0x15, 0x52, 0x9b, 0xdc, 0x16, 0x51, 0x98, 0xdf, 0x17, 0x50, + 0x99, 0xde, 0x18, 0x5f, 0x96, 0xd1, 0x19, 0x5e, 0x97, 0xd0, + 0x1a, 0x5d, 0x94, 0xd3, 0x1b, 0x5c, 0x95, 0xd2, 0x1c, 0x5b, + 0x92, 0xd5, 0x1d, 0x5a, 0x93, 0xd4, 0x1e, 0x59, 0x90, 0xd7, + 0x1f, 0x58, 0x91, 0xd6, 0x20, 0x67, 0xae, 0xe9, 0x21, 0x66, + 0xaf, 0xe8, 0x22, 0x65, 0xac, 0xeb, 0x23, 0x64, 0xad, 0xea, + 0x24, 0x63, 0xaa, 0xed, 0x25, 0x62, 0xab, 0xec, 0x26, 0x61, + 0xa8, 0xef, 0x27, 0x60, 0xa9, 0xee, 0x28, 0x6f, 0xa6, 0xe1, + 0x29, 0x6e, 0xa7, 0xe0, 0x2a, 0x6d, 0xa4, 0xe3, 0x2b, 0x6c, + 0xa5, 0xe2, 0x2c, 0x6b, 0xa2, 0xe5, 0x2d, 0x6a, 0xa3, 0xe4, + 0x2e, 0x69, 0xa0, 0xe7, 0x2f, 0x68, 0xa1, 0xe6, 0x30, 0x77, + 0xbe, 0xf9, 0x31, 0x76, 0xbf, 0xf8, 0x32, 0x75, 0xbc, 0xfb, + 0x33, 0x74, 0xbd, 0xfa, 0x34, 0x73, 0xba, 0xfd, 0x35, 0x72, + 0xbb, 0xfc, 0x36, 0x71, 0xb8, 0xff, 0x37, 0x70, 0xb9, 0xfe, + 0x38, 0x7f, 0xb6, 0xf1, 0x39, 0x7e, 0xb7, 0xf0, 0x3a, 0x7d, + 0xb4, 0xf3, 0x3b, 0x7c, 0xb5, 0xf2, 0x3c, 0x7b, 0xb2, 0xf5, + 0x3d, 0x7a, 0xb3, 0xf4, 0x3e, 0x79, 0xb0, 0xf7, 0x3f, 0x78, + 0xb1, 0xf6, 0x00, 0x48, 0x90, 0xd8, 0x3d, 0x75, 0xad, 0xe5, + 0x7a, 0x32, 0xea, 0xa2, 0x47, 0x0f, 0xd7, 0x9f, 0xf4, 0xbc, + 0x64, 0x2c, 0xc9, 0x81, 0x59, 0x11, 0x8e, 0xc6, 0x1e, 0x56, + 0xb3, 0xfb, 0x23, 0x6b, 0xf5, 0xbd, 0x65, 0x2d, 0xc8, 0x80, + 0x58, 0x10, 0x8f, 0xc7, 0x1f, 0x57, 0xb2, 0xfa, 0x22, 0x6a, + 0x01, 0x49, 0x91, 0xd9, 0x3c, 0x74, 0xac, 0xe4, 0x7b, 0x33, + 0xeb, 0xa3, 0x46, 0x0e, 0xd6, 0x9e, 0xf7, 0xbf, 0x67, 0x2f, + 0xca, 0x82, 0x5a, 0x12, 0x8d, 0xc5, 0x1d, 0x55, 0xb0, 0xf8, + 0x20, 0x68, 0x03, 0x4b, 0x93, 0xdb, 0x3e, 0x76, 0xae, 0xe6, + 0x79, 0x31, 0xe9, 0xa1, 0x44, 0x0c, 0xd4, 0x9c, 0x02, 0x4a, + 0x92, 0xda, 0x3f, 0x77, 0xaf, 0xe7, 0x78, 0x30, 0xe8, 0xa0, + 0x45, 0x0d, 0xd5, 0x9d, 0xf6, 0xbe, 0x66, 0x2e, 0xcb, 0x83, + 0x5b, 0x13, 0x8c, 0xc4, 0x1c, 0x54, 0xb1, 0xf9, 0x21, 0x69, + 0xf3, 0xbb, 0x63, 0x2b, 0xce, 0x86, 0x5e, 0x16, 0x89, 0xc1, + 0x19, 0x51, 0xb4, 0xfc, 0x24, 0x6c, 0x07, 0x4f, 0x97, 0xdf, + 0x3a, 0x72, 0xaa, 0xe2, 0x7d, 0x35, 0xed, 0xa5, 0x40, 0x08, + 0xd0, 0x98, 0x06, 0x4e, 0x96, 0xde, 0x3b, 0x73, 0xab, 0xe3, + 0x7c, 0x34, 0xec, 0xa4, 0x41, 0x09, 0xd1, 0x99, 0xf2, 0xba, + 0x62, 0x2a, 0xcf, 0x87, 0x5f, 0x17, 0x88, 0xc0, 0x18, 0x50, + 0xb5, 0xfd, 0x25, 0x6d, 0x04, 0x4c, 0x94, 0xdc, 0x39, 0x71, + 0xa9, 0xe1, 0x7e, 0x36, 0xee, 0xa6, 0x43, 0x0b, 0xd3, 0x9b, + 0xf0, 0xb8, 0x60, 0x28, 0xcd, 0x85, 0x5d, 0x15, 0x8a, 0xc2, + 0x1a, 0x52, 0xb7, 0xff, 0x27, 0x6f, 0xf1, 0xb9, 0x61, 0x29, + 0xcc, 0x84, 0x5c, 0x14, 0x8b, 0xc3, 0x1b, 0x53, 0xb6, 0xfe, + 0x26, 0x6e, 0x05, 0x4d, 0x95, 0xdd, 0x38, 0x70, 0xa8, 0xe0, + 0x7f, 0x37, 0xef, 0xa7, 0x42, 0x0a, 0xd2, 0x9a, 0x00, 0x49, + 0x92, 0xdb, 0x39, 0x70, 0xab, 0xe2, 0x72, 0x3b, 0xe0, 0xa9, + 0x4b, 0x02, 0xd9, 0x90, 0xe4, 0xad, 0x76, 0x3f, 0xdd, 0x94, + 0x4f, 0x06, 0x96, 0xdf, 0x04, 0x4d, 0xaf, 0xe6, 0x3d, 0x74, + 0xd5, 0x9c, 0x47, 0x0e, 0xec, 0xa5, 0x7e, 0x37, 0xa7, 0xee, + 0x35, 0x7c, 0x9e, 0xd7, 0x0c, 0x45, 0x31, 0x78, 0xa3, 0xea, + 0x08, 0x41, 0x9a, 0xd3, 0x43, 0x0a, 0xd1, 0x98, 0x7a, 0x33, + 0xe8, 0xa1, 0xb7, 0xfe, 0x25, 0x6c, 0x8e, 0xc7, 0x1c, 0x55, + 0xc5, 0x8c, 0x57, 0x1e, 0xfc, 0xb5, 0x6e, 0x27, 0x53, 0x1a, + 0xc1, 0x88, 0x6a, 0x23, 0xf8, 0xb1, 0x21, 0x68, 0xb3, 0xfa, + 0x18, 0x51, 0x8a, 0xc3, 0x62, 0x2b, 0xf0, 0xb9, 0x5b, 0x12, + 0xc9, 0x80, 0x10, 0x59, 0x82, 0xcb, 0x29, 0x60, 0xbb, 0xf2, + 0x86, 0xcf, 0x14, 0x5d, 0xbf, 0xf6, 0x2d, 0x64, 0xf4, 0xbd, + 0x66, 0x2f, 0xcd, 0x84, 0x5f, 0x16, 0x73, 0x3a, 0xe1, 0xa8, + 0x4a, 0x03, 0xd8, 0x91, 0x01, 0x48, 0x93, 0xda, 0x38, 0x71, + 0xaa, 0xe3, 0x97, 0xde, 0x05, 0x4c, 0xae, 0xe7, 0x3c, 0x75, + 0xe5, 0xac, 0x77, 0x3e, 0xdc, 0x95, 0x4e, 0x07, 0xa6, 0xef, + 0x34, 0x7d, 0x9f, 0xd6, 0x0d, 0x44, 0xd4, 0x9d, 0x46, 0x0f, + 0xed, 0xa4, 0x7f, 0x36, 0x42, 0x0b, 0xd0, 0x99, 0x7b, 0x32, + 0xe9, 0xa0, 0x30, 0x79, 0xa2, 0xeb, 0x09, 0x40, 0x9b, 0xd2, + 0xc4, 0x8d, 0x56, 0x1f, 0xfd, 0xb4, 0x6f, 0x26, 0xb6, 0xff, + 0x24, 0x6d, 0x8f, 0xc6, 0x1d, 0x54, 0x20, 0x69, 0xb2, 0xfb, + 0x19, 0x50, 0x8b, 0xc2, 0x52, 0x1b, 0xc0, 0x89, 0x6b, 0x22, + 0xf9, 0xb0, 0x11, 0x58, 0x83, 0xca, 0x28, 0x61, 0xba, 0xf3, + 0x63, 0x2a, 0xf1, 0xb8, 0x5a, 0x13, 0xc8, 0x81, 0xf5, 0xbc, + 0x67, 0x2e, 0xcc, 0x85, 0x5e, 0x17, 0x87, 0xce, 0x15, 0x5c, + 0xbe, 0xf7, 0x2c, 0x65, 0x00, 0x4a, 0x94, 0xde, 0x35, 0x7f, + 0xa1, 0xeb, 0x6a, 0x20, 0xfe, 0xb4, 0x5f, 0x15, 0xcb, 0x81, + 0xd4, 0x9e, 0x40, 0x0a, 0xe1, 0xab, 0x75, 0x3f, 0xbe, 0xf4, + 0x2a, 0x60, 0x8b, 0xc1, 0x1f, 0x55, 0xb5, 0xff, 0x21, 0x6b, + 0x80, 0xca, 0x14, 0x5e, 0xdf, 0x95, 0x4b, 0x01, 0xea, 0xa0, + 0x7e, 0x34, 0x61, 0x2b, 0xf5, 0xbf, 0x54, 0x1e, 0xc0, 0x8a, + 0x0b, 0x41, 0x9f, 0xd5, 0x3e, 0x74, 0xaa, 0xe0, 0x77, 0x3d, + 0xe3, 0xa9, 0x42, 0x08, 0xd6, 0x9c, 0x1d, 0x57, 0x89, 0xc3, + 0x28, 0x62, 0xbc, 0xf6, 0xa3, 0xe9, 0x37, 0x7d, 0x96, 0xdc, + 0x02, 0x48, 0xc9, 0x83, 0x5d, 0x17, 0xfc, 0xb6, 0x68, 0x22, + 0xc2, 0x88, 0x56, 0x1c, 0xf7, 0xbd, 0x63, 0x29, 0xa8, 0xe2, + 0x3c, 0x76, 0x9d, 0xd7, 0x09, 0x43, 0x16, 0x5c, 0x82, 0xc8, + 0x23, 0x69, 0xb7, 0xfd, 0x7c, 0x36, 0xe8, 0xa2, 0x49, 0x03, + 0xdd, 0x97, 0xee, 0xa4, 0x7a, 0x30, 0xdb, 0x91, 0x4f, 0x05, + 0x84, 0xce, 0x10, 0x5a, 0xb1, 0xfb, 0x25, 0x6f, 0x3a, 0x70, + 0xae, 0xe4, 0x0f, 0x45, 0x9b, 0xd1, 0x50, 0x1a, 0xc4, 0x8e, + 0x65, 0x2f, 0xf1, 0xbb, 0x5b, 0x11, 0xcf, 0x85, 0x6e, 0x24, + 0xfa, 0xb0, 0x31, 0x7b, 0xa5, 0xef, 0x04, 0x4e, 0x90, 0xda, + 0x8f, 0xc5, 0x1b, 0x51, 0xba, 0xf0, 0x2e, 0x64, 0xe5, 0xaf, + 0x71, 0x3b, 0xd0, 0x9a, 0x44, 0x0e, 0x99, 0xd3, 0x0d, 0x47, + 0xac, 0xe6, 0x38, 0x72, 0xf3, 0xb9, 0x67, 0x2d, 0xc6, 0x8c, + 0x52, 0x18, 0x4d, 0x07, 0xd9, 0x93, 0x78, 0x32, 0xec, 0xa6, + 0x27, 0x6d, 0xb3, 0xf9, 0x12, 0x58, 0x86, 0xcc, 0x2c, 0x66, + 0xb8, 0xf2, 0x19, 0x53, 0x8d, 0xc7, 0x46, 0x0c, 0xd2, 0x98, + 0x73, 0x39, 0xe7, 0xad, 0xf8, 0xb2, 0x6c, 0x26, 0xcd, 0x87, + 0x59, 0x13, 0x92, 0xd8, 0x06, 0x4c, 0xa7, 0xed, 0x33, 0x79, + 0x00, 0x4b, 0x96, 0xdd, 0x31, 0x7a, 0xa7, 0xec, 0x62, 0x29, + 0xf4, 0xbf, 0x53, 0x18, 0xc5, 0x8e, 0xc4, 0x8f, 0x52, 0x19, + 0xf5, 0xbe, 0x63, 0x28, 0xa6, 0xed, 0x30, 0x7b, 0x97, 0xdc, + 0x01, 0x4a, 0x95, 0xde, 0x03, 0x48, 0xa4, 0xef, 0x32, 0x79, + 0xf7, 0xbc, 0x61, 0x2a, 0xc6, 0x8d, 0x50, 0x1b, 0x51, 0x1a, + 0xc7, 0x8c, 0x60, 0x2b, 0xf6, 0xbd, 0x33, 0x78, 0xa5, 0xee, + 0x02, 0x49, 0x94, 0xdf, 0x37, 0x7c, 0xa1, 0xea, 0x06, 0x4d, + 0x90, 0xdb, 0x55, 0x1e, 0xc3, 0x88, 0x64, 0x2f, 0xf2, 0xb9, + 0xf3, 0xb8, 0x65, 0x2e, 0xc2, 0x89, 0x54, 0x1f, 0x91, 0xda, + 0x07, 0x4c, 0xa0, 0xeb, 0x36, 0x7d, 0xa2, 0xe9, 0x34, 0x7f, + 0x93, 0xd8, 0x05, 0x4e, 0xc0, 0x8b, 0x56, 0x1d, 0xf1, 0xba, + 0x67, 0x2c, 0x66, 0x2d, 0xf0, 0xbb, 0x57, 0x1c, 0xc1, 0x8a, + 0x04, 0x4f, 0x92, 0xd9, 0x35, 0x7e, 0xa3, 0xe8, 0x6e, 0x25, + 0xf8, 0xb3, 0x5f, 0x14, 0xc9, 0x82, 0x0c, 0x47, 0x9a, 0xd1, + 0x3d, 0x76, 0xab, 0xe0, 0xaa, 0xe1, 0x3c, 0x77, 0x9b, 0xd0, + 0x0d, 0x46, 0xc8, 0x83, 0x5e, 0x15, 0xf9, 0xb2, 0x6f, 0x24, + 0xfb, 0xb0, 0x6d, 0x26, 0xca, 0x81, 0x5c, 0x17, 0x99, 0xd2, + 0x0f, 0x44, 0xa8, 0xe3, 0x3e, 0x75, 0x3f, 0x74, 0xa9, 0xe2, + 0x0e, 0x45, 0x98, 0xd3, 0x5d, 0x16, 0xcb, 0x80, 0x6c, 0x27, + 0xfa, 0xb1, 0x59, 0x12, 0xcf, 0x84, 0x68, 0x23, 0xfe, 0xb5, + 0x3b, 0x70, 0xad, 0xe6, 0x0a, 0x41, 0x9c, 0xd7, 0x9d, 0xd6, + 0x0b, 0x40, 0xac, 0xe7, 0x3a, 0x71, 0xff, 0xb4, 0x69, 0x22, + 0xce, 0x85, 0x58, 0x13, 0xcc, 0x87, 0x5a, 0x11, 0xfd, 0xb6, + 0x6b, 0x20, 0xae, 0xe5, 0x38, 0x73, 0x9f, 0xd4, 0x09, 0x42, + 0x08, 0x43, 0x9e, 0xd5, 0x39, 0x72, 0xaf, 0xe4, 0x6a, 0x21, + 0xfc, 0xb7, 0x5b, 0x10, 0xcd, 0x86, 0x00, 0x4c, 0x98, 0xd4, + 0x2d, 0x61, 0xb5, 0xf9, 0x5a, 0x16, 0xc2, 0x8e, 0x77, 0x3b, + 0xef, 0xa3, 0xb4, 0xf8, 0x2c, 0x60, 0x99, 0xd5, 0x01, 0x4d, + 0xee, 0xa2, 0x76, 0x3a, 0xc3, 0x8f, 0x5b, 0x17, 0x75, 0x39, + 0xed, 0xa1, 0x58, 0x14, 0xc0, 0x8c, 0x2f, 0x63, 0xb7, 0xfb, + 0x02, 0x4e, 0x9a, 0xd6, 0xc1, 0x8d, 0x59, 0x15, 0xec, 0xa0, + 0x74, 0x38, 0x9b, 0xd7, 0x03, 0x4f, 0xb6, 0xfa, 0x2e, 0x62, + 0xea, 0xa6, 0x72, 0x3e, 0xc7, 0x8b, 0x5f, 0x13, 0xb0, 0xfc, + 0x28, 0x64, 0x9d, 0xd1, 0x05, 0x49, 0x5e, 0x12, 0xc6, 0x8a, + 0x73, 0x3f, 0xeb, 0xa7, 0x04, 0x48, 0x9c, 0xd0, 0x29, 0x65, + 0xb1, 0xfd, 0x9f, 0xd3, 0x07, 0x4b, 0xb2, 0xfe, 0x2a, 0x66, + 0xc5, 0x89, 0x5d, 0x11, 0xe8, 0xa4, 0x70, 0x3c, 0x2b, 0x67, + 0xb3, 0xff, 0x06, 0x4a, 0x9e, 0xd2, 0x71, 0x3d, 0xe9, 0xa5, + 0x5c, 0x10, 0xc4, 0x88, 0xc9, 0x85, 0x51, 0x1d, 0xe4, 0xa8, + 0x7c, 0x30, 0x93, 0xdf, 0x0b, 0x47, 0xbe, 0xf2, 0x26, 0x6a, + 0x7d, 0x31, 0xe5, 0xa9, 0x50, 0x1c, 0xc8, 0x84, 0x27, 0x6b, + 0xbf, 0xf3, 0x0a, 0x46, 0x92, 0xde, 0xbc, 0xf0, 0x24, 0x68, + 0x91, 0xdd, 0x09, 0x45, 0xe6, 0xaa, 0x7e, 0x32, 0xcb, 0x87, + 0x53, 0x1f, 0x08, 0x44, 0x90, 0xdc, 0x25, 0x69, 0xbd, 0xf1, + 0x52, 0x1e, 0xca, 0x86, 0x7f, 0x33, 0xe7, 0xab, 0x23, 0x6f, + 0xbb, 0xf7, 0x0e, 0x42, 0x96, 0xda, 0x79, 0x35, 0xe1, 0xad, + 0x54, 0x18, 0xcc, 0x80, 0x97, 0xdb, 0x0f, 0x43, 0xba, 0xf6, + 0x22, 0x6e, 0xcd, 0x81, 0x55, 0x19, 0xe0, 0xac, 0x78, 0x34, + 0x56, 0x1a, 0xce, 0x82, 0x7b, 0x37, 0xe3, 0xaf, 0x0c, 0x40, + 0x94, 0xd8, 0x21, 0x6d, 0xb9, 0xf5, 0xe2, 0xae, 0x7a, 0x36, + 0xcf, 0x83, 0x57, 0x1b, 0xb8, 0xf4, 0x20, 0x6c, 0x95, 0xd9, + 0x0d, 0x41, 0x00, 0x4d, 0x9a, 0xd7, 0x29, 0x64, 0xb3, 0xfe, + 0x52, 0x1f, 0xc8, 0x85, 0x7b, 0x36, 0xe1, 0xac, 0xa4, 0xe9, + 0x3e, 0x73, 0x8d, 0xc0, 0x17, 0x5a, 0xf6, 0xbb, 0x6c, 0x21, + 0xdf, 0x92, 0x45, 0x08, 0x55, 0x18, 0xcf, 0x82, 0x7c, 0x31, + 0xe6, 0xab, 0x07, 0x4a, 0x9d, 0xd0, 0x2e, 0x63, 0xb4, 0xf9, + 0xf1, 0xbc, 0x6b, 0x26, 0xd8, 0x95, 0x42, 0x0f, 0xa3, 0xee, + 0x39, 0x74, 0x8a, 0xc7, 0x10, 0x5d, 0xaa, 0xe7, 0x30, 0x7d, + 0x83, 0xce, 0x19, 0x54, 0xf8, 0xb5, 0x62, 0x2f, 0xd1, 0x9c, + 0x4b, 0x06, 0x0e, 0x43, 0x94, 0xd9, 0x27, 0x6a, 0xbd, 0xf0, + 0x5c, 0x11, 0xc6, 0x8b, 0x75, 0x38, 0xef, 0xa2, 0xff, 0xb2, + 0x65, 0x28, 0xd6, 0x9b, 0x4c, 0x01, 0xad, 0xe0, 0x37, 0x7a, + 0x84, 0xc9, 0x1e, 0x53, 0x5b, 0x16, 0xc1, 0x8c, 0x72, 0x3f, + 0xe8, 0xa5, 0x09, 0x44, 0x93, 0xde, 0x20, 0x6d, 0xba, 0xf7, + 0x49, 0x04, 0xd3, 0x9e, 0x60, 0x2d, 0xfa, 0xb7, 0x1b, 0x56, + 0x81, 0xcc, 0x32, 0x7f, 0xa8, 0xe5, 0xed, 0xa0, 0x77, 0x3a, + 0xc4, 0x89, 0x5e, 0x13, 0xbf, 0xf2, 0x25, 0x68, 0x96, 0xdb, + 0x0c, 0x41, 0x1c, 0x51, 0x86, 0xcb, 0x35, 0x78, 0xaf, 0xe2, + 0x4e, 0x03, 0xd4, 0x99, 0x67, 0x2a, 0xfd, 0xb0, 0xb8, 0xf5, + 0x22, 0x6f, 0x91, 0xdc, 0x0b, 0x46, 0xea, 0xa7, 0x70, 0x3d, + 0xc3, 0x8e, 0x59, 0x14, 0xe3, 0xae, 0x79, 0x34, 0xca, 0x87, + 0x50, 0x1d, 0xb1, 0xfc, 0x2b, 0x66, 0x98, 0xd5, 0x02, 0x4f, + 0x47, 0x0a, 0xdd, 0x90, 0x6e, 0x23, 0xf4, 0xb9, 0x15, 0x58, + 0x8f, 0xc2, 0x3c, 0x71, 0xa6, 0xeb, 0xb6, 0xfb, 0x2c, 0x61, + 0x9f, 0xd2, 0x05, 0x48, 0xe4, 0xa9, 0x7e, 0x33, 0xcd, 0x80, + 0x57, 0x1a, 0x12, 0x5f, 0x88, 0xc5, 0x3b, 0x76, 0xa1, 0xec, + 0x40, 0x0d, 0xda, 0x97, 0x69, 0x24, 0xf3, 0xbe, 0x00, 0x4e, + 0x9c, 0xd2, 0x25, 0x6b, 0xb9, 0xf7, 0x4a, 0x04, 0xd6, 0x98, + 0x6f, 0x21, 0xf3, 0xbd, 0x94, 0xda, 0x08, 0x46, 0xb1, 0xff, + 0x2d, 0x63, 0xde, 0x90, 0x42, 0x0c, 0xfb, 0xb5, 0x67, 0x29, + 0x35, 0x7b, 0xa9, 0xe7, 0x10, 0x5e, 0x8c, 0xc2, 0x7f, 0x31, + 0xe3, 0xad, 0x5a, 0x14, 0xc6, 0x88, 0xa1, 0xef, 0x3d, 0x73, + 0x84, 0xca, 0x18, 0x56, 0xeb, 0xa5, 0x77, 0x39, 0xce, 0x80, + 0x52, 0x1c, 0x6a, 0x24, 0xf6, 0xb8, 0x4f, 0x01, 0xd3, 0x9d, + 0x20, 0x6e, 0xbc, 0xf2, 0x05, 0x4b, 0x99, 0xd7, 0xfe, 0xb0, + 0x62, 0x2c, 0xdb, 0x95, 0x47, 0x09, 0xb4, 0xfa, 0x28, 0x66, + 0x91, 0xdf, 0x0d, 0x43, 0x5f, 0x11, 0xc3, 0x8d, 0x7a, 0x34, + 0xe6, 0xa8, 0x15, 0x5b, 0x89, 0xc7, 0x30, 0x7e, 0xac, 0xe2, + 0xcb, 0x85, 0x57, 0x19, 0xee, 0xa0, 0x72, 0x3c, 0x81, 0xcf, + 0x1d, 0x53, 0xa4, 0xea, 0x38, 0x76, 0xd4, 0x9a, 0x48, 0x06, + 0xf1, 0xbf, 0x6d, 0x23, 0x9e, 0xd0, 0x02, 0x4c, 0xbb, 0xf5, + 0x27, 0x69, 0x40, 0x0e, 0xdc, 0x92, 0x65, 0x2b, 0xf9, 0xb7, + 0x0a, 0x44, 0x96, 0xd8, 0x2f, 0x61, 0xb3, 0xfd, 0xe1, 0xaf, + 0x7d, 0x33, 0xc4, 0x8a, 0x58, 0x16, 0xab, 0xe5, 0x37, 0x79, + 0x8e, 0xc0, 0x12, 0x5c, 0x75, 0x3b, 0xe9, 0xa7, 0x50, 0x1e, + 0xcc, 0x82, 0x3f, 0x71, 0xa3, 0xed, 0x1a, 0x54, 0x86, 0xc8, + 0xbe, 0xf0, 0x22, 0x6c, 0x9b, 0xd5, 0x07, 0x49, 0xf4, 0xba, + 0x68, 0x26, 0xd1, 0x9f, 0x4d, 0x03, 0x2a, 0x64, 0xb6, 0xf8, + 0x0f, 0x41, 0x93, 0xdd, 0x60, 0x2e, 0xfc, 0xb2, 0x45, 0x0b, + 0xd9, 0x97, 0x8b, 0xc5, 0x17, 0x59, 0xae, 0xe0, 0x32, 0x7c, + 0xc1, 0x8f, 0x5d, 0x13, 0xe4, 0xaa, 0x78, 0x36, 0x1f, 0x51, + 0x83, 0xcd, 0x3a, 0x74, 0xa6, 0xe8, 0x55, 0x1b, 0xc9, 0x87, + 0x70, 0x3e, 0xec, 0xa2, 0x00, 0x4f, 0x9e, 0xd1, 0x21, 0x6e, + 0xbf, 0xf0, 0x42, 0x0d, 0xdc, 0x93, 0x63, 0x2c, 0xfd, 0xb2, + 0x84, 0xcb, 0x1a, 0x55, 0xa5, 0xea, 0x3b, 0x74, 0xc6, 0x89, + 0x58, 0x17, 0xe7, 0xa8, 0x79, 0x36, 0x15, 0x5a, 0x8b, 0xc4, + 0x34, 0x7b, 0xaa, 0xe5, 0x57, 0x18, 0xc9, 0x86, 0x76, 0x39, + 0xe8, 0xa7, 0x91, 0xde, 0x0f, 0x40, 0xb0, 0xff, 0x2e, 0x61, + 0xd3, 0x9c, 0x4d, 0x02, 0xf2, 0xbd, 0x6c, 0x23, 0x2a, 0x65, + 0xb4, 0xfb, 0x0b, 0x44, 0x95, 0xda, 0x68, 0x27, 0xf6, 0xb9, + 0x49, 0x06, 0xd7, 0x98, 0xae, 0xe1, 0x30, 0x7f, 0x8f, 0xc0, + 0x11, 0x5e, 0xec, 0xa3, 0x72, 0x3d, 0xcd, 0x82, 0x53, 0x1c, + 0x3f, 0x70, 0xa1, 0xee, 0x1e, 0x51, 0x80, 0xcf, 0x7d, 0x32, + 0xe3, 0xac, 0x5c, 0x13, 0xc2, 0x8d, 0xbb, 0xf4, 0x25, 0x6a, + 0x9a, 0xd5, 0x04, 0x4b, 0xf9, 0xb6, 0x67, 0x28, 0xd8, 0x97, + 0x46, 0x09, 0x54, 0x1b, 0xca, 0x85, 0x75, 0x3a, 0xeb, 0xa4, + 0x16, 0x59, 0x88, 0xc7, 0x37, 0x78, 0xa9, 0xe6, 0xd0, 0x9f, + 0x4e, 0x01, 0xf1, 0xbe, 0x6f, 0x20, 0x92, 0xdd, 0x0c, 0x43, + 0xb3, 0xfc, 0x2d, 0x62, 0x41, 0x0e, 0xdf, 0x90, 0x60, 0x2f, + 0xfe, 0xb1, 0x03, 0x4c, 0x9d, 0xd2, 0x22, 0x6d, 0xbc, 0xf3, + 0xc5, 0x8a, 0x5b, 0x14, 0xe4, 0xab, 0x7a, 0x35, 0x87, 0xc8, + 0x19, 0x56, 0xa6, 0xe9, 0x38, 0x77, 0x7e, 0x31, 0xe0, 0xaf, + 0x5f, 0x10, 0xc1, 0x8e, 0x3c, 0x73, 0xa2, 0xed, 0x1d, 0x52, + 0x83, 0xcc, 0xfa, 0xb5, 0x64, 0x2b, 0xdb, 0x94, 0x45, 0x0a, + 0xb8, 0xf7, 0x26, 0x69, 0x99, 0xd6, 0x07, 0x48, 0x6b, 0x24, + 0xf5, 0xba, 0x4a, 0x05, 0xd4, 0x9b, 0x29, 0x66, 0xb7, 0xf8, + 0x08, 0x47, 0x96, 0xd9, 0xef, 0xa0, 0x71, 0x3e, 0xce, 0x81, + 0x50, 0x1f, 0xad, 0xe2, 0x33, 0x7c, 0x8c, 0xc3, 0x12, 0x5d, + 0x00, 0x50, 0xa0, 0xf0, 0x5d, 0x0d, 0xfd, 0xad, 0xba, 0xea, + 0x1a, 0x4a, 0xe7, 0xb7, 0x47, 0x17, 0x69, 0x39, 0xc9, 0x99, + 0x34, 0x64, 0x94, 0xc4, 0xd3, 0x83, 0x73, 0x23, 0x8e, 0xde, + 0x2e, 0x7e, 0xd2, 0x82, 0x72, 0x22, 0x8f, 0xdf, 0x2f, 0x7f, + 0x68, 0x38, 0xc8, 0x98, 0x35, 0x65, 0x95, 0xc5, 0xbb, 0xeb, + 0x1b, 0x4b, 0xe6, 0xb6, 0x46, 0x16, 0x01, 0x51, 0xa1, 0xf1, + 0x5c, 0x0c, 0xfc, 0xac, 0xb9, 0xe9, 0x19, 0x49, 0xe4, 0xb4, + 0x44, 0x14, 0x03, 0x53, 0xa3, 0xf3, 0x5e, 0x0e, 0xfe, 0xae, + 0xd0, 0x80, 0x70, 0x20, 0x8d, 0xdd, 0x2d, 0x7d, 0x6a, 0x3a, + 0xca, 0x9a, 0x37, 0x67, 0x97, 0xc7, 0x6b, 0x3b, 0xcb, 0x9b, + 0x36, 0x66, 0x96, 0xc6, 0xd1, 0x81, 0x71, 0x21, 0x8c, 0xdc, + 0x2c, 0x7c, 0x02, 0x52, 0xa2, 0xf2, 0x5f, 0x0f, 0xff, 0xaf, + 0xb8, 0xe8, 0x18, 0x48, 0xe5, 0xb5, 0x45, 0x15, 0x6f, 0x3f, + 0xcf, 0x9f, 0x32, 0x62, 0x92, 0xc2, 0xd5, 0x85, 0x75, 0x25, + 0x88, 0xd8, 0x28, 0x78, 0x06, 0x56, 0xa6, 0xf6, 0x5b, 0x0b, + 0xfb, 0xab, 0xbc, 0xec, 0x1c, 0x4c, 0xe1, 0xb1, 0x41, 0x11, + 0xbd, 0xed, 0x1d, 0x4d, 0xe0, 0xb0, 0x40, 0x10, 0x07, 0x57, + 0xa7, 0xf7, 0x5a, 0x0a, 0xfa, 0xaa, 0xd4, 0x84, 0x74, 0x24, + 0x89, 0xd9, 0x29, 0x79, 0x6e, 0x3e, 0xce, 0x9e, 0x33, 0x63, + 0x93, 0xc3, 0xd6, 0x86, 0x76, 0x26, 0x8b, 0xdb, 0x2b, 0x7b, + 0x6c, 0x3c, 0xcc, 0x9c, 0x31, 0x61, 0x91, 0xc1, 0xbf, 0xef, + 0x1f, 0x4f, 0xe2, 0xb2, 0x42, 0x12, 0x05, 0x55, 0xa5, 0xf5, + 0x58, 0x08, 0xf8, 0xa8, 0x04, 0x54, 0xa4, 0xf4, 0x59, 0x09, + 0xf9, 0xa9, 0xbe, 0xee, 0x1e, 0x4e, 0xe3, 0xb3, 0x43, 0x13, + 0x6d, 0x3d, 0xcd, 0x9d, 0x30, 0x60, 0x90, 0xc0, 0xd7, 0x87, + 0x77, 0x27, 0x8a, 0xda, 0x2a, 0x7a, 0x00, 0x51, 0xa2, 0xf3, + 0x59, 0x08, 0xfb, 0xaa, 0xb2, 0xe3, 0x10, 0x41, 0xeb, 0xba, + 0x49, 0x18, 0x79, 0x28, 0xdb, 0x8a, 0x20, 0x71, 0x82, 0xd3, + 0xcb, 0x9a, 0x69, 0x38, 0x92, 0xc3, 0x30, 0x61, 0xf2, 0xa3, + 0x50, 0x01, 0xab, 0xfa, 0x09, 0x58, 0x40, 0x11, 0xe2, 0xb3, + 0x19, 0x48, 0xbb, 0xea, 0x8b, 0xda, 0x29, 0x78, 0xd2, 0x83, + 0x70, 0x21, 0x39, 0x68, 0x9b, 0xca, 0x60, 0x31, 0xc2, 0x93, + 0xf9, 0xa8, 0x5b, 0x0a, 0xa0, 0xf1, 0x02, 0x53, 0x4b, 0x1a, + 0xe9, 0xb8, 0x12, 0x43, 0xb0, 0xe1, 0x80, 0xd1, 0x22, 0x73, + 0xd9, 0x88, 0x7b, 0x2a, 0x32, 0x63, 0x90, 0xc1, 0x6b, 0x3a, + 0xc9, 0x98, 0x0b, 0x5a, 0xa9, 0xf8, 0x52, 0x03, 0xf0, 0xa1, + 0xb9, 0xe8, 0x1b, 0x4a, 0xe0, 0xb1, 0x42, 0x13, 0x72, 0x23, + 0xd0, 0x81, 0x2b, 0x7a, 0x89, 0xd8, 0xc0, 0x91, 0x62, 0x33, + 0x99, 0xc8, 0x3b, 0x6a, 0xef, 0xbe, 0x4d, 0x1c, 0xb6, 0xe7, + 0x14, 0x45, 0x5d, 0x0c, 0xff, 0xae, 0x04, 0x55, 0xa6, 0xf7, + 0x96, 0xc7, 0x34, 0x65, 0xcf, 0x9e, 0x6d, 0x3c, 0x24, 0x75, + 0x86, 0xd7, 0x7d, 0x2c, 0xdf, 0x8e, 0x1d, 0x4c, 0xbf, 0xee, + 0x44, 0x15, 0xe6, 0xb7, 0xaf, 0xfe, 0x0d, 0x5c, 0xf6, 0xa7, + 0x54, 0x05, 0x64, 0x35, 0xc6, 0x97, 0x3d, 0x6c, 0x9f, 0xce, + 0xd6, 0x87, 0x74, 0x25, 0x8f, 0xde, 0x2d, 0x7c, 0x16, 0x47, + 0xb4, 0xe5, 0x4f, 0x1e, 0xed, 0xbc, 0xa4, 0xf5, 0x06, 0x57, + 0xfd, 0xac, 0x5f, 0x0e, 0x6f, 0x3e, 0xcd, 0x9c, 0x36, 0x67, + 0x94, 0xc5, 0xdd, 0x8c, 0x7f, 0x2e, 0x84, 0xd5, 0x26, 0x77, + 0xe4, 0xb5, 0x46, 0x17, 0xbd, 0xec, 0x1f, 0x4e, 0x56, 0x07, + 0xf4, 0xa5, 0x0f, 0x5e, 0xad, 0xfc, 0x9d, 0xcc, 0x3f, 0x6e, + 0xc4, 0x95, 0x66, 0x37, 0x2f, 0x7e, 0x8d, 0xdc, 0x76, 0x27, + 0xd4, 0x85, 0x00, 0x52, 0xa4, 0xf6, 0x55, 0x07, 0xf1, 0xa3, + 0xaa, 0xf8, 0x0e, 0x5c, 0xff, 0xad, 0x5b, 0x09, 0x49, 0x1b, + 0xed, 0xbf, 0x1c, 0x4e, 0xb8, 0xea, 0xe3, 0xb1, 0x47, 0x15, + 0xb6, 0xe4, 0x12, 0x40, 0x92, 0xc0, 0x36, 0x64, 0xc7, 0x95, + 0x63, 0x31, 0x38, 0x6a, 0x9c, 0xce, 0x6d, 0x3f, 0xc9, 0x9b, + 0xdb, 0x89, 0x7f, 0x2d, 0x8e, 0xdc, 0x2a, 0x78, 0x71, 0x23, + 0xd5, 0x87, 0x24, 0x76, 0x80, 0xd2, 0x39, 0x6b, 0x9d, 0xcf, + 0x6c, 0x3e, 0xc8, 0x9a, 0x93, 0xc1, 0x37, 0x65, 0xc6, 0x94, + 0x62, 0x30, 0x70, 0x22, 0xd4, 0x86, 0x25, 0x77, 0x81, 0xd3, + 0xda, 0x88, 0x7e, 0x2c, 0x8f, 0xdd, 0x2b, 0x79, 0xab, 0xf9, + 0x0f, 0x5d, 0xfe, 0xac, 0x5a, 0x08, 0x01, 0x53, 0xa5, 0xf7, + 0x54, 0x06, 0xf0, 0xa2, 0xe2, 0xb0, 0x46, 0x14, 0xb7, 0xe5, + 0x13, 0x41, 0x48, 0x1a, 0xec, 0xbe, 0x1d, 0x4f, 0xb9, 0xeb, + 0x72, 0x20, 0xd6, 0x84, 0x27, 0x75, 0x83, 0xd1, 0xd8, 0x8a, + 0x7c, 0x2e, 0x8d, 0xdf, 0x29, 0x7b, 0x3b, 0x69, 0x9f, 0xcd, + 0x6e, 0x3c, 0xca, 0x98, 0x91, 0xc3, 0x35, 0x67, 0xc4, 0x96, + 0x60, 0x32, 0xe0, 0xb2, 0x44, 0x16, 0xb5, 0xe7, 0x11, 0x43, + 0x4a, 0x18, 0xee, 0xbc, 0x1f, 0x4d, 0xbb, 0xe9, 0xa9, 0xfb, + 0x0d, 0x5f, 0xfc, 0xae, 0x58, 0x0a, 0x03, 0x51, 0xa7, 0xf5, + 0x56, 0x04, 0xf2, 0xa0, 0x4b, 0x19, 0xef, 0xbd, 0x1e, 0x4c, + 0xba, 0xe8, 0xe1, 0xb3, 0x45, 0x17, 0xb4, 0xe6, 0x10, 0x42, + 0x02, 0x50, 0xa6, 0xf4, 0x57, 0x05, 0xf3, 0xa1, 0xa8, 0xfa, + 0x0c, 0x5e, 0xfd, 0xaf, 0x59, 0x0b, 0xd9, 0x8b, 0x7d, 0x2f, + 0x8c, 0xde, 0x28, 0x7a, 0x73, 0x21, 0xd7, 0x85, 0x26, 0x74, + 0x82, 0xd0, 0x90, 0xc2, 0x34, 0x66, 0xc5, 0x97, 0x61, 0x33, + 0x3a, 0x68, 0x9e, 0xcc, 0x6f, 0x3d, 0xcb, 0x99, 0x00, 0x53, + 0xa6, 0xf5, 0x51, 0x02, 0xf7, 0xa4, 0xa2, 0xf1, 0x04, 0x57, + 0xf3, 0xa0, 0x55, 0x06, 0x59, 0x0a, 0xff, 0xac, 0x08, 0x5b, + 0xae, 0xfd, 0xfb, 0xa8, 0x5d, 0x0e, 0xaa, 0xf9, 0x0c, 0x5f, + 0xb2, 0xe1, 0x14, 0x47, 0xe3, 0xb0, 0x45, 0x16, 0x10, 0x43, + 0xb6, 0xe5, 0x41, 0x12, 0xe7, 0xb4, 0xeb, 0xb8, 0x4d, 0x1e, + 0xba, 0xe9, 0x1c, 0x4f, 0x49, 0x1a, 0xef, 0xbc, 0x18, 0x4b, + 0xbe, 0xed, 0x79, 0x2a, 0xdf, 0x8c, 0x28, 0x7b, 0x8e, 0xdd, + 0xdb, 0x88, 0x7d, 0x2e, 0x8a, 0xd9, 0x2c, 0x7f, 0x20, 0x73, + 0x86, 0xd5, 0x71, 0x22, 0xd7, 0x84, 0x82, 0xd1, 0x24, 0x77, + 0xd3, 0x80, 0x75, 0x26, 0xcb, 0x98, 0x6d, 0x3e, 0x9a, 0xc9, + 0x3c, 0x6f, 0x69, 0x3a, 0xcf, 0x9c, 0x38, 0x6b, 0x9e, 0xcd, + 0x92, 0xc1, 0x34, 0x67, 0xc3, 0x90, 0x65, 0x36, 0x30, 0x63, + 0x96, 0xc5, 0x61, 0x32, 0xc7, 0x94, 0xf2, 0xa1, 0x54, 0x07, + 0xa3, 0xf0, 0x05, 0x56, 0x50, 0x03, 0xf6, 0xa5, 0x01, 0x52, + 0xa7, 0xf4, 0xab, 0xf8, 0x0d, 0x5e, 0xfa, 0xa9, 0x5c, 0x0f, + 0x09, 0x5a, 0xaf, 0xfc, 0x58, 0x0b, 0xfe, 0xad, 0x40, 0x13, + 0xe6, 0xb5, 0x11, 0x42, 0xb7, 0xe4, 0xe2, 0xb1, 0x44, 0x17, + 0xb3, 0xe0, 0x15, 0x46, 0x19, 0x4a, 0xbf, 0xec, 0x48, 0x1b, + 0xee, 0xbd, 0xbb, 0xe8, 0x1d, 0x4e, 0xea, 0xb9, 0x4c, 0x1f, + 0x8b, 0xd8, 0x2d, 0x7e, 0xda, 0x89, 0x7c, 0x2f, 0x29, 0x7a, + 0x8f, 0xdc, 0x78, 0x2b, 0xde, 0x8d, 0xd2, 0x81, 0x74, 0x27, + 0x83, 0xd0, 0x25, 0x76, 0x70, 0x23, 0xd6, 0x85, 0x21, 0x72, + 0x87, 0xd4, 0x39, 0x6a, 0x9f, 0xcc, 0x68, 0x3b, 0xce, 0x9d, + 0x9b, 0xc8, 0x3d, 0x6e, 0xca, 0x99, 0x6c, 0x3f, 0x60, 0x33, + 0xc6, 0x95, 0x31, 0x62, 0x97, 0xc4, 0xc2, 0x91, 0x64, 0x37, + 0x93, 0xc0, 0x35, 0x66, 0x00, 0x54, 0xa8, 0xfc, 0x4d, 0x19, + 0xe5, 0xb1, 0x9a, 0xce, 0x32, 0x66, 0xd7, 0x83, 0x7f, 0x2b, + 0x29, 0x7d, 0x81, 0xd5, 0x64, 0x30, 0xcc, 0x98, 0xb3, 0xe7, + 0x1b, 0x4f, 0xfe, 0xaa, 0x56, 0x02, 0x52, 0x06, 0xfa, 0xae, + 0x1f, 0x4b, 0xb7, 0xe3, 0xc8, 0x9c, 0x60, 0x34, 0x85, 0xd1, + 0x2d, 0x79, 0x7b, 0x2f, 0xd3, 0x87, 0x36, 0x62, 0x9e, 0xca, + 0xe1, 0xb5, 0x49, 0x1d, 0xac, 0xf8, 0x04, 0x50, 0xa4, 0xf0, + 0x0c, 0x58, 0xe9, 0xbd, 0x41, 0x15, 0x3e, 0x6a, 0x96, 0xc2, + 0x73, 0x27, 0xdb, 0x8f, 0x8d, 0xd9, 0x25, 0x71, 0xc0, 0x94, + 0x68, 0x3c, 0x17, 0x43, 0xbf, 0xeb, 0x5a, 0x0e, 0xf2, 0xa6, + 0xf6, 0xa2, 0x5e, 0x0a, 0xbb, 0xef, 0x13, 0x47, 0x6c, 0x38, + 0xc4, 0x90, 0x21, 0x75, 0x89, 0xdd, 0xdf, 0x8b, 0x77, 0x23, + 0x92, 0xc6, 0x3a, 0x6e, 0x45, 0x11, 0xed, 0xb9, 0x08, 0x5c, + 0xa0, 0xf4, 0x55, 0x01, 0xfd, 0xa9, 0x18, 0x4c, 0xb0, 0xe4, + 0xcf, 0x9b, 0x67, 0x33, 0x82, 0xd6, 0x2a, 0x7e, 0x7c, 0x28, + 0xd4, 0x80, 0x31, 0x65, 0x99, 0xcd, 0xe6, 0xb2, 0x4e, 0x1a, + 0xab, 0xff, 0x03, 0x57, 0x07, 0x53, 0xaf, 0xfb, 0x4a, 0x1e, + 0xe2, 0xb6, 0x9d, 0xc9, 0x35, 0x61, 0xd0, 0x84, 0x78, 0x2c, + 0x2e, 0x7a, 0x86, 0xd2, 0x63, 0x37, 0xcb, 0x9f, 0xb4, 0xe0, + 0x1c, 0x48, 0xf9, 0xad, 0x51, 0x05, 0xf1, 0xa5, 0x59, 0x0d, + 0xbc, 0xe8, 0x14, 0x40, 0x6b, 0x3f, 0xc3, 0x97, 0x26, 0x72, + 0x8e, 0xda, 0xd8, 0x8c, 0x70, 0x24, 0x95, 0xc1, 0x3d, 0x69, + 0x42, 0x16, 0xea, 0xbe, 0x0f, 0x5b, 0xa7, 0xf3, 0xa3, 0xf7, + 0x0b, 0x5f, 0xee, 0xba, 0x46, 0x12, 0x39, 0x6d, 0x91, 0xc5, + 0x74, 0x20, 0xdc, 0x88, 0x8a, 0xde, 0x22, 0x76, 0xc7, 0x93, + 0x6f, 0x3b, 0x10, 0x44, 0xb8, 0xec, 0x5d, 0x09, 0xf5, 0xa1, + 0x00, 0x55, 0xaa, 0xff, 0x49, 0x1c, 0xe3, 0xb6, 0x92, 0xc7, + 0x38, 0x6d, 0xdb, 0x8e, 0x71, 0x24, 0x39, 0x6c, 0x93, 0xc6, + 0x70, 0x25, 0xda, 0x8f, 0xab, 0xfe, 0x01, 0x54, 0xe2, 0xb7, + 0x48, 0x1d, 0x72, 0x27, 0xd8, 0x8d, 0x3b, 0x6e, 0x91, 0xc4, + 0xe0, 0xb5, 0x4a, 0x1f, 0xa9, 0xfc, 0x03, 0x56, 0x4b, 0x1e, + 0xe1, 0xb4, 0x02, 0x57, 0xa8, 0xfd, 0xd9, 0x8c, 0x73, 0x26, + 0x90, 0xc5, 0x3a, 0x6f, 0xe4, 0xb1, 0x4e, 0x1b, 0xad, 0xf8, + 0x07, 0x52, 0x76, 0x23, 0xdc, 0x89, 0x3f, 0x6a, 0x95, 0xc0, + 0xdd, 0x88, 0x77, 0x22, 0x94, 0xc1, 0x3e, 0x6b, 0x4f, 0x1a, + 0xe5, 0xb0, 0x06, 0x53, 0xac, 0xf9, 0x96, 0xc3, 0x3c, 0x69, + 0xdf, 0x8a, 0x75, 0x20, 0x04, 0x51, 0xae, 0xfb, 0x4d, 0x18, + 0xe7, 0xb2, 0xaf, 0xfa, 0x05, 0x50, 0xe6, 0xb3, 0x4c, 0x19, + 0x3d, 0x68, 0x97, 0xc2, 0x74, 0x21, 0xde, 0x8b, 0xd5, 0x80, + 0x7f, 0x2a, 0x9c, 0xc9, 0x36, 0x63, 0x47, 0x12, 0xed, 0xb8, + 0x0e, 0x5b, 0xa4, 0xf1, 0xec, 0xb9, 0x46, 0x13, 0xa5, 0xf0, + 0x0f, 0x5a, 0x7e, 0x2b, 0xd4, 0x81, 0x37, 0x62, 0x9d, 0xc8, + 0xa7, 0xf2, 0x0d, 0x58, 0xee, 0xbb, 0x44, 0x11, 0x35, 0x60, + 0x9f, 0xca, 0x7c, 0x29, 0xd6, 0x83, 0x9e, 0xcb, 0x34, 0x61, + 0xd7, 0x82, 0x7d, 0x28, 0x0c, 0x59, 0xa6, 0xf3, 0x45, 0x10, + 0xef, 0xba, 0x31, 0x64, 0x9b, 0xce, 0x78, 0x2d, 0xd2, 0x87, + 0xa3, 0xf6, 0x09, 0x5c, 0xea, 0xbf, 0x40, 0x15, 0x08, 0x5d, + 0xa2, 0xf7, 0x41, 0x14, 0xeb, 0xbe, 0x9a, 0xcf, 0x30, 0x65, + 0xd3, 0x86, 0x79, 0x2c, 0x43, 0x16, 0xe9, 0xbc, 0x0a, 0x5f, + 0xa0, 0xf5, 0xd1, 0x84, 0x7b, 0x2e, 0x98, 0xcd, 0x32, 0x67, + 0x7a, 0x2f, 0xd0, 0x85, 0x33, 0x66, 0x99, 0xcc, 0xe8, 0xbd, + 0x42, 0x17, 0xa1, 0xf4, 0x0b, 0x5e, 0x00, 0x56, 0xac, 0xfa, + 0x45, 0x13, 0xe9, 0xbf, 0x8a, 0xdc, 0x26, 0x70, 0xcf, 0x99, + 0x63, 0x35, 0x09, 0x5f, 0xa5, 0xf3, 0x4c, 0x1a, 0xe0, 0xb6, + 0x83, 0xd5, 0x2f, 0x79, 0xc6, 0x90, 0x6a, 0x3c, 0x12, 0x44, + 0xbe, 0xe8, 0x57, 0x01, 0xfb, 0xad, 0x98, 0xce, 0x34, 0x62, + 0xdd, 0x8b, 0x71, 0x27, 0x1b, 0x4d, 0xb7, 0xe1, 0x5e, 0x08, + 0xf2, 0xa4, 0x91, 0xc7, 0x3d, 0x6b, 0xd4, 0x82, 0x78, 0x2e, + 0x24, 0x72, 0x88, 0xde, 0x61, 0x37, 0xcd, 0x9b, 0xae, 0xf8, + 0x02, 0x54, 0xeb, 0xbd, 0x47, 0x11, 0x2d, 0x7b, 0x81, 0xd7, + 0x68, 0x3e, 0xc4, 0x92, 0xa7, 0xf1, 0x0b, 0x5d, 0xe2, 0xb4, + 0x4e, 0x18, 0x36, 0x60, 0x9a, 0xcc, 0x73, 0x25, 0xdf, 0x89, + 0xbc, 0xea, 0x10, 0x46, 0xf9, 0xaf, 0x55, 0x03, 0x3f, 0x69, + 0x93, 0xc5, 0x7a, 0x2c, 0xd6, 0x80, 0xb5, 0xe3, 0x19, 0x4f, + 0xf0, 0xa6, 0x5c, 0x0a, 0x48, 0x1e, 0xe4, 0xb2, 0x0d, 0x5b, + 0xa1, 0xf7, 0xc2, 0x94, 0x6e, 0x38, 0x87, 0xd1, 0x2b, 0x7d, + 0x41, 0x17, 0xed, 0xbb, 0x04, 0x52, 0xa8, 0xfe, 0xcb, 0x9d, + 0x67, 0x31, 0x8e, 0xd8, 0x22, 0x74, 0x5a, 0x0c, 0xf6, 0xa0, + 0x1f, 0x49, 0xb3, 0xe5, 0xd0, 0x86, 0x7c, 0x2a, 0x95, 0xc3, + 0x39, 0x6f, 0x53, 0x05, 0xff, 0xa9, 0x16, 0x40, 0xba, 0xec, + 0xd9, 0x8f, 0x75, 0x23, 0x9c, 0xca, 0x30, 0x66, 0x6c, 0x3a, + 0xc0, 0x96, 0x29, 0x7f, 0x85, 0xd3, 0xe6, 0xb0, 0x4a, 0x1c, + 0xa3, 0xf5, 0x0f, 0x59, 0x65, 0x33, 0xc9, 0x9f, 0x20, 0x76, + 0x8c, 0xda, 0xef, 0xb9, 0x43, 0x15, 0xaa, 0xfc, 0x06, 0x50, + 0x7e, 0x28, 0xd2, 0x84, 0x3b, 0x6d, 0x97, 0xc1, 0xf4, 0xa2, + 0x58, 0x0e, 0xb1, 0xe7, 0x1d, 0x4b, 0x77, 0x21, 0xdb, 0x8d, + 0x32, 0x64, 0x9e, 0xc8, 0xfd, 0xab, 0x51, 0x07, 0xb8, 0xee, + 0x14, 0x42, 0x00, 0x57, 0xae, 0xf9, 0x41, 0x16, 0xef, 0xb8, + 0x82, 0xd5, 0x2c, 0x7b, 0xc3, 0x94, 0x6d, 0x3a, 0x19, 0x4e, + 0xb7, 0xe0, 0x58, 0x0f, 0xf6, 0xa1, 0x9b, 0xcc, 0x35, 0x62, + 0xda, 0x8d, 0x74, 0x23, 0x32, 0x65, 0x9c, 0xcb, 0x73, 0x24, + 0xdd, 0x8a, 0xb0, 0xe7, 0x1e, 0x49, 0xf1, 0xa6, 0x5f, 0x08, + 0x2b, 0x7c, 0x85, 0xd2, 0x6a, 0x3d, 0xc4, 0x93, 0xa9, 0xfe, + 0x07, 0x50, 0xe8, 0xbf, 0x46, 0x11, 0x64, 0x33, 0xca, 0x9d, + 0x25, 0x72, 0x8b, 0xdc, 0xe6, 0xb1, 0x48, 0x1f, 0xa7, 0xf0, + 0x09, 0x5e, 0x7d, 0x2a, 0xd3, 0x84, 0x3c, 0x6b, 0x92, 0xc5, + 0xff, 0xa8, 0x51, 0x06, 0xbe, 0xe9, 0x10, 0x47, 0x56, 0x01, + 0xf8, 0xaf, 0x17, 0x40, 0xb9, 0xee, 0xd4, 0x83, 0x7a, 0x2d, + 0x95, 0xc2, 0x3b, 0x6c, 0x4f, 0x18, 0xe1, 0xb6, 0x0e, 0x59, + 0xa0, 0xf7, 0xcd, 0x9a, 0x63, 0x34, 0x8c, 0xdb, 0x22, 0x75, + 0xc8, 0x9f, 0x66, 0x31, 0x89, 0xde, 0x27, 0x70, 0x4a, 0x1d, + 0xe4, 0xb3, 0x0b, 0x5c, 0xa5, 0xf2, 0xd1, 0x86, 0x7f, 0x28, + 0x90, 0xc7, 0x3e, 0x69, 0x53, 0x04, 0xfd, 0xaa, 0x12, 0x45, + 0xbc, 0xeb, 0xfa, 0xad, 0x54, 0x03, 0xbb, 0xec, 0x15, 0x42, + 0x78, 0x2f, 0xd6, 0x81, 0x39, 0x6e, 0x97, 0xc0, 0xe3, 0xb4, + 0x4d, 0x1a, 0xa2, 0xf5, 0x0c, 0x5b, 0x61, 0x36, 0xcf, 0x98, + 0x20, 0x77, 0x8e, 0xd9, 0xac, 0xfb, 0x02, 0x55, 0xed, 0xba, + 0x43, 0x14, 0x2e, 0x79, 0x80, 0xd7, 0x6f, 0x38, 0xc1, 0x96, + 0xb5, 0xe2, 0x1b, 0x4c, 0xf4, 0xa3, 0x5a, 0x0d, 0x37, 0x60, + 0x99, 0xce, 0x76, 0x21, 0xd8, 0x8f, 0x9e, 0xc9, 0x30, 0x67, + 0xdf, 0x88, 0x71, 0x26, 0x1c, 0x4b, 0xb2, 0xe5, 0x5d, 0x0a, + 0xf3, 0xa4, 0x87, 0xd0, 0x29, 0x7e, 0xc6, 0x91, 0x68, 0x3f, + 0x05, 0x52, 0xab, 0xfc, 0x44, 0x13, 0xea, 0xbd, 0x00, 0x58, + 0xb0, 0xe8, 0x7d, 0x25, 0xcd, 0x95, 0xfa, 0xa2, 0x4a, 0x12, + 0x87, 0xdf, 0x37, 0x6f, 0xe9, 0xb1, 0x59, 0x01, 0x94, 0xcc, + 0x24, 0x7c, 0x13, 0x4b, 0xa3, 0xfb, 0x6e, 0x36, 0xde, 0x86, + 0xcf, 0x97, 0x7f, 0x27, 0xb2, 0xea, 0x02, 0x5a, 0x35, 0x6d, + 0x85, 0xdd, 0x48, 0x10, 0xf8, 0xa0, 0x26, 0x7e, 0x96, 0xce, + 0x5b, 0x03, 0xeb, 0xb3, 0xdc, 0x84, 0x6c, 0x34, 0xa1, 0xf9, + 0x11, 0x49, 0x83, 0xdb, 0x33, 0x6b, 0xfe, 0xa6, 0x4e, 0x16, + 0x79, 0x21, 0xc9, 0x91, 0x04, 0x5c, 0xb4, 0xec, 0x6a, 0x32, + 0xda, 0x82, 0x17, 0x4f, 0xa7, 0xff, 0x90, 0xc8, 0x20, 0x78, + 0xed, 0xb5, 0x5d, 0x05, 0x4c, 0x14, 0xfc, 0xa4, 0x31, 0x69, + 0x81, 0xd9, 0xb6, 0xee, 0x06, 0x5e, 0xcb, 0x93, 0x7b, 0x23, + 0xa5, 0xfd, 0x15, 0x4d, 0xd8, 0x80, 0x68, 0x30, 0x5f, 0x07, + 0xef, 0xb7, 0x22, 0x7a, 0x92, 0xca, 0x1b, 0x43, 0xab, 0xf3, + 0x66, 0x3e, 0xd6, 0x8e, 0xe1, 0xb9, 0x51, 0x09, 0x9c, 0xc4, + 0x2c, 0x74, 0xf2, 0xaa, 0x42, 0x1a, 0x8f, 0xd7, 0x3f, 0x67, + 0x08, 0x50, 0xb8, 0xe0, 0x75, 0x2d, 0xc5, 0x9d, 0xd4, 0x8c, + 0x64, 0x3c, 0xa9, 0xf1, 0x19, 0x41, 0x2e, 0x76, 0x9e, 0xc6, + 0x53, 0x0b, 0xe3, 0xbb, 0x3d, 0x65, 0x8d, 0xd5, 0x40, 0x18, + 0xf0, 0xa8, 0xc7, 0x9f, 0x77, 0x2f, 0xba, 0xe2, 0x0a, 0x52, + 0x98, 0xc0, 0x28, 0x70, 0xe5, 0xbd, 0x55, 0x0d, 0x62, 0x3a, + 0xd2, 0x8a, 0x1f, 0x47, 0xaf, 0xf7, 0x71, 0x29, 0xc1, 0x99, + 0x0c, 0x54, 0xbc, 0xe4, 0x8b, 0xd3, 0x3b, 0x63, 0xf6, 0xae, + 0x46, 0x1e, 0x57, 0x0f, 0xe7, 0xbf, 0x2a, 0x72, 0x9a, 0xc2, + 0xad, 0xf5, 0x1d, 0x45, 0xd0, 0x88, 0x60, 0x38, 0xbe, 0xe6, + 0x0e, 0x56, 0xc3, 0x9b, 0x73, 0x2b, 0x44, 0x1c, 0xf4, 0xac, + 0x39, 0x61, 0x89, 0xd1, 0x00, 0x59, 0xb2, 0xeb, 0x79, 0x20, + 0xcb, 0x92, 0xf2, 0xab, 0x40, 0x19, 0x8b, 0xd2, 0x39, 0x60, + 0xf9, 0xa0, 0x4b, 0x12, 0x80, 0xd9, 0x32, 0x6b, 0x0b, 0x52, + 0xb9, 0xe0, 0x72, 0x2b, 0xc0, 0x99, 0xef, 0xb6, 0x5d, 0x04, + 0x96, 0xcf, 0x24, 0x7d, 0x1d, 0x44, 0xaf, 0xf6, 0x64, 0x3d, + 0xd6, 0x8f, 0x16, 0x4f, 0xa4, 0xfd, 0x6f, 0x36, 0xdd, 0x84, + 0xe4, 0xbd, 0x56, 0x0f, 0x9d, 0xc4, 0x2f, 0x76, 0xc3, 0x9a, + 0x71, 0x28, 0xba, 0xe3, 0x08, 0x51, 0x31, 0x68, 0x83, 0xda, + 0x48, 0x11, 0xfa, 0xa3, 0x3a, 0x63, 0x88, 0xd1, 0x43, 0x1a, + 0xf1, 0xa8, 0xc8, 0x91, 0x7a, 0x23, 0xb1, 0xe8, 0x03, 0x5a, + 0x2c, 0x75, 0x9e, 0xc7, 0x55, 0x0c, 0xe7, 0xbe, 0xde, 0x87, + 0x6c, 0x35, 0xa7, 0xfe, 0x15, 0x4c, 0xd5, 0x8c, 0x67, 0x3e, + 0xac, 0xf5, 0x1e, 0x47, 0x27, 0x7e, 0x95, 0xcc, 0x5e, 0x07, + 0xec, 0xb5, 0x9b, 0xc2, 0x29, 0x70, 0xe2, 0xbb, 0x50, 0x09, + 0x69, 0x30, 0xdb, 0x82, 0x10, 0x49, 0xa2, 0xfb, 0x62, 0x3b, + 0xd0, 0x89, 0x1b, 0x42, 0xa9, 0xf0, 0x90, 0xc9, 0x22, 0x7b, + 0xe9, 0xb0, 0x5b, 0x02, 0x74, 0x2d, 0xc6, 0x9f, 0x0d, 0x54, + 0xbf, 0xe6, 0x86, 0xdf, 0x34, 0x6d, 0xff, 0xa6, 0x4d, 0x14, + 0x8d, 0xd4, 0x3f, 0x66, 0xf4, 0xad, 0x46, 0x1f, 0x7f, 0x26, + 0xcd, 0x94, 0x06, 0x5f, 0xb4, 0xed, 0x58, 0x01, 0xea, 0xb3, + 0x21, 0x78, 0x93, 0xca, 0xaa, 0xf3, 0x18, 0x41, 0xd3, 0x8a, + 0x61, 0x38, 0xa1, 0xf8, 0x13, 0x4a, 0xd8, 0x81, 0x6a, 0x33, + 0x53, 0x0a, 0xe1, 0xb8, 0x2a, 0x73, 0x98, 0xc1, 0xb7, 0xee, + 0x05, 0x5c, 0xce, 0x97, 0x7c, 0x25, 0x45, 0x1c, 0xf7, 0xae, + 0x3c, 0x65, 0x8e, 0xd7, 0x4e, 0x17, 0xfc, 0xa5, 0x37, 0x6e, + 0x85, 0xdc, 0xbc, 0xe5, 0x0e, 0x57, 0xc5, 0x9c, 0x77, 0x2e, + 0x00, 0x5a, 0xb4, 0xee, 0x75, 0x2f, 0xc1, 0x9b, 0xea, 0xb0, + 0x5e, 0x04, 0x9f, 0xc5, 0x2b, 0x71, 0xc9, 0x93, 0x7d, 0x27, + 0xbc, 0xe6, 0x08, 0x52, 0x23, 0x79, 0x97, 0xcd, 0x56, 0x0c, + 0xe2, 0xb8, 0x8f, 0xd5, 0x3b, 0x61, 0xfa, 0xa0, 0x4e, 0x14, + 0x65, 0x3f, 0xd1, 0x8b, 0x10, 0x4a, 0xa4, 0xfe, 0x46, 0x1c, + 0xf2, 0xa8, 0x33, 0x69, 0x87, 0xdd, 0xac, 0xf6, 0x18, 0x42, + 0xd9, 0x83, 0x6d, 0x37, 0x03, 0x59, 0xb7, 0xed, 0x76, 0x2c, + 0xc2, 0x98, 0xe9, 0xb3, 0x5d, 0x07, 0x9c, 0xc6, 0x28, 0x72, + 0xca, 0x90, 0x7e, 0x24, 0xbf, 0xe5, 0x0b, 0x51, 0x20, 0x7a, + 0x94, 0xce, 0x55, 0x0f, 0xe1, 0xbb, 0x8c, 0xd6, 0x38, 0x62, + 0xf9, 0xa3, 0x4d, 0x17, 0x66, 0x3c, 0xd2, 0x88, 0x13, 0x49, + 0xa7, 0xfd, 0x45, 0x1f, 0xf1, 0xab, 0x30, 0x6a, 0x84, 0xde, + 0xaf, 0xf5, 0x1b, 0x41, 0xda, 0x80, 0x6e, 0x34, 0x06, 0x5c, + 0xb2, 0xe8, 0x73, 0x29, 0xc7, 0x9d, 0xec, 0xb6, 0x58, 0x02, + 0x99, 0xc3, 0x2d, 0x77, 0xcf, 0x95, 0x7b, 0x21, 0xba, 0xe0, + 0x0e, 0x54, 0x25, 0x7f, 0x91, 0xcb, 0x50, 0x0a, 0xe4, 0xbe, + 0x89, 0xd3, 0x3d, 0x67, 0xfc, 0xa6, 0x48, 0x12, 0x63, 0x39, + 0xd7, 0x8d, 0x16, 0x4c, 0xa2, 0xf8, 0x40, 0x1a, 0xf4, 0xae, + 0x35, 0x6f, 0x81, 0xdb, 0xaa, 0xf0, 0x1e, 0x44, 0xdf, 0x85, + 0x6b, 0x31, 0x05, 0x5f, 0xb1, 0xeb, 0x70, 0x2a, 0xc4, 0x9e, + 0xef, 0xb5, 0x5b, 0x01, 0x9a, 0xc0, 0x2e, 0x74, 0xcc, 0x96, + 0x78, 0x22, 0xb9, 0xe3, 0x0d, 0x57, 0x26, 0x7c, 0x92, 0xc8, + 0x53, 0x09, 0xe7, 0xbd, 0x8a, 0xd0, 0x3e, 0x64, 0xff, 0xa5, + 0x4b, 0x11, 0x60, 0x3a, 0xd4, 0x8e, 0x15, 0x4f, 0xa1, 0xfb, + 0x43, 0x19, 0xf7, 0xad, 0x36, 0x6c, 0x82, 0xd8, 0xa9, 0xf3, + 0x1d, 0x47, 0xdc, 0x86, 0x68, 0x32, 0x00, 0x5b, 0xb6, 0xed, + 0x71, 0x2a, 0xc7, 0x9c, 0xe2, 0xb9, 0x54, 0x0f, 0x93, 0xc8, + 0x25, 0x7e, 0xd9, 0x82, 0x6f, 0x34, 0xa8, 0xf3, 0x1e, 0x45, + 0x3b, 0x60, 0x8d, 0xd6, 0x4a, 0x11, 0xfc, 0xa7, 0xaf, 0xf4, + 0x19, 0x42, 0xde, 0x85, 0x68, 0x33, 0x4d, 0x16, 0xfb, 0xa0, + 0x3c, 0x67, 0x8a, 0xd1, 0x76, 0x2d, 0xc0, 0x9b, 0x07, 0x5c, + 0xb1, 0xea, 0x94, 0xcf, 0x22, 0x79, 0xe5, 0xbe, 0x53, 0x08, + 0x43, 0x18, 0xf5, 0xae, 0x32, 0x69, 0x84, 0xdf, 0xa1, 0xfa, + 0x17, 0x4c, 0xd0, 0x8b, 0x66, 0x3d, 0x9a, 0xc1, 0x2c, 0x77, + 0xeb, 0xb0, 0x5d, 0x06, 0x78, 0x23, 0xce, 0x95, 0x09, 0x52, + 0xbf, 0xe4, 0xec, 0xb7, 0x5a, 0x01, 0x9d, 0xc6, 0x2b, 0x70, + 0x0e, 0x55, 0xb8, 0xe3, 0x7f, 0x24, 0xc9, 0x92, 0x35, 0x6e, + 0x83, 0xd8, 0x44, 0x1f, 0xf2, 0xa9, 0xd7, 0x8c, 0x61, 0x3a, + 0xa6, 0xfd, 0x10, 0x4b, 0x86, 0xdd, 0x30, 0x6b, 0xf7, 0xac, + 0x41, 0x1a, 0x64, 0x3f, 0xd2, 0x89, 0x15, 0x4e, 0xa3, 0xf8, + 0x5f, 0x04, 0xe9, 0xb2, 0x2e, 0x75, 0x98, 0xc3, 0xbd, 0xe6, + 0x0b, 0x50, 0xcc, 0x97, 0x7a, 0x21, 0x29, 0x72, 0x9f, 0xc4, + 0x58, 0x03, 0xee, 0xb5, 0xcb, 0x90, 0x7d, 0x26, 0xba, 0xe1, + 0x0c, 0x57, 0xf0, 0xab, 0x46, 0x1d, 0x81, 0xda, 0x37, 0x6c, + 0x12, 0x49, 0xa4, 0xff, 0x63, 0x38, 0xd5, 0x8e, 0xc5, 0x9e, + 0x73, 0x28, 0xb4, 0xef, 0x02, 0x59, 0x27, 0x7c, 0x91, 0xca, + 0x56, 0x0d, 0xe0, 0xbb, 0x1c, 0x47, 0xaa, 0xf1, 0x6d, 0x36, + 0xdb, 0x80, 0xfe, 0xa5, 0x48, 0x13, 0x8f, 0xd4, 0x39, 0x62, + 0x6a, 0x31, 0xdc, 0x87, 0x1b, 0x40, 0xad, 0xf6, 0x88, 0xd3, + 0x3e, 0x65, 0xf9, 0xa2, 0x4f, 0x14, 0xb3, 0xe8, 0x05, 0x5e, + 0xc2, 0x99, 0x74, 0x2f, 0x51, 0x0a, 0xe7, 0xbc, 0x20, 0x7b, + 0x96, 0xcd, 0x00, 0x5c, 0xb8, 0xe4, 0x6d, 0x31, 0xd5, 0x89, + 0xda, 0x86, 0x62, 0x3e, 0xb7, 0xeb, 0x0f, 0x53, 0xa9, 0xf5, + 0x11, 0x4d, 0xc4, 0x98, 0x7c, 0x20, 0x73, 0x2f, 0xcb, 0x97, + 0x1e, 0x42, 0xa6, 0xfa, 0x4f, 0x13, 0xf7, 0xab, 0x22, 0x7e, + 0x9a, 0xc6, 0x95, 0xc9, 0x2d, 0x71, 0xf8, 0xa4, 0x40, 0x1c, + 0xe6, 0xba, 0x5e, 0x02, 0x8b, 0xd7, 0x33, 0x6f, 0x3c, 0x60, + 0x84, 0xd8, 0x51, 0x0d, 0xe9, 0xb5, 0x9e, 0xc2, 0x26, 0x7a, + 0xf3, 0xaf, 0x4b, 0x17, 0x44, 0x18, 0xfc, 0xa0, 0x29, 0x75, + 0x91, 0xcd, 0x37, 0x6b, 0x8f, 0xd3, 0x5a, 0x06, 0xe2, 0xbe, + 0xed, 0xb1, 0x55, 0x09, 0x80, 0xdc, 0x38, 0x64, 0xd1, 0x8d, + 0x69, 0x35, 0xbc, 0xe0, 0x04, 0x58, 0x0b, 0x57, 0xb3, 0xef, + 0x66, 0x3a, 0xde, 0x82, 0x78, 0x24, 0xc0, 0x9c, 0x15, 0x49, + 0xad, 0xf1, 0xa2, 0xfe, 0x1a, 0x46, 0xcf, 0x93, 0x77, 0x2b, + 0x21, 0x7d, 0x99, 0xc5, 0x4c, 0x10, 0xf4, 0xa8, 0xfb, 0xa7, + 0x43, 0x1f, 0x96, 0xca, 0x2e, 0x72, 0x88, 0xd4, 0x30, 0x6c, + 0xe5, 0xb9, 0x5d, 0x01, 0x52, 0x0e, 0xea, 0xb6, 0x3f, 0x63, + 0x87, 0xdb, 0x6e, 0x32, 0xd6, 0x8a, 0x03, 0x5f, 0xbb, 0xe7, + 0xb4, 0xe8, 0x0c, 0x50, 0xd9, 0x85, 0x61, 0x3d, 0xc7, 0x9b, + 0x7f, 0x23, 0xaa, 0xf6, 0x12, 0x4e, 0x1d, 0x41, 0xa5, 0xf9, + 0x70, 0x2c, 0xc8, 0x94, 0xbf, 0xe3, 0x07, 0x5b, 0xd2, 0x8e, + 0x6a, 0x36, 0x65, 0x39, 0xdd, 0x81, 0x08, 0x54, 0xb0, 0xec, + 0x16, 0x4a, 0xae, 0xf2, 0x7b, 0x27, 0xc3, 0x9f, 0xcc, 0x90, + 0x74, 0x28, 0xa1, 0xfd, 0x19, 0x45, 0xf0, 0xac, 0x48, 0x14, + 0x9d, 0xc1, 0x25, 0x79, 0x2a, 0x76, 0x92, 0xce, 0x47, 0x1b, + 0xff, 0xa3, 0x59, 0x05, 0xe1, 0xbd, 0x34, 0x68, 0x8c, 0xd0, + 0x83, 0xdf, 0x3b, 0x67, 0xee, 0xb2, 0x56, 0x0a, 0x00, 0x5d, + 0xba, 0xe7, 0x69, 0x34, 0xd3, 0x8e, 0xd2, 0x8f, 0x68, 0x35, + 0xbb, 0xe6, 0x01, 0x5c, 0xb9, 0xe4, 0x03, 0x5e, 0xd0, 0x8d, + 0x6a, 0x37, 0x6b, 0x36, 0xd1, 0x8c, 0x02, 0x5f, 0xb8, 0xe5, + 0x6f, 0x32, 0xd5, 0x88, 0x06, 0x5b, 0xbc, 0xe1, 0xbd, 0xe0, + 0x07, 0x5a, 0xd4, 0x89, 0x6e, 0x33, 0xd6, 0x8b, 0x6c, 0x31, + 0xbf, 0xe2, 0x05, 0x58, 0x04, 0x59, 0xbe, 0xe3, 0x6d, 0x30, + 0xd7, 0x8a, 0xde, 0x83, 0x64, 0x39, 0xb7, 0xea, 0x0d, 0x50, + 0x0c, 0x51, 0xb6, 0xeb, 0x65, 0x38, 0xdf, 0x82, 0x67, 0x3a, + 0xdd, 0x80, 0x0e, 0x53, 0xb4, 0xe9, 0xb5, 0xe8, 0x0f, 0x52, + 0xdc, 0x81, 0x66, 0x3b, 0xb1, 0xec, 0x0b, 0x56, 0xd8, 0x85, + 0x62, 0x3f, 0x63, 0x3e, 0xd9, 0x84, 0x0a, 0x57, 0xb0, 0xed, + 0x08, 0x55, 0xb2, 0xef, 0x61, 0x3c, 0xdb, 0x86, 0xda, 0x87, + 0x60, 0x3d, 0xb3, 0xee, 0x09, 0x54, 0xa1, 0xfc, 0x1b, 0x46, + 0xc8, 0x95, 0x72, 0x2f, 0x73, 0x2e, 0xc9, 0x94, 0x1a, 0x47, + 0xa0, 0xfd, 0x18, 0x45, 0xa2, 0xff, 0x71, 0x2c, 0xcb, 0x96, + 0xca, 0x97, 0x70, 0x2d, 0xa3, 0xfe, 0x19, 0x44, 0xce, 0x93, + 0x74, 0x29, 0xa7, 0xfa, 0x1d, 0x40, 0x1c, 0x41, 0xa6, 0xfb, + 0x75, 0x28, 0xcf, 0x92, 0x77, 0x2a, 0xcd, 0x90, 0x1e, 0x43, + 0xa4, 0xf9, 0xa5, 0xf8, 0x1f, 0x42, 0xcc, 0x91, 0x76, 0x2b, + 0x7f, 0x22, 0xc5, 0x98, 0x16, 0x4b, 0xac, 0xf1, 0xad, 0xf0, + 0x17, 0x4a, 0xc4, 0x99, 0x7e, 0x23, 0xc6, 0x9b, 0x7c, 0x21, + 0xaf, 0xf2, 0x15, 0x48, 0x14, 0x49, 0xae, 0xf3, 0x7d, 0x20, + 0xc7, 0x9a, 0x10, 0x4d, 0xaa, 0xf7, 0x79, 0x24, 0xc3, 0x9e, + 0xc2, 0x9f, 0x78, 0x25, 0xab, 0xf6, 0x11, 0x4c, 0xa9, 0xf4, + 0x13, 0x4e, 0xc0, 0x9d, 0x7a, 0x27, 0x7b, 0x26, 0xc1, 0x9c, + 0x12, 0x4f, 0xa8, 0xf5, 0x00, 0x5e, 0xbc, 0xe2, 0x65, 0x3b, + 0xd9, 0x87, 0xca, 0x94, 0x76, 0x28, 0xaf, 0xf1, 0x13, 0x4d, + 0x89, 0xd7, 0x35, 0x6b, 0xec, 0xb2, 0x50, 0x0e, 0x43, 0x1d, + 0xff, 0xa1, 0x26, 0x78, 0x9a, 0xc4, 0x0f, 0x51, 0xb3, 0xed, + 0x6a, 0x34, 0xd6, 0x88, 0xc5, 0x9b, 0x79, 0x27, 0xa0, 0xfe, + 0x1c, 0x42, 0x86, 0xd8, 0x3a, 0x64, 0xe3, 0xbd, 0x5f, 0x01, + 0x4c, 0x12, 0xf0, 0xae, 0x29, 0x77, 0x95, 0xcb, 0x1e, 0x40, + 0xa2, 0xfc, 0x7b, 0x25, 0xc7, 0x99, 0xd4, 0x8a, 0x68, 0x36, + 0xb1, 0xef, 0x0d, 0x53, 0x97, 0xc9, 0x2b, 0x75, 0xf2, 0xac, + 0x4e, 0x10, 0x5d, 0x03, 0xe1, 0xbf, 0x38, 0x66, 0x84, 0xda, + 0x11, 0x4f, 0xad, 0xf3, 0x74, 0x2a, 0xc8, 0x96, 0xdb, 0x85, + 0x67, 0x39, 0xbe, 0xe0, 0x02, 0x5c, 0x98, 0xc6, 0x24, 0x7a, + 0xfd, 0xa3, 0x41, 0x1f, 0x52, 0x0c, 0xee, 0xb0, 0x37, 0x69, + 0x8b, 0xd5, 0x3c, 0x62, 0x80, 0xde, 0x59, 0x07, 0xe5, 0xbb, + 0xf6, 0xa8, 0x4a, 0x14, 0x93, 0xcd, 0x2f, 0x71, 0xb5, 0xeb, + 0x09, 0x57, 0xd0, 0x8e, 0x6c, 0x32, 0x7f, 0x21, 0xc3, 0x9d, + 0x1a, 0x44, 0xa6, 0xf8, 0x33, 0x6d, 0x8f, 0xd1, 0x56, 0x08, + 0xea, 0xb4, 0xf9, 0xa7, 0x45, 0x1b, 0x9c, 0xc2, 0x20, 0x7e, + 0xba, 0xe4, 0x06, 0x58, 0xdf, 0x81, 0x63, 0x3d, 0x70, 0x2e, + 0xcc, 0x92, 0x15, 0x4b, 0xa9, 0xf7, 0x22, 0x7c, 0x9e, 0xc0, + 0x47, 0x19, 0xfb, 0xa5, 0xe8, 0xb6, 0x54, 0x0a, 0x8d, 0xd3, + 0x31, 0x6f, 0xab, 0xf5, 0x17, 0x49, 0xce, 0x90, 0x72, 0x2c, + 0x61, 0x3f, 0xdd, 0x83, 0x04, 0x5a, 0xb8, 0xe6, 0x2d, 0x73, + 0x91, 0xcf, 0x48, 0x16, 0xf4, 0xaa, 0xe7, 0xb9, 0x5b, 0x05, + 0x82, 0xdc, 0x3e, 0x60, 0xa4, 0xfa, 0x18, 0x46, 0xc1, 0x9f, + 0x7d, 0x23, 0x6e, 0x30, 0xd2, 0x8c, 0x0b, 0x55, 0xb7, 0xe9, + 0x00, 0x5f, 0xbe, 0xe1, 0x61, 0x3e, 0xdf, 0x80, 0xc2, 0x9d, + 0x7c, 0x23, 0xa3, 0xfc, 0x1d, 0x42, 0x99, 0xc6, 0x27, 0x78, + 0xf8, 0xa7, 0x46, 0x19, 0x5b, 0x04, 0xe5, 0xba, 0x3a, 0x65, + 0x84, 0xdb, 0x2f, 0x70, 0x91, 0xce, 0x4e, 0x11, 0xf0, 0xaf, + 0xed, 0xb2, 0x53, 0x0c, 0x8c, 0xd3, 0x32, 0x6d, 0xb6, 0xe9, + 0x08, 0x57, 0xd7, 0x88, 0x69, 0x36, 0x74, 0x2b, 0xca, 0x95, + 0x15, 0x4a, 0xab, 0xf4, 0x5e, 0x01, 0xe0, 0xbf, 0x3f, 0x60, + 0x81, 0xde, 0x9c, 0xc3, 0x22, 0x7d, 0xfd, 0xa2, 0x43, 0x1c, + 0xc7, 0x98, 0x79, 0x26, 0xa6, 0xf9, 0x18, 0x47, 0x05, 0x5a, + 0xbb, 0xe4, 0x64, 0x3b, 0xda, 0x85, 0x71, 0x2e, 0xcf, 0x90, + 0x10, 0x4f, 0xae, 0xf1, 0xb3, 0xec, 0x0d, 0x52, 0xd2, 0x8d, + 0x6c, 0x33, 0xe8, 0xb7, 0x56, 0x09, 0x89, 0xd6, 0x37, 0x68, + 0x2a, 0x75, 0x94, 0xcb, 0x4b, 0x14, 0xf5, 0xaa, 0xbc, 0xe3, + 0x02, 0x5d, 0xdd, 0x82, 0x63, 0x3c, 0x7e, 0x21, 0xc0, 0x9f, + 0x1f, 0x40, 0xa1, 0xfe, 0x25, 0x7a, 0x9b, 0xc4, 0x44, 0x1b, + 0xfa, 0xa5, 0xe7, 0xb8, 0x59, 0x06, 0x86, 0xd9, 0x38, 0x67, + 0x93, 0xcc, 0x2d, 0x72, 0xf2, 0xad, 0x4c, 0x13, 0x51, 0x0e, + 0xef, 0xb0, 0x30, 0x6f, 0x8e, 0xd1, 0x0a, 0x55, 0xb4, 0xeb, + 0x6b, 0x34, 0xd5, 0x8a, 0xc8, 0x97, 0x76, 0x29, 0xa9, 0xf6, + 0x17, 0x48, 0xe2, 0xbd, 0x5c, 0x03, 0x83, 0xdc, 0x3d, 0x62, + 0x20, 0x7f, 0x9e, 0xc1, 0x41, 0x1e, 0xff, 0xa0, 0x7b, 0x24, + 0xc5, 0x9a, 0x1a, 0x45, 0xa4, 0xfb, 0xb9, 0xe6, 0x07, 0x58, + 0xd8, 0x87, 0x66, 0x39, 0xcd, 0x92, 0x73, 0x2c, 0xac, 0xf3, + 0x12, 0x4d, 0x0f, 0x50, 0xb1, 0xee, 0x6e, 0x31, 0xd0, 0x8f, + 0x54, 0x0b, 0xea, 0xb5, 0x35, 0x6a, 0x8b, 0xd4, 0x96, 0xc9, + 0x28, 0x77, 0xf7, 0xa8, 0x49, 0x16, 0x00, 0x60, 0xc0, 0xa0, + 0x9d, 0xfd, 0x5d, 0x3d, 0x27, 0x47, 0xe7, 0x87, 0xba, 0xda, + 0x7a, 0x1a, 0x4e, 0x2e, 0x8e, 0xee, 0xd3, 0xb3, 0x13, 0x73, + 0x69, 0x09, 0xa9, 0xc9, 0xf4, 0x94, 0x34, 0x54, 0x9c, 0xfc, + 0x5c, 0x3c, 0x01, 0x61, 0xc1, 0xa1, 0xbb, 0xdb, 0x7b, 0x1b, + 0x26, 0x46, 0xe6, 0x86, 0xd2, 0xb2, 0x12, 0x72, 0x4f, 0x2f, + 0x8f, 0xef, 0xf5, 0x95, 0x35, 0x55, 0x68, 0x08, 0xa8, 0xc8, + 0x25, 0x45, 0xe5, 0x85, 0xb8, 0xd8, 0x78, 0x18, 0x02, 0x62, + 0xc2, 0xa2, 0x9f, 0xff, 0x5f, 0x3f, 0x6b, 0x0b, 0xab, 0xcb, + 0xf6, 0x96, 0x36, 0x56, 0x4c, 0x2c, 0x8c, 0xec, 0xd1, 0xb1, + 0x11, 0x71, 0xb9, 0xd9, 0x79, 0x19, 0x24, 0x44, 0xe4, 0x84, + 0x9e, 0xfe, 0x5e, 0x3e, 0x03, 0x63, 0xc3, 0xa3, 0xf7, 0x97, + 0x37, 0x57, 0x6a, 0x0a, 0xaa, 0xca, 0xd0, 0xb0, 0x10, 0x70, + 0x4d, 0x2d, 0x8d, 0xed, 0x4a, 0x2a, 0x8a, 0xea, 0xd7, 0xb7, + 0x17, 0x77, 0x6d, 0x0d, 0xad, 0xcd, 0xf0, 0x90, 0x30, 0x50, + 0x04, 0x64, 0xc4, 0xa4, 0x99, 0xf9, 0x59, 0x39, 0x23, 0x43, + 0xe3, 0x83, 0xbe, 0xde, 0x7e, 0x1e, 0xd6, 0xb6, 0x16, 0x76, + 0x4b, 0x2b, 0x8b, 0xeb, 0xf1, 0x91, 0x31, 0x51, 0x6c, 0x0c, + 0xac, 0xcc, 0x98, 0xf8, 0x58, 0x38, 0x05, 0x65, 0xc5, 0xa5, + 0xbf, 0xdf, 0x7f, 0x1f, 0x22, 0x42, 0xe2, 0x82, 0x6f, 0x0f, + 0xaf, 0xcf, 0xf2, 0x92, 0x32, 0x52, 0x48, 0x28, 0x88, 0xe8, + 0xd5, 0xb5, 0x15, 0x75, 0x21, 0x41, 0xe1, 0x81, 0xbc, 0xdc, + 0x7c, 0x1c, 0x06, 0x66, 0xc6, 0xa6, 0x9b, 0xfb, 0x5b, 0x3b, + 0xf3, 0x93, 0x33, 0x53, 0x6e, 0x0e, 0xae, 0xce, 0xd4, 0xb4, + 0x14, 0x74, 0x49, 0x29, 0x89, 0xe9, 0xbd, 0xdd, 0x7d, 0x1d, + 0x20, 0x40, 0xe0, 0x80, 0x9a, 0xfa, 0x5a, 0x3a, 0x07, 0x67, + 0xc7, 0xa7, 0x00, 0x61, 0xc2, 0xa3, 0x99, 0xf8, 0x5b, 0x3a, + 0x2f, 0x4e, 0xed, 0x8c, 0xb6, 0xd7, 0x74, 0x15, 0x5e, 0x3f, + 0x9c, 0xfd, 0xc7, 0xa6, 0x05, 0x64, 0x71, 0x10, 0xb3, 0xd2, + 0xe8, 0x89, 0x2a, 0x4b, 0xbc, 0xdd, 0x7e, 0x1f, 0x25, 0x44, + 0xe7, 0x86, 0x93, 0xf2, 0x51, 0x30, 0x0a, 0x6b, 0xc8, 0xa9, + 0xe2, 0x83, 0x20, 0x41, 0x7b, 0x1a, 0xb9, 0xd8, 0xcd, 0xac, + 0x0f, 0x6e, 0x54, 0x35, 0x96, 0xf7, 0x65, 0x04, 0xa7, 0xc6, + 0xfc, 0x9d, 0x3e, 0x5f, 0x4a, 0x2b, 0x88, 0xe9, 0xd3, 0xb2, + 0x11, 0x70, 0x3b, 0x5a, 0xf9, 0x98, 0xa2, 0xc3, 0x60, 0x01, + 0x14, 0x75, 0xd6, 0xb7, 0x8d, 0xec, 0x4f, 0x2e, 0xd9, 0xb8, + 0x1b, 0x7a, 0x40, 0x21, 0x82, 0xe3, 0xf6, 0x97, 0x34, 0x55, + 0x6f, 0x0e, 0xad, 0xcc, 0x87, 0xe6, 0x45, 0x24, 0x1e, 0x7f, + 0xdc, 0xbd, 0xa8, 0xc9, 0x6a, 0x0b, 0x31, 0x50, 0xf3, 0x92, + 0xca, 0xab, 0x08, 0x69, 0x53, 0x32, 0x91, 0xf0, 0xe5, 0x84, + 0x27, 0x46, 0x7c, 0x1d, 0xbe, 0xdf, 0x94, 0xf5, 0x56, 0x37, + 0x0d, 0x6c, 0xcf, 0xae, 0xbb, 0xda, 0x79, 0x18, 0x22, 0x43, + 0xe0, 0x81, 0x76, 0x17, 0xb4, 0xd5, 0xef, 0x8e, 0x2d, 0x4c, + 0x59, 0x38, 0x9b, 0xfa, 0xc0, 0xa1, 0x02, 0x63, 0x28, 0x49, + 0xea, 0x8b, 0xb1, 0xd0, 0x73, 0x12, 0x07, 0x66, 0xc5, 0xa4, + 0x9e, 0xff, 0x5c, 0x3d, 0xaf, 0xce, 0x6d, 0x0c, 0x36, 0x57, + 0xf4, 0x95, 0x80, 0xe1, 0x42, 0x23, 0x19, 0x78, 0xdb, 0xba, + 0xf1, 0x90, 0x33, 0x52, 0x68, 0x09, 0xaa, 0xcb, 0xde, 0xbf, + 0x1c, 0x7d, 0x47, 0x26, 0x85, 0xe4, 0x13, 0x72, 0xd1, 0xb0, + 0x8a, 0xeb, 0x48, 0x29, 0x3c, 0x5d, 0xfe, 0x9f, 0xa5, 0xc4, + 0x67, 0x06, 0x4d, 0x2c, 0x8f, 0xee, 0xd4, 0xb5, 0x16, 0x77, + 0x62, 0x03, 0xa0, 0xc1, 0xfb, 0x9a, 0x39, 0x58, 0x00, 0x62, + 0xc4, 0xa6, 0x95, 0xf7, 0x51, 0x33, 0x37, 0x55, 0xf3, 0x91, + 0xa2, 0xc0, 0x66, 0x04, 0x6e, 0x0c, 0xaa, 0xc8, 0xfb, 0x99, + 0x3f, 0x5d, 0x59, 0x3b, 0x9d, 0xff, 0xcc, 0xae, 0x08, 0x6a, + 0xdc, 0xbe, 0x18, 0x7a, 0x49, 0x2b, 0x8d, 0xef, 0xeb, 0x89, + 0x2f, 0x4d, 0x7e, 0x1c, 0xba, 0xd8, 0xb2, 0xd0, 0x76, 0x14, + 0x27, 0x45, 0xe3, 0x81, 0x85, 0xe7, 0x41, 0x23, 0x10, 0x72, + 0xd4, 0xb6, 0xa5, 0xc7, 0x61, 0x03, 0x30, 0x52, 0xf4, 0x96, + 0x92, 0xf0, 0x56, 0x34, 0x07, 0x65, 0xc3, 0xa1, 0xcb, 0xa9, + 0x0f, 0x6d, 0x5e, 0x3c, 0x9a, 0xf8, 0xfc, 0x9e, 0x38, 0x5a, + 0x69, 0x0b, 0xad, 0xcf, 0x79, 0x1b, 0xbd, 0xdf, 0xec, 0x8e, + 0x28, 0x4a, 0x4e, 0x2c, 0x8a, 0xe8, 0xdb, 0xb9, 0x1f, 0x7d, + 0x17, 0x75, 0xd3, 0xb1, 0x82, 0xe0, 0x46, 0x24, 0x20, 0x42, + 0xe4, 0x86, 0xb5, 0xd7, 0x71, 0x13, 0x57, 0x35, 0x93, 0xf1, + 0xc2, 0xa0, 0x06, 0x64, 0x60, 0x02, 0xa4, 0xc6, 0xf5, 0x97, + 0x31, 0x53, 0x39, 0x5b, 0xfd, 0x9f, 0xac, 0xce, 0x68, 0x0a, + 0x0e, 0x6c, 0xca, 0xa8, 0x9b, 0xf9, 0x5f, 0x3d, 0x8b, 0xe9, + 0x4f, 0x2d, 0x1e, 0x7c, 0xda, 0xb8, 0xbc, 0xde, 0x78, 0x1a, + 0x29, 0x4b, 0xed, 0x8f, 0xe5, 0x87, 0x21, 0x43, 0x70, 0x12, + 0xb4, 0xd6, 0xd2, 0xb0, 0x16, 0x74, 0x47, 0x25, 0x83, 0xe1, + 0xf2, 0x90, 0x36, 0x54, 0x67, 0x05, 0xa3, 0xc1, 0xc5, 0xa7, + 0x01, 0x63, 0x50, 0x32, 0x94, 0xf6, 0x9c, 0xfe, 0x58, 0x3a, + 0x09, 0x6b, 0xcd, 0xaf, 0xab, 0xc9, 0x6f, 0x0d, 0x3e, 0x5c, + 0xfa, 0x98, 0x2e, 0x4c, 0xea, 0x88, 0xbb, 0xd9, 0x7f, 0x1d, + 0x19, 0x7b, 0xdd, 0xbf, 0x8c, 0xee, 0x48, 0x2a, 0x40, 0x22, + 0x84, 0xe6, 0xd5, 0xb7, 0x11, 0x73, 0x77, 0x15, 0xb3, 0xd1, + 0xe2, 0x80, 0x26, 0x44, 0x00, 0x63, 0xc6, 0xa5, 0x91, 0xf2, + 0x57, 0x34, 0x3f, 0x5c, 0xf9, 0x9a, 0xae, 0xcd, 0x68, 0x0b, + 0x7e, 0x1d, 0xb8, 0xdb, 0xef, 0x8c, 0x29, 0x4a, 0x41, 0x22, + 0x87, 0xe4, 0xd0, 0xb3, 0x16, 0x75, 0xfc, 0x9f, 0x3a, 0x59, + 0x6d, 0x0e, 0xab, 0xc8, 0xc3, 0xa0, 0x05, 0x66, 0x52, 0x31, + 0x94, 0xf7, 0x82, 0xe1, 0x44, 0x27, 0x13, 0x70, 0xd5, 0xb6, + 0xbd, 0xde, 0x7b, 0x18, 0x2c, 0x4f, 0xea, 0x89, 0xe5, 0x86, + 0x23, 0x40, 0x74, 0x17, 0xb2, 0xd1, 0xda, 0xb9, 0x1c, 0x7f, + 0x4b, 0x28, 0x8d, 0xee, 0x9b, 0xf8, 0x5d, 0x3e, 0x0a, 0x69, + 0xcc, 0xaf, 0xa4, 0xc7, 0x62, 0x01, 0x35, 0x56, 0xf3, 0x90, + 0x19, 0x7a, 0xdf, 0xbc, 0x88, 0xeb, 0x4e, 0x2d, 0x26, 0x45, + 0xe0, 0x83, 0xb7, 0xd4, 0x71, 0x12, 0x67, 0x04, 0xa1, 0xc2, + 0xf6, 0x95, 0x30, 0x53, 0x58, 0x3b, 0x9e, 0xfd, 0xc9, 0xaa, + 0x0f, 0x6c, 0xd7, 0xb4, 0x11, 0x72, 0x46, 0x25, 0x80, 0xe3, + 0xe8, 0x8b, 0x2e, 0x4d, 0x79, 0x1a, 0xbf, 0xdc, 0xa9, 0xca, + 0x6f, 0x0c, 0x38, 0x5b, 0xfe, 0x9d, 0x96, 0xf5, 0x50, 0x33, + 0x07, 0x64, 0xc1, 0xa2, 0x2b, 0x48, 0xed, 0x8e, 0xba, 0xd9, + 0x7c, 0x1f, 0x14, 0x77, 0xd2, 0xb1, 0x85, 0xe6, 0x43, 0x20, + 0x55, 0x36, 0x93, 0xf0, 0xc4, 0xa7, 0x02, 0x61, 0x6a, 0x09, + 0xac, 0xcf, 0xfb, 0x98, 0x3d, 0x5e, 0x32, 0x51, 0xf4, 0x97, + 0xa3, 0xc0, 0x65, 0x06, 0x0d, 0x6e, 0xcb, 0xa8, 0x9c, 0xff, + 0x5a, 0x39, 0x4c, 0x2f, 0x8a, 0xe9, 0xdd, 0xbe, 0x1b, 0x78, + 0x73, 0x10, 0xb5, 0xd6, 0xe2, 0x81, 0x24, 0x47, 0xce, 0xad, + 0x08, 0x6b, 0x5f, 0x3c, 0x99, 0xfa, 0xf1, 0x92, 0x37, 0x54, + 0x60, 0x03, 0xa6, 0xc5, 0xb0, 0xd3, 0x76, 0x15, 0x21, 0x42, + 0xe7, 0x84, 0x8f, 0xec, 0x49, 0x2a, 0x1e, 0x7d, 0xd8, 0xbb, + 0x00, 0x64, 0xc8, 0xac, 0x8d, 0xe9, 0x45, 0x21, 0x07, 0x63, + 0xcf, 0xab, 0x8a, 0xee, 0x42, 0x26, 0x0e, 0x6a, 0xc6, 0xa2, + 0x83, 0xe7, 0x4b, 0x2f, 0x09, 0x6d, 0xc1, 0xa5, 0x84, 0xe0, + 0x4c, 0x28, 0x1c, 0x78, 0xd4, 0xb0, 0x91, 0xf5, 0x59, 0x3d, + 0x1b, 0x7f, 0xd3, 0xb7, 0x96, 0xf2, 0x5e, 0x3a, 0x12, 0x76, + 0xda, 0xbe, 0x9f, 0xfb, 0x57, 0x33, 0x15, 0x71, 0xdd, 0xb9, + 0x98, 0xfc, 0x50, 0x34, 0x38, 0x5c, 0xf0, 0x94, 0xb5, 0xd1, + 0x7d, 0x19, 0x3f, 0x5b, 0xf7, 0x93, 0xb2, 0xd6, 0x7a, 0x1e, + 0x36, 0x52, 0xfe, 0x9a, 0xbb, 0xdf, 0x73, 0x17, 0x31, 0x55, + 0xf9, 0x9d, 0xbc, 0xd8, 0x74, 0x10, 0x24, 0x40, 0xec, 0x88, + 0xa9, 0xcd, 0x61, 0x05, 0x23, 0x47, 0xeb, 0x8f, 0xae, 0xca, + 0x66, 0x02, 0x2a, 0x4e, 0xe2, 0x86, 0xa7, 0xc3, 0x6f, 0x0b, + 0x2d, 0x49, 0xe5, 0x81, 0xa0, 0xc4, 0x68, 0x0c, 0x70, 0x14, + 0xb8, 0xdc, 0xfd, 0x99, 0x35, 0x51, 0x77, 0x13, 0xbf, 0xdb, + 0xfa, 0x9e, 0x32, 0x56, 0x7e, 0x1a, 0xb6, 0xd2, 0xf3, 0x97, + 0x3b, 0x5f, 0x79, 0x1d, 0xb1, 0xd5, 0xf4, 0x90, 0x3c, 0x58, + 0x6c, 0x08, 0xa4, 0xc0, 0xe1, 0x85, 0x29, 0x4d, 0x6b, 0x0f, + 0xa3, 0xc7, 0xe6, 0x82, 0x2e, 0x4a, 0x62, 0x06, 0xaa, 0xce, + 0xef, 0x8b, 0x27, 0x43, 0x65, 0x01, 0xad, 0xc9, 0xe8, 0x8c, + 0x20, 0x44, 0x48, 0x2c, 0x80, 0xe4, 0xc5, 0xa1, 0x0d, 0x69, + 0x4f, 0x2b, 0x87, 0xe3, 0xc2, 0xa6, 0x0a, 0x6e, 0x46, 0x22, + 0x8e, 0xea, 0xcb, 0xaf, 0x03, 0x67, 0x41, 0x25, 0x89, 0xed, + 0xcc, 0xa8, 0x04, 0x60, 0x54, 0x30, 0x9c, 0xf8, 0xd9, 0xbd, + 0x11, 0x75, 0x53, 0x37, 0x9b, 0xff, 0xde, 0xba, 0x16, 0x72, + 0x5a, 0x3e, 0x92, 0xf6, 0xd7, 0xb3, 0x1f, 0x7b, 0x5d, 0x39, + 0x95, 0xf1, 0xd0, 0xb4, 0x18, 0x7c, 0x00, 0x65, 0xca, 0xaf, + 0x89, 0xec, 0x43, 0x26, 0x0f, 0x6a, 0xc5, 0xa0, 0x86, 0xe3, + 0x4c, 0x29, 0x1e, 0x7b, 0xd4, 0xb1, 0x97, 0xf2, 0x5d, 0x38, + 0x11, 0x74, 0xdb, 0xbe, 0x98, 0xfd, 0x52, 0x37, 0x3c, 0x59, + 0xf6, 0x93, 0xb5, 0xd0, 0x7f, 0x1a, 0x33, 0x56, 0xf9, 0x9c, + 0xba, 0xdf, 0x70, 0x15, 0x22, 0x47, 0xe8, 0x8d, 0xab, 0xce, + 0x61, 0x04, 0x2d, 0x48, 0xe7, 0x82, 0xa4, 0xc1, 0x6e, 0x0b, + 0x78, 0x1d, 0xb2, 0xd7, 0xf1, 0x94, 0x3b, 0x5e, 0x77, 0x12, + 0xbd, 0xd8, 0xfe, 0x9b, 0x34, 0x51, 0x66, 0x03, 0xac, 0xc9, + 0xef, 0x8a, 0x25, 0x40, 0x69, 0x0c, 0xa3, 0xc6, 0xe0, 0x85, + 0x2a, 0x4f, 0x44, 0x21, 0x8e, 0xeb, 0xcd, 0xa8, 0x07, 0x62, + 0x4b, 0x2e, 0x81, 0xe4, 0xc2, 0xa7, 0x08, 0x6d, 0x5a, 0x3f, + 0x90, 0xf5, 0xd3, 0xb6, 0x19, 0x7c, 0x55, 0x30, 0x9f, 0xfa, + 0xdc, 0xb9, 0x16, 0x73, 0xf0, 0x95, 0x3a, 0x5f, 0x79, 0x1c, + 0xb3, 0xd6, 0xff, 0x9a, 0x35, 0x50, 0x76, 0x13, 0xbc, 0xd9, + 0xee, 0x8b, 0x24, 0x41, 0x67, 0x02, 0xad, 0xc8, 0xe1, 0x84, + 0x2b, 0x4e, 0x68, 0x0d, 0xa2, 0xc7, 0xcc, 0xa9, 0x06, 0x63, + 0x45, 0x20, 0x8f, 0xea, 0xc3, 0xa6, 0x09, 0x6c, 0x4a, 0x2f, + 0x80, 0xe5, 0xd2, 0xb7, 0x18, 0x7d, 0x5b, 0x3e, 0x91, 0xf4, + 0xdd, 0xb8, 0x17, 0x72, 0x54, 0x31, 0x9e, 0xfb, 0x88, 0xed, + 0x42, 0x27, 0x01, 0x64, 0xcb, 0xae, 0x87, 0xe2, 0x4d, 0x28, + 0x0e, 0x6b, 0xc4, 0xa1, 0x96, 0xf3, 0x5c, 0x39, 0x1f, 0x7a, + 0xd5, 0xb0, 0x99, 0xfc, 0x53, 0x36, 0x10, 0x75, 0xda, 0xbf, + 0xb4, 0xd1, 0x7e, 0x1b, 0x3d, 0x58, 0xf7, 0x92, 0xbb, 0xde, + 0x71, 0x14, 0x32, 0x57, 0xf8, 0x9d, 0xaa, 0xcf, 0x60, 0x05, + 0x23, 0x46, 0xe9, 0x8c, 0xa5, 0xc0, 0x6f, 0x0a, 0x2c, 0x49, + 0xe6, 0x83, 0x00, 0x66, 0xcc, 0xaa, 0x85, 0xe3, 0x49, 0x2f, + 0x17, 0x71, 0xdb, 0xbd, 0x92, 0xf4, 0x5e, 0x38, 0x2e, 0x48, + 0xe2, 0x84, 0xab, 0xcd, 0x67, 0x01, 0x39, 0x5f, 0xf5, 0x93, + 0xbc, 0xda, 0x70, 0x16, 0x5c, 0x3a, 0x90, 0xf6, 0xd9, 0xbf, + 0x15, 0x73, 0x4b, 0x2d, 0x87, 0xe1, 0xce, 0xa8, 0x02, 0x64, + 0x72, 0x14, 0xbe, 0xd8, 0xf7, 0x91, 0x3b, 0x5d, 0x65, 0x03, + 0xa9, 0xcf, 0xe0, 0x86, 0x2c, 0x4a, 0xb8, 0xde, 0x74, 0x12, + 0x3d, 0x5b, 0xf1, 0x97, 0xaf, 0xc9, 0x63, 0x05, 0x2a, 0x4c, + 0xe6, 0x80, 0x96, 0xf0, 0x5a, 0x3c, 0x13, 0x75, 0xdf, 0xb9, + 0x81, 0xe7, 0x4d, 0x2b, 0x04, 0x62, 0xc8, 0xae, 0xe4, 0x82, + 0x28, 0x4e, 0x61, 0x07, 0xad, 0xcb, 0xf3, 0x95, 0x3f, 0x59, + 0x76, 0x10, 0xba, 0xdc, 0xca, 0xac, 0x06, 0x60, 0x4f, 0x29, + 0x83, 0xe5, 0xdd, 0xbb, 0x11, 0x77, 0x58, 0x3e, 0x94, 0xf2, + 0x6d, 0x0b, 0xa1, 0xc7, 0xe8, 0x8e, 0x24, 0x42, 0x7a, 0x1c, + 0xb6, 0xd0, 0xff, 0x99, 0x33, 0x55, 0x43, 0x25, 0x8f, 0xe9, + 0xc6, 0xa0, 0x0a, 0x6c, 0x54, 0x32, 0x98, 0xfe, 0xd1, 0xb7, + 0x1d, 0x7b, 0x31, 0x57, 0xfd, 0x9b, 0xb4, 0xd2, 0x78, 0x1e, + 0x26, 0x40, 0xea, 0x8c, 0xa3, 0xc5, 0x6f, 0x09, 0x1f, 0x79, + 0xd3, 0xb5, 0x9a, 0xfc, 0x56, 0x30, 0x08, 0x6e, 0xc4, 0xa2, + 0x8d, 0xeb, 0x41, 0x27, 0xd5, 0xb3, 0x19, 0x7f, 0x50, 0x36, + 0x9c, 0xfa, 0xc2, 0xa4, 0x0e, 0x68, 0x47, 0x21, 0x8b, 0xed, + 0xfb, 0x9d, 0x37, 0x51, 0x7e, 0x18, 0xb2, 0xd4, 0xec, 0x8a, + 0x20, 0x46, 0x69, 0x0f, 0xa5, 0xc3, 0x89, 0xef, 0x45, 0x23, + 0x0c, 0x6a, 0xc0, 0xa6, 0x9e, 0xf8, 0x52, 0x34, 0x1b, 0x7d, + 0xd7, 0xb1, 0xa7, 0xc1, 0x6b, 0x0d, 0x22, 0x44, 0xee, 0x88, + 0xb0, 0xd6, 0x7c, 0x1a, 0x35, 0x53, 0xf9, 0x9f, 0x00, 0x67, + 0xce, 0xa9, 0x81, 0xe6, 0x4f, 0x28, 0x1f, 0x78, 0xd1, 0xb6, + 0x9e, 0xf9, 0x50, 0x37, 0x3e, 0x59, 0xf0, 0x97, 0xbf, 0xd8, + 0x71, 0x16, 0x21, 0x46, 0xef, 0x88, 0xa0, 0xc7, 0x6e, 0x09, + 0x7c, 0x1b, 0xb2, 0xd5, 0xfd, 0x9a, 0x33, 0x54, 0x63, 0x04, + 0xad, 0xca, 0xe2, 0x85, 0x2c, 0x4b, 0x42, 0x25, 0x8c, 0xeb, + 0xc3, 0xa4, 0x0d, 0x6a, 0x5d, 0x3a, 0x93, 0xf4, 0xdc, 0xbb, + 0x12, 0x75, 0xf8, 0x9f, 0x36, 0x51, 0x79, 0x1e, 0xb7, 0xd0, + 0xe7, 0x80, 0x29, 0x4e, 0x66, 0x01, 0xa8, 0xcf, 0xc6, 0xa1, + 0x08, 0x6f, 0x47, 0x20, 0x89, 0xee, 0xd9, 0xbe, 0x17, 0x70, + 0x58, 0x3f, 0x96, 0xf1, 0x84, 0xe3, 0x4a, 0x2d, 0x05, 0x62, + 0xcb, 0xac, 0x9b, 0xfc, 0x55, 0x32, 0x1a, 0x7d, 0xd4, 0xb3, + 0xba, 0xdd, 0x74, 0x13, 0x3b, 0x5c, 0xf5, 0x92, 0xa5, 0xc2, + 0x6b, 0x0c, 0x24, 0x43, 0xea, 0x8d, 0xed, 0x8a, 0x23, 0x44, + 0x6c, 0x0b, 0xa2, 0xc5, 0xf2, 0x95, 0x3c, 0x5b, 0x73, 0x14, + 0xbd, 0xda, 0xd3, 0xb4, 0x1d, 0x7a, 0x52, 0x35, 0x9c, 0xfb, + 0xcc, 0xab, 0x02, 0x65, 0x4d, 0x2a, 0x83, 0xe4, 0x91, 0xf6, + 0x5f, 0x38, 0x10, 0x77, 0xde, 0xb9, 0x8e, 0xe9, 0x40, 0x27, + 0x0f, 0x68, 0xc1, 0xa6, 0xaf, 0xc8, 0x61, 0x06, 0x2e, 0x49, + 0xe0, 0x87, 0xb0, 0xd7, 0x7e, 0x19, 0x31, 0x56, 0xff, 0x98, + 0x15, 0x72, 0xdb, 0xbc, 0x94, 0xf3, 0x5a, 0x3d, 0x0a, 0x6d, + 0xc4, 0xa3, 0x8b, 0xec, 0x45, 0x22, 0x2b, 0x4c, 0xe5, 0x82, + 0xaa, 0xcd, 0x64, 0x03, 0x34, 0x53, 0xfa, 0x9d, 0xb5, 0xd2, + 0x7b, 0x1c, 0x69, 0x0e, 0xa7, 0xc0, 0xe8, 0x8f, 0x26, 0x41, + 0x76, 0x11, 0xb8, 0xdf, 0xf7, 0x90, 0x39, 0x5e, 0x57, 0x30, + 0x99, 0xfe, 0xd6, 0xb1, 0x18, 0x7f, 0x48, 0x2f, 0x86, 0xe1, + 0xc9, 0xae, 0x07, 0x60, 0x00, 0x68, 0xd0, 0xb8, 0xbd, 0xd5, + 0x6d, 0x05, 0x67, 0x0f, 0xb7, 0xdf, 0xda, 0xb2, 0x0a, 0x62, + 0xce, 0xa6, 0x1e, 0x76, 0x73, 0x1b, 0xa3, 0xcb, 0xa9, 0xc1, + 0x79, 0x11, 0x14, 0x7c, 0xc4, 0xac, 0x81, 0xe9, 0x51, 0x39, + 0x3c, 0x54, 0xec, 0x84, 0xe6, 0x8e, 0x36, 0x5e, 0x5b, 0x33, + 0x8b, 0xe3, 0x4f, 0x27, 0x9f, 0xf7, 0xf2, 0x9a, 0x22, 0x4a, + 0x28, 0x40, 0xf8, 0x90, 0x95, 0xfd, 0x45, 0x2d, 0x1f, 0x77, + 0xcf, 0xa7, 0xa2, 0xca, 0x72, 0x1a, 0x78, 0x10, 0xa8, 0xc0, + 0xc5, 0xad, 0x15, 0x7d, 0xd1, 0xb9, 0x01, 0x69, 0x6c, 0x04, + 0xbc, 0xd4, 0xb6, 0xde, 0x66, 0x0e, 0x0b, 0x63, 0xdb, 0xb3, + 0x9e, 0xf6, 0x4e, 0x26, 0x23, 0x4b, 0xf3, 0x9b, 0xf9, 0x91, + 0x29, 0x41, 0x44, 0x2c, 0x94, 0xfc, 0x50, 0x38, 0x80, 0xe8, + 0xed, 0x85, 0x3d, 0x55, 0x37, 0x5f, 0xe7, 0x8f, 0x8a, 0xe2, + 0x5a, 0x32, 0x3e, 0x56, 0xee, 0x86, 0x83, 0xeb, 0x53, 0x3b, + 0x59, 0x31, 0x89, 0xe1, 0xe4, 0x8c, 0x34, 0x5c, 0xf0, 0x98, + 0x20, 0x48, 0x4d, 0x25, 0x9d, 0xf5, 0x97, 0xff, 0x47, 0x2f, + 0x2a, 0x42, 0xfa, 0x92, 0xbf, 0xd7, 0x6f, 0x07, 0x02, 0x6a, + 0xd2, 0xba, 0xd8, 0xb0, 0x08, 0x60, 0x65, 0x0d, 0xb5, 0xdd, + 0x71, 0x19, 0xa1, 0xc9, 0xcc, 0xa4, 0x1c, 0x74, 0x16, 0x7e, + 0xc6, 0xae, 0xab, 0xc3, 0x7b, 0x13, 0x21, 0x49, 0xf1, 0x99, + 0x9c, 0xf4, 0x4c, 0x24, 0x46, 0x2e, 0x96, 0xfe, 0xfb, 0x93, + 0x2b, 0x43, 0xef, 0x87, 0x3f, 0x57, 0x52, 0x3a, 0x82, 0xea, + 0x88, 0xe0, 0x58, 0x30, 0x35, 0x5d, 0xe5, 0x8d, 0xa0, 0xc8, + 0x70, 0x18, 0x1d, 0x75, 0xcd, 0xa5, 0xc7, 0xaf, 0x17, 0x7f, + 0x7a, 0x12, 0xaa, 0xc2, 0x6e, 0x06, 0xbe, 0xd6, 0xd3, 0xbb, + 0x03, 0x6b, 0x09, 0x61, 0xd9, 0xb1, 0xb4, 0xdc, 0x64, 0x0c, + 0x00, 0x69, 0xd2, 0xbb, 0xb9, 0xd0, 0x6b, 0x02, 0x6f, 0x06, + 0xbd, 0xd4, 0xd6, 0xbf, 0x04, 0x6d, 0xde, 0xb7, 0x0c, 0x65, + 0x67, 0x0e, 0xb5, 0xdc, 0xb1, 0xd8, 0x63, 0x0a, 0x08, 0x61, + 0xda, 0xb3, 0xa1, 0xc8, 0x73, 0x1a, 0x18, 0x71, 0xca, 0xa3, + 0xce, 0xa7, 0x1c, 0x75, 0x77, 0x1e, 0xa5, 0xcc, 0x7f, 0x16, + 0xad, 0xc4, 0xc6, 0xaf, 0x14, 0x7d, 0x10, 0x79, 0xc2, 0xab, + 0xa9, 0xc0, 0x7b, 0x12, 0x5f, 0x36, 0x8d, 0xe4, 0xe6, 0x8f, + 0x34, 0x5d, 0x30, 0x59, 0xe2, 0x8b, 0x89, 0xe0, 0x5b, 0x32, + 0x81, 0xe8, 0x53, 0x3a, 0x38, 0x51, 0xea, 0x83, 0xee, 0x87, + 0x3c, 0x55, 0x57, 0x3e, 0x85, 0xec, 0xfe, 0x97, 0x2c, 0x45, + 0x47, 0x2e, 0x95, 0xfc, 0x91, 0xf8, 0x43, 0x2a, 0x28, 0x41, + 0xfa, 0x93, 0x20, 0x49, 0xf2, 0x9b, 0x99, 0xf0, 0x4b, 0x22, + 0x4f, 0x26, 0x9d, 0xf4, 0xf6, 0x9f, 0x24, 0x4d, 0xbe, 0xd7, + 0x6c, 0x05, 0x07, 0x6e, 0xd5, 0xbc, 0xd1, 0xb8, 0x03, 0x6a, + 0x68, 0x01, 0xba, 0xd3, 0x60, 0x09, 0xb2, 0xdb, 0xd9, 0xb0, + 0x0b, 0x62, 0x0f, 0x66, 0xdd, 0xb4, 0xb6, 0xdf, 0x64, 0x0d, + 0x1f, 0x76, 0xcd, 0xa4, 0xa6, 0xcf, 0x74, 0x1d, 0x70, 0x19, + 0xa2, 0xcb, 0xc9, 0xa0, 0x1b, 0x72, 0xc1, 0xa8, 0x13, 0x7a, + 0x78, 0x11, 0xaa, 0xc3, 0xae, 0xc7, 0x7c, 0x15, 0x17, 0x7e, + 0xc5, 0xac, 0xe1, 0x88, 0x33, 0x5a, 0x58, 0x31, 0x8a, 0xe3, + 0x8e, 0xe7, 0x5c, 0x35, 0x37, 0x5e, 0xe5, 0x8c, 0x3f, 0x56, + 0xed, 0x84, 0x86, 0xef, 0x54, 0x3d, 0x50, 0x39, 0x82, 0xeb, + 0xe9, 0x80, 0x3b, 0x52, 0x40, 0x29, 0x92, 0xfb, 0xf9, 0x90, + 0x2b, 0x42, 0x2f, 0x46, 0xfd, 0x94, 0x96, 0xff, 0x44, 0x2d, + 0x9e, 0xf7, 0x4c, 0x25, 0x27, 0x4e, 0xf5, 0x9c, 0xf1, 0x98, + 0x23, 0x4a, 0x48, 0x21, 0x9a, 0xf3, 0x00, 0x6a, 0xd4, 0xbe, + 0xb5, 0xdf, 0x61, 0x0b, 0x77, 0x1d, 0xa3, 0xc9, 0xc2, 0xa8, + 0x16, 0x7c, 0xee, 0x84, 0x3a, 0x50, 0x5b, 0x31, 0x8f, 0xe5, + 0x99, 0xf3, 0x4d, 0x27, 0x2c, 0x46, 0xf8, 0x92, 0xc1, 0xab, + 0x15, 0x7f, 0x74, 0x1e, 0xa0, 0xca, 0xb6, 0xdc, 0x62, 0x08, + 0x03, 0x69, 0xd7, 0xbd, 0x2f, 0x45, 0xfb, 0x91, 0x9a, 0xf0, + 0x4e, 0x24, 0x58, 0x32, 0x8c, 0xe6, 0xed, 0x87, 0x39, 0x53, + 0x9f, 0xf5, 0x4b, 0x21, 0x2a, 0x40, 0xfe, 0x94, 0xe8, 0x82, + 0x3c, 0x56, 0x5d, 0x37, 0x89, 0xe3, 0x71, 0x1b, 0xa5, 0xcf, + 0xc4, 0xae, 0x10, 0x7a, 0x06, 0x6c, 0xd2, 0xb8, 0xb3, 0xd9, + 0x67, 0x0d, 0x5e, 0x34, 0x8a, 0xe0, 0xeb, 0x81, 0x3f, 0x55, + 0x29, 0x43, 0xfd, 0x97, 0x9c, 0xf6, 0x48, 0x22, 0xb0, 0xda, + 0x64, 0x0e, 0x05, 0x6f, 0xd1, 0xbb, 0xc7, 0xad, 0x13, 0x79, + 0x72, 0x18, 0xa6, 0xcc, 0x23, 0x49, 0xf7, 0x9d, 0x96, 0xfc, + 0x42, 0x28, 0x54, 0x3e, 0x80, 0xea, 0xe1, 0x8b, 0x35, 0x5f, + 0xcd, 0xa7, 0x19, 0x73, 0x78, 0x12, 0xac, 0xc6, 0xba, 0xd0, + 0x6e, 0x04, 0x0f, 0x65, 0xdb, 0xb1, 0xe2, 0x88, 0x36, 0x5c, + 0x57, 0x3d, 0x83, 0xe9, 0x95, 0xff, 0x41, 0x2b, 0x20, 0x4a, + 0xf4, 0x9e, 0x0c, 0x66, 0xd8, 0xb2, 0xb9, 0xd3, 0x6d, 0x07, + 0x7b, 0x11, 0xaf, 0xc5, 0xce, 0xa4, 0x1a, 0x70, 0xbc, 0xd6, + 0x68, 0x02, 0x09, 0x63, 0xdd, 0xb7, 0xcb, 0xa1, 0x1f, 0x75, + 0x7e, 0x14, 0xaa, 0xc0, 0x52, 0x38, 0x86, 0xec, 0xe7, 0x8d, + 0x33, 0x59, 0x25, 0x4f, 0xf1, 0x9b, 0x90, 0xfa, 0x44, 0x2e, + 0x7d, 0x17, 0xa9, 0xc3, 0xc8, 0xa2, 0x1c, 0x76, 0x0a, 0x60, + 0xde, 0xb4, 0xbf, 0xd5, 0x6b, 0x01, 0x93, 0xf9, 0x47, 0x2d, + 0x26, 0x4c, 0xf2, 0x98, 0xe4, 0x8e, 0x30, 0x5a, 0x51, 0x3b, + 0x85, 0xef, 0x00, 0x6b, 0xd6, 0xbd, 0xb1, 0xda, 0x67, 0x0c, + 0x7f, 0x14, 0xa9, 0xc2, 0xce, 0xa5, 0x18, 0x73, 0xfe, 0x95, + 0x28, 0x43, 0x4f, 0x24, 0x99, 0xf2, 0x81, 0xea, 0x57, 0x3c, + 0x30, 0x5b, 0xe6, 0x8d, 0xe1, 0x8a, 0x37, 0x5c, 0x50, 0x3b, + 0x86, 0xed, 0x9e, 0xf5, 0x48, 0x23, 0x2f, 0x44, 0xf9, 0x92, + 0x1f, 0x74, 0xc9, 0xa2, 0xae, 0xc5, 0x78, 0x13, 0x60, 0x0b, + 0xb6, 0xdd, 0xd1, 0xba, 0x07, 0x6c, 0xdf, 0xb4, 0x09, 0x62, + 0x6e, 0x05, 0xb8, 0xd3, 0xa0, 0xcb, 0x76, 0x1d, 0x11, 0x7a, + 0xc7, 0xac, 0x21, 0x4a, 0xf7, 0x9c, 0x90, 0xfb, 0x46, 0x2d, + 0x5e, 0x35, 0x88, 0xe3, 0xef, 0x84, 0x39, 0x52, 0x3e, 0x55, + 0xe8, 0x83, 0x8f, 0xe4, 0x59, 0x32, 0x41, 0x2a, 0x97, 0xfc, + 0xf0, 0x9b, 0x26, 0x4d, 0xc0, 0xab, 0x16, 0x7d, 0x71, 0x1a, + 0xa7, 0xcc, 0xbf, 0xd4, 0x69, 0x02, 0x0e, 0x65, 0xd8, 0xb3, + 0xa3, 0xc8, 0x75, 0x1e, 0x12, 0x79, 0xc4, 0xaf, 0xdc, 0xb7, + 0x0a, 0x61, 0x6d, 0x06, 0xbb, 0xd0, 0x5d, 0x36, 0x8b, 0xe0, + 0xec, 0x87, 0x3a, 0x51, 0x22, 0x49, 0xf4, 0x9f, 0x93, 0xf8, + 0x45, 0x2e, 0x42, 0x29, 0x94, 0xff, 0xf3, 0x98, 0x25, 0x4e, + 0x3d, 0x56, 0xeb, 0x80, 0x8c, 0xe7, 0x5a, 0x31, 0xbc, 0xd7, + 0x6a, 0x01, 0x0d, 0x66, 0xdb, 0xb0, 0xc3, 0xa8, 0x15, 0x7e, + 0x72, 0x19, 0xa4, 0xcf, 0x7c, 0x17, 0xaa, 0xc1, 0xcd, 0xa6, + 0x1b, 0x70, 0x03, 0x68, 0xd5, 0xbe, 0xb2, 0xd9, 0x64, 0x0f, + 0x82, 0xe9, 0x54, 0x3f, 0x33, 0x58, 0xe5, 0x8e, 0xfd, 0x96, + 0x2b, 0x40, 0x4c, 0x27, 0x9a, 0xf1, 0x9d, 0xf6, 0x4b, 0x20, + 0x2c, 0x47, 0xfa, 0x91, 0xe2, 0x89, 0x34, 0x5f, 0x53, 0x38, + 0x85, 0xee, 0x63, 0x08, 0xb5, 0xde, 0xd2, 0xb9, 0x04, 0x6f, + 0x1c, 0x77, 0xca, 0xa1, 0xad, 0xc6, 0x7b, 0x10, 0x00, 0x6c, + 0xd8, 0xb4, 0xad, 0xc1, 0x75, 0x19, 0x47, 0x2b, 0x9f, 0xf3, + 0xea, 0x86, 0x32, 0x5e, 0x8e, 0xe2, 0x56, 0x3a, 0x23, 0x4f, + 0xfb, 0x97, 0xc9, 0xa5, 0x11, 0x7d, 0x64, 0x08, 0xbc, 0xd0, + 0x01, 0x6d, 0xd9, 0xb5, 0xac, 0xc0, 0x74, 0x18, 0x46, 0x2a, + 0x9e, 0xf2, 0xeb, 0x87, 0x33, 0x5f, 0x8f, 0xe3, 0x57, 0x3b, + 0x22, 0x4e, 0xfa, 0x96, 0xc8, 0xa4, 0x10, 0x7c, 0x65, 0x09, + 0xbd, 0xd1, 0x02, 0x6e, 0xda, 0xb6, 0xaf, 0xc3, 0x77, 0x1b, + 0x45, 0x29, 0x9d, 0xf1, 0xe8, 0x84, 0x30, 0x5c, 0x8c, 0xe0, + 0x54, 0x38, 0x21, 0x4d, 0xf9, 0x95, 0xcb, 0xa7, 0x13, 0x7f, + 0x66, 0x0a, 0xbe, 0xd2, 0x03, 0x6f, 0xdb, 0xb7, 0xae, 0xc2, + 0x76, 0x1a, 0x44, 0x28, 0x9c, 0xf0, 0xe9, 0x85, 0x31, 0x5d, + 0x8d, 0xe1, 0x55, 0x39, 0x20, 0x4c, 0xf8, 0x94, 0xca, 0xa6, + 0x12, 0x7e, 0x67, 0x0b, 0xbf, 0xd3, 0x04, 0x68, 0xdc, 0xb0, + 0xa9, 0xc5, 0x71, 0x1d, 0x43, 0x2f, 0x9b, 0xf7, 0xee, 0x82, + 0x36, 0x5a, 0x8a, 0xe6, 0x52, 0x3e, 0x27, 0x4b, 0xff, 0x93, + 0xcd, 0xa1, 0x15, 0x79, 0x60, 0x0c, 0xb8, 0xd4, 0x05, 0x69, + 0xdd, 0xb1, 0xa8, 0xc4, 0x70, 0x1c, 0x42, 0x2e, 0x9a, 0xf6, + 0xef, 0x83, 0x37, 0x5b, 0x8b, 0xe7, 0x53, 0x3f, 0x26, 0x4a, + 0xfe, 0x92, 0xcc, 0xa0, 0x14, 0x78, 0x61, 0x0d, 0xb9, 0xd5, + 0x06, 0x6a, 0xde, 0xb2, 0xab, 0xc7, 0x73, 0x1f, 0x41, 0x2d, + 0x99, 0xf5, 0xec, 0x80, 0x34, 0x58, 0x88, 0xe4, 0x50, 0x3c, + 0x25, 0x49, 0xfd, 0x91, 0xcf, 0xa3, 0x17, 0x7b, 0x62, 0x0e, + 0xba, 0xd6, 0x07, 0x6b, 0xdf, 0xb3, 0xaa, 0xc6, 0x72, 0x1e, + 0x40, 0x2c, 0x98, 0xf4, 0xed, 0x81, 0x35, 0x59, 0x89, 0xe5, + 0x51, 0x3d, 0x24, 0x48, 0xfc, 0x90, 0xce, 0xa2, 0x16, 0x7a, + 0x63, 0x0f, 0xbb, 0xd7, 0x00, 0x6d, 0xda, 0xb7, 0xa9, 0xc4, + 0x73, 0x1e, 0x4f, 0x22, 0x95, 0xf8, 0xe6, 0x8b, 0x3c, 0x51, + 0x9e, 0xf3, 0x44, 0x29, 0x37, 0x5a, 0xed, 0x80, 0xd1, 0xbc, + 0x0b, 0x66, 0x78, 0x15, 0xa2, 0xcf, 0x21, 0x4c, 0xfb, 0x96, + 0x88, 0xe5, 0x52, 0x3f, 0x6e, 0x03, 0xb4, 0xd9, 0xc7, 0xaa, + 0x1d, 0x70, 0xbf, 0xd2, 0x65, 0x08, 0x16, 0x7b, 0xcc, 0xa1, + 0xf0, 0x9d, 0x2a, 0x47, 0x59, 0x34, 0x83, 0xee, 0x42, 0x2f, + 0x98, 0xf5, 0xeb, 0x86, 0x31, 0x5c, 0x0d, 0x60, 0xd7, 0xba, + 0xa4, 0xc9, 0x7e, 0x13, 0xdc, 0xb1, 0x06, 0x6b, 0x75, 0x18, + 0xaf, 0xc2, 0x93, 0xfe, 0x49, 0x24, 0x3a, 0x57, 0xe0, 0x8d, + 0x63, 0x0e, 0xb9, 0xd4, 0xca, 0xa7, 0x10, 0x7d, 0x2c, 0x41, + 0xf6, 0x9b, 0x85, 0xe8, 0x5f, 0x32, 0xfd, 0x90, 0x27, 0x4a, + 0x54, 0x39, 0x8e, 0xe3, 0xb2, 0xdf, 0x68, 0x05, 0x1b, 0x76, + 0xc1, 0xac, 0x84, 0xe9, 0x5e, 0x33, 0x2d, 0x40, 0xf7, 0x9a, + 0xcb, 0xa6, 0x11, 0x7c, 0x62, 0x0f, 0xb8, 0xd5, 0x1a, 0x77, + 0xc0, 0xad, 0xb3, 0xde, 0x69, 0x04, 0x55, 0x38, 0x8f, 0xe2, + 0xfc, 0x91, 0x26, 0x4b, 0xa5, 0xc8, 0x7f, 0x12, 0x0c, 0x61, + 0xd6, 0xbb, 0xea, 0x87, 0x30, 0x5d, 0x43, 0x2e, 0x99, 0xf4, + 0x3b, 0x56, 0xe1, 0x8c, 0x92, 0xff, 0x48, 0x25, 0x74, 0x19, + 0xae, 0xc3, 0xdd, 0xb0, 0x07, 0x6a, 0xc6, 0xab, 0x1c, 0x71, + 0x6f, 0x02, 0xb5, 0xd8, 0x89, 0xe4, 0x53, 0x3e, 0x20, 0x4d, + 0xfa, 0x97, 0x58, 0x35, 0x82, 0xef, 0xf1, 0x9c, 0x2b, 0x46, + 0x17, 0x7a, 0xcd, 0xa0, 0xbe, 0xd3, 0x64, 0x09, 0xe7, 0x8a, + 0x3d, 0x50, 0x4e, 0x23, 0x94, 0xf9, 0xa8, 0xc5, 0x72, 0x1f, + 0x01, 0x6c, 0xdb, 0xb6, 0x79, 0x14, 0xa3, 0xce, 0xd0, 0xbd, + 0x0a, 0x67, 0x36, 0x5b, 0xec, 0x81, 0x9f, 0xf2, 0x45, 0x28, + 0x00, 0x6e, 0xdc, 0xb2, 0xa5, 0xcb, 0x79, 0x17, 0x57, 0x39, + 0x8b, 0xe5, 0xf2, 0x9c, 0x2e, 0x40, 0xae, 0xc0, 0x72, 0x1c, + 0x0b, 0x65, 0xd7, 0xb9, 0xf9, 0x97, 0x25, 0x4b, 0x5c, 0x32, + 0x80, 0xee, 0x41, 0x2f, 0x9d, 0xf3, 0xe4, 0x8a, 0x38, 0x56, + 0x16, 0x78, 0xca, 0xa4, 0xb3, 0xdd, 0x6f, 0x01, 0xef, 0x81, + 0x33, 0x5d, 0x4a, 0x24, 0x96, 0xf8, 0xb8, 0xd6, 0x64, 0x0a, + 0x1d, 0x73, 0xc1, 0xaf, 0x82, 0xec, 0x5e, 0x30, 0x27, 0x49, + 0xfb, 0x95, 0xd5, 0xbb, 0x09, 0x67, 0x70, 0x1e, 0xac, 0xc2, + 0x2c, 0x42, 0xf0, 0x9e, 0x89, 0xe7, 0x55, 0x3b, 0x7b, 0x15, + 0xa7, 0xc9, 0xde, 0xb0, 0x02, 0x6c, 0xc3, 0xad, 0x1f, 0x71, + 0x66, 0x08, 0xba, 0xd4, 0x94, 0xfa, 0x48, 0x26, 0x31, 0x5f, + 0xed, 0x83, 0x6d, 0x03, 0xb1, 0xdf, 0xc8, 0xa6, 0x14, 0x7a, + 0x3a, 0x54, 0xe6, 0x88, 0x9f, 0xf1, 0x43, 0x2d, 0x19, 0x77, + 0xc5, 0xab, 0xbc, 0xd2, 0x60, 0x0e, 0x4e, 0x20, 0x92, 0xfc, + 0xeb, 0x85, 0x37, 0x59, 0xb7, 0xd9, 0x6b, 0x05, 0x12, 0x7c, + 0xce, 0xa0, 0xe0, 0x8e, 0x3c, 0x52, 0x45, 0x2b, 0x99, 0xf7, + 0x58, 0x36, 0x84, 0xea, 0xfd, 0x93, 0x21, 0x4f, 0x0f, 0x61, + 0xd3, 0xbd, 0xaa, 0xc4, 0x76, 0x18, 0xf6, 0x98, 0x2a, 0x44, + 0x53, 0x3d, 0x8f, 0xe1, 0xa1, 0xcf, 0x7d, 0x13, 0x04, 0x6a, + 0xd8, 0xb6, 0x9b, 0xf5, 0x47, 0x29, 0x3e, 0x50, 0xe2, 0x8c, + 0xcc, 0xa2, 0x10, 0x7e, 0x69, 0x07, 0xb5, 0xdb, 0x35, 0x5b, + 0xe9, 0x87, 0x90, 0xfe, 0x4c, 0x22, 0x62, 0x0c, 0xbe, 0xd0, + 0xc7, 0xa9, 0x1b, 0x75, 0xda, 0xb4, 0x06, 0x68, 0x7f, 0x11, + 0xa3, 0xcd, 0x8d, 0xe3, 0x51, 0x3f, 0x28, 0x46, 0xf4, 0x9a, + 0x74, 0x1a, 0xa8, 0xc6, 0xd1, 0xbf, 0x0d, 0x63, 0x23, 0x4d, + 0xff, 0x91, 0x86, 0xe8, 0x5a, 0x34, 0x00, 0x6f, 0xde, 0xb1, + 0xa1, 0xce, 0x7f, 0x10, 0x5f, 0x30, 0x81, 0xee, 0xfe, 0x91, + 0x20, 0x4f, 0xbe, 0xd1, 0x60, 0x0f, 0x1f, 0x70, 0xc1, 0xae, + 0xe1, 0x8e, 0x3f, 0x50, 0x40, 0x2f, 0x9e, 0xf1, 0x61, 0x0e, + 0xbf, 0xd0, 0xc0, 0xaf, 0x1e, 0x71, 0x3e, 0x51, 0xe0, 0x8f, + 0x9f, 0xf0, 0x41, 0x2e, 0xdf, 0xb0, 0x01, 0x6e, 0x7e, 0x11, + 0xa0, 0xcf, 0x80, 0xef, 0x5e, 0x31, 0x21, 0x4e, 0xff, 0x90, + 0xc2, 0xad, 0x1c, 0x73, 0x63, 0x0c, 0xbd, 0xd2, 0x9d, 0xf2, + 0x43, 0x2c, 0x3c, 0x53, 0xe2, 0x8d, 0x7c, 0x13, 0xa2, 0xcd, + 0xdd, 0xb2, 0x03, 0x6c, 0x23, 0x4c, 0xfd, 0x92, 0x82, 0xed, + 0x5c, 0x33, 0xa3, 0xcc, 0x7d, 0x12, 0x02, 0x6d, 0xdc, 0xb3, + 0xfc, 0x93, 0x22, 0x4d, 0x5d, 0x32, 0x83, 0xec, 0x1d, 0x72, + 0xc3, 0xac, 0xbc, 0xd3, 0x62, 0x0d, 0x42, 0x2d, 0x9c, 0xf3, + 0xe3, 0x8c, 0x3d, 0x52, 0x99, 0xf6, 0x47, 0x28, 0x38, 0x57, + 0xe6, 0x89, 0xc6, 0xa9, 0x18, 0x77, 0x67, 0x08, 0xb9, 0xd6, + 0x27, 0x48, 0xf9, 0x96, 0x86, 0xe9, 0x58, 0x37, 0x78, 0x17, + 0xa6, 0xc9, 0xd9, 0xb6, 0x07, 0x68, 0xf8, 0x97, 0x26, 0x49, + 0x59, 0x36, 0x87, 0xe8, 0xa7, 0xc8, 0x79, 0x16, 0x06, 0x69, + 0xd8, 0xb7, 0x46, 0x29, 0x98, 0xf7, 0xe7, 0x88, 0x39, 0x56, + 0x19, 0x76, 0xc7, 0xa8, 0xb8, 0xd7, 0x66, 0x09, 0x5b, 0x34, + 0x85, 0xea, 0xfa, 0x95, 0x24, 0x4b, 0x04, 0x6b, 0xda, 0xb5, + 0xa5, 0xca, 0x7b, 0x14, 0xe5, 0x8a, 0x3b, 0x54, 0x44, 0x2b, + 0x9a, 0xf5, 0xba, 0xd5, 0x64, 0x0b, 0x1b, 0x74, 0xc5, 0xaa, + 0x3a, 0x55, 0xe4, 0x8b, 0x9b, 0xf4, 0x45, 0x2a, 0x65, 0x0a, + 0xbb, 0xd4, 0xc4, 0xab, 0x1a, 0x75, 0x84, 0xeb, 0x5a, 0x35, + 0x25, 0x4a, 0xfb, 0x94, 0xdb, 0xb4, 0x05, 0x6a, 0x7a, 0x15, + 0xa4, 0xcb, 0x00, 0x70, 0xe0, 0x90, 0xdd, 0xad, 0x3d, 0x4d, + 0xa7, 0xd7, 0x47, 0x37, 0x7a, 0x0a, 0x9a, 0xea, 0x53, 0x23, + 0xb3, 0xc3, 0x8e, 0xfe, 0x6e, 0x1e, 0xf4, 0x84, 0x14, 0x64, + 0x29, 0x59, 0xc9, 0xb9, 0xa6, 0xd6, 0x46, 0x36, 0x7b, 0x0b, + 0x9b, 0xeb, 0x01, 0x71, 0xe1, 0x91, 0xdc, 0xac, 0x3c, 0x4c, + 0xf5, 0x85, 0x15, 0x65, 0x28, 0x58, 0xc8, 0xb8, 0x52, 0x22, + 0xb2, 0xc2, 0x8f, 0xff, 0x6f, 0x1f, 0x51, 0x21, 0xb1, 0xc1, + 0x8c, 0xfc, 0x6c, 0x1c, 0xf6, 0x86, 0x16, 0x66, 0x2b, 0x5b, + 0xcb, 0xbb, 0x02, 0x72, 0xe2, 0x92, 0xdf, 0xaf, 0x3f, 0x4f, + 0xa5, 0xd5, 0x45, 0x35, 0x78, 0x08, 0x98, 0xe8, 0xf7, 0x87, + 0x17, 0x67, 0x2a, 0x5a, 0xca, 0xba, 0x50, 0x20, 0xb0, 0xc0, + 0x8d, 0xfd, 0x6d, 0x1d, 0xa4, 0xd4, 0x44, 0x34, 0x79, 0x09, + 0x99, 0xe9, 0x03, 0x73, 0xe3, 0x93, 0xde, 0xae, 0x3e, 0x4e, + 0xa2, 0xd2, 0x42, 0x32, 0x7f, 0x0f, 0x9f, 0xef, 0x05, 0x75, + 0xe5, 0x95, 0xd8, 0xa8, 0x38, 0x48, 0xf1, 0x81, 0x11, 0x61, + 0x2c, 0x5c, 0xcc, 0xbc, 0x56, 0x26, 0xb6, 0xc6, 0x8b, 0xfb, + 0x6b, 0x1b, 0x04, 0x74, 0xe4, 0x94, 0xd9, 0xa9, 0x39, 0x49, + 0xa3, 0xd3, 0x43, 0x33, 0x7e, 0x0e, 0x9e, 0xee, 0x57, 0x27, + 0xb7, 0xc7, 0x8a, 0xfa, 0x6a, 0x1a, 0xf0, 0x80, 0x10, 0x60, + 0x2d, 0x5d, 0xcd, 0xbd, 0xf3, 0x83, 0x13, 0x63, 0x2e, 0x5e, + 0xce, 0xbe, 0x54, 0x24, 0xb4, 0xc4, 0x89, 0xf9, 0x69, 0x19, + 0xa0, 0xd0, 0x40, 0x30, 0x7d, 0x0d, 0x9d, 0xed, 0x07, 0x77, + 0xe7, 0x97, 0xda, 0xaa, 0x3a, 0x4a, 0x55, 0x25, 0xb5, 0xc5, + 0x88, 0xf8, 0x68, 0x18, 0xf2, 0x82, 0x12, 0x62, 0x2f, 0x5f, + 0xcf, 0xbf, 0x06, 0x76, 0xe6, 0x96, 0xdb, 0xab, 0x3b, 0x4b, + 0xa1, 0xd1, 0x41, 0x31, 0x7c, 0x0c, 0x9c, 0xec, 0x00, 0x71, + 0xe2, 0x93, 0xd9, 0xa8, 0x3b, 0x4a, 0xaf, 0xde, 0x4d, 0x3c, + 0x76, 0x07, 0x94, 0xe5, 0x43, 0x32, 0xa1, 0xd0, 0x9a, 0xeb, + 0x78, 0x09, 0xec, 0x9d, 0x0e, 0x7f, 0x35, 0x44, 0xd7, 0xa6, + 0x86, 0xf7, 0x64, 0x15, 0x5f, 0x2e, 0xbd, 0xcc, 0x29, 0x58, + 0xcb, 0xba, 0xf0, 0x81, 0x12, 0x63, 0xc5, 0xb4, 0x27, 0x56, + 0x1c, 0x6d, 0xfe, 0x8f, 0x6a, 0x1b, 0x88, 0xf9, 0xb3, 0xc2, + 0x51, 0x20, 0x11, 0x60, 0xf3, 0x82, 0xc8, 0xb9, 0x2a, 0x5b, + 0xbe, 0xcf, 0x5c, 0x2d, 0x67, 0x16, 0x85, 0xf4, 0x52, 0x23, + 0xb0, 0xc1, 0x8b, 0xfa, 0x69, 0x18, 0xfd, 0x8c, 0x1f, 0x6e, + 0x24, 0x55, 0xc6, 0xb7, 0x97, 0xe6, 0x75, 0x04, 0x4e, 0x3f, + 0xac, 0xdd, 0x38, 0x49, 0xda, 0xab, 0xe1, 0x90, 0x03, 0x72, + 0xd4, 0xa5, 0x36, 0x47, 0x0d, 0x7c, 0xef, 0x9e, 0x7b, 0x0a, + 0x99, 0xe8, 0xa2, 0xd3, 0x40, 0x31, 0x22, 0x53, 0xc0, 0xb1, + 0xfb, 0x8a, 0x19, 0x68, 0x8d, 0xfc, 0x6f, 0x1e, 0x54, 0x25, + 0xb6, 0xc7, 0x61, 0x10, 0x83, 0xf2, 0xb8, 0xc9, 0x5a, 0x2b, + 0xce, 0xbf, 0x2c, 0x5d, 0x17, 0x66, 0xf5, 0x84, 0xa4, 0xd5, + 0x46, 0x37, 0x7d, 0x0c, 0x9f, 0xee, 0x0b, 0x7a, 0xe9, 0x98, + 0xd2, 0xa3, 0x30, 0x41, 0xe7, 0x96, 0x05, 0x74, 0x3e, 0x4f, + 0xdc, 0xad, 0x48, 0x39, 0xaa, 0xdb, 0x91, 0xe0, 0x73, 0x02, + 0x33, 0x42, 0xd1, 0xa0, 0xea, 0x9b, 0x08, 0x79, 0x9c, 0xed, + 0x7e, 0x0f, 0x45, 0x34, 0xa7, 0xd6, 0x70, 0x01, 0x92, 0xe3, + 0xa9, 0xd8, 0x4b, 0x3a, 0xdf, 0xae, 0x3d, 0x4c, 0x06, 0x77, + 0xe4, 0x95, 0xb5, 0xc4, 0x57, 0x26, 0x6c, 0x1d, 0x8e, 0xff, + 0x1a, 0x6b, 0xf8, 0x89, 0xc3, 0xb2, 0x21, 0x50, 0xf6, 0x87, + 0x14, 0x65, 0x2f, 0x5e, 0xcd, 0xbc, 0x59, 0x28, 0xbb, 0xca, + 0x80, 0xf1, 0x62, 0x13, 0x00, 0x72, 0xe4, 0x96, 0xd5, 0xa7, + 0x31, 0x43, 0xb7, 0xc5, 0x53, 0x21, 0x62, 0x10, 0x86, 0xf4, + 0x73, 0x01, 0x97, 0xe5, 0xa6, 0xd4, 0x42, 0x30, 0xc4, 0xb6, + 0x20, 0x52, 0x11, 0x63, 0xf5, 0x87, 0xe6, 0x94, 0x02, 0x70, + 0x33, 0x41, 0xd7, 0xa5, 0x51, 0x23, 0xb5, 0xc7, 0x84, 0xf6, + 0x60, 0x12, 0x95, 0xe7, 0x71, 0x03, 0x40, 0x32, 0xa4, 0xd6, + 0x22, 0x50, 0xc6, 0xb4, 0xf7, 0x85, 0x13, 0x61, 0xd1, 0xa3, + 0x35, 0x47, 0x04, 0x76, 0xe0, 0x92, 0x66, 0x14, 0x82, 0xf0, + 0xb3, 0xc1, 0x57, 0x25, 0xa2, 0xd0, 0x46, 0x34, 0x77, 0x05, + 0x93, 0xe1, 0x15, 0x67, 0xf1, 0x83, 0xc0, 0xb2, 0x24, 0x56, + 0x37, 0x45, 0xd3, 0xa1, 0xe2, 0x90, 0x06, 0x74, 0x80, 0xf2, + 0x64, 0x16, 0x55, 0x27, 0xb1, 0xc3, 0x44, 0x36, 0xa0, 0xd2, + 0x91, 0xe3, 0x75, 0x07, 0xf3, 0x81, 0x17, 0x65, 0x26, 0x54, + 0xc2, 0xb0, 0xbf, 0xcd, 0x5b, 0x29, 0x6a, 0x18, 0x8e, 0xfc, + 0x08, 0x7a, 0xec, 0x9e, 0xdd, 0xaf, 0x39, 0x4b, 0xcc, 0xbe, + 0x28, 0x5a, 0x19, 0x6b, 0xfd, 0x8f, 0x7b, 0x09, 0x9f, 0xed, + 0xae, 0xdc, 0x4a, 0x38, 0x59, 0x2b, 0xbd, 0xcf, 0x8c, 0xfe, + 0x68, 0x1a, 0xee, 0x9c, 0x0a, 0x78, 0x3b, 0x49, 0xdf, 0xad, + 0x2a, 0x58, 0xce, 0xbc, 0xff, 0x8d, 0x1b, 0x69, 0x9d, 0xef, + 0x79, 0x0b, 0x48, 0x3a, 0xac, 0xde, 0x6e, 0x1c, 0x8a, 0xf8, + 0xbb, 0xc9, 0x5f, 0x2d, 0xd9, 0xab, 0x3d, 0x4f, 0x0c, 0x7e, + 0xe8, 0x9a, 0x1d, 0x6f, 0xf9, 0x8b, 0xc8, 0xba, 0x2c, 0x5e, + 0xaa, 0xd8, 0x4e, 0x3c, 0x7f, 0x0d, 0x9b, 0xe9, 0x88, 0xfa, + 0x6c, 0x1e, 0x5d, 0x2f, 0xb9, 0xcb, 0x3f, 0x4d, 0xdb, 0xa9, + 0xea, 0x98, 0x0e, 0x7c, 0xfb, 0x89, 0x1f, 0x6d, 0x2e, 0x5c, + 0xca, 0xb8, 0x4c, 0x3e, 0xa8, 0xda, 0x99, 0xeb, 0x7d, 0x0f, + 0x00, 0x73, 0xe6, 0x95, 0xd1, 0xa2, 0x37, 0x44, 0xbf, 0xcc, + 0x59, 0x2a, 0x6e, 0x1d, 0x88, 0xfb, 0x63, 0x10, 0x85, 0xf6, + 0xb2, 0xc1, 0x54, 0x27, 0xdc, 0xaf, 0x3a, 0x49, 0x0d, 0x7e, + 0xeb, 0x98, 0xc6, 0xb5, 0x20, 0x53, 0x17, 0x64, 0xf1, 0x82, + 0x79, 0x0a, 0x9f, 0xec, 0xa8, 0xdb, 0x4e, 0x3d, 0xa5, 0xd6, + 0x43, 0x30, 0x74, 0x07, 0x92, 0xe1, 0x1a, 0x69, 0xfc, 0x8f, + 0xcb, 0xb8, 0x2d, 0x5e, 0x91, 0xe2, 0x77, 0x04, 0x40, 0x33, + 0xa6, 0xd5, 0x2e, 0x5d, 0xc8, 0xbb, 0xff, 0x8c, 0x19, 0x6a, + 0xf2, 0x81, 0x14, 0x67, 0x23, 0x50, 0xc5, 0xb6, 0x4d, 0x3e, + 0xab, 0xd8, 0x9c, 0xef, 0x7a, 0x09, 0x57, 0x24, 0xb1, 0xc2, + 0x86, 0xf5, 0x60, 0x13, 0xe8, 0x9b, 0x0e, 0x7d, 0x39, 0x4a, + 0xdf, 0xac, 0x34, 0x47, 0xd2, 0xa1, 0xe5, 0x96, 0x03, 0x70, + 0x8b, 0xf8, 0x6d, 0x1e, 0x5a, 0x29, 0xbc, 0xcf, 0x3f, 0x4c, + 0xd9, 0xaa, 0xee, 0x9d, 0x08, 0x7b, 0x80, 0xf3, 0x66, 0x15, + 0x51, 0x22, 0xb7, 0xc4, 0x5c, 0x2f, 0xba, 0xc9, 0x8d, 0xfe, + 0x6b, 0x18, 0xe3, 0x90, 0x05, 0x76, 0x32, 0x41, 0xd4, 0xa7, + 0xf9, 0x8a, 0x1f, 0x6c, 0x28, 0x5b, 0xce, 0xbd, 0x46, 0x35, + 0xa0, 0xd3, 0x97, 0xe4, 0x71, 0x02, 0x9a, 0xe9, 0x7c, 0x0f, + 0x4b, 0x38, 0xad, 0xde, 0x25, 0x56, 0xc3, 0xb0, 0xf4, 0x87, + 0x12, 0x61, 0xae, 0xdd, 0x48, 0x3b, 0x7f, 0x0c, 0x99, 0xea, + 0x11, 0x62, 0xf7, 0x84, 0xc0, 0xb3, 0x26, 0x55, 0xcd, 0xbe, + 0x2b, 0x58, 0x1c, 0x6f, 0xfa, 0x89, 0x72, 0x01, 0x94, 0xe7, + 0xa3, 0xd0, 0x45, 0x36, 0x68, 0x1b, 0x8e, 0xfd, 0xb9, 0xca, + 0x5f, 0x2c, 0xd7, 0xa4, 0x31, 0x42, 0x06, 0x75, 0xe0, 0x93, + 0x0b, 0x78, 0xed, 0x9e, 0xda, 0xa9, 0x3c, 0x4f, 0xb4, 0xc7, + 0x52, 0x21, 0x65, 0x16, 0x83, 0xf0, 0x00, 0x74, 0xe8, 0x9c, + 0xcd, 0xb9, 0x25, 0x51, 0x87, 0xf3, 0x6f, 0x1b, 0x4a, 0x3e, + 0xa2, 0xd6, 0x13, 0x67, 0xfb, 0x8f, 0xde, 0xaa, 0x36, 0x42, + 0x94, 0xe0, 0x7c, 0x08, 0x59, 0x2d, 0xb1, 0xc5, 0x26, 0x52, + 0xce, 0xba, 0xeb, 0x9f, 0x03, 0x77, 0xa1, 0xd5, 0x49, 0x3d, + 0x6c, 0x18, 0x84, 0xf0, 0x35, 0x41, 0xdd, 0xa9, 0xf8, 0x8c, + 0x10, 0x64, 0xb2, 0xc6, 0x5a, 0x2e, 0x7f, 0x0b, 0x97, 0xe3, + 0x4c, 0x38, 0xa4, 0xd0, 0x81, 0xf5, 0x69, 0x1d, 0xcb, 0xbf, + 0x23, 0x57, 0x06, 0x72, 0xee, 0x9a, 0x5f, 0x2b, 0xb7, 0xc3, + 0x92, 0xe6, 0x7a, 0x0e, 0xd8, 0xac, 0x30, 0x44, 0x15, 0x61, + 0xfd, 0x89, 0x6a, 0x1e, 0x82, 0xf6, 0xa7, 0xd3, 0x4f, 0x3b, + 0xed, 0x99, 0x05, 0x71, 0x20, 0x54, 0xc8, 0xbc, 0x79, 0x0d, + 0x91, 0xe5, 0xb4, 0xc0, 0x5c, 0x28, 0xfe, 0x8a, 0x16, 0x62, + 0x33, 0x47, 0xdb, 0xaf, 0x98, 0xec, 0x70, 0x04, 0x55, 0x21, + 0xbd, 0xc9, 0x1f, 0x6b, 0xf7, 0x83, 0xd2, 0xa6, 0x3a, 0x4e, + 0x8b, 0xff, 0x63, 0x17, 0x46, 0x32, 0xae, 0xda, 0x0c, 0x78, + 0xe4, 0x90, 0xc1, 0xb5, 0x29, 0x5d, 0xbe, 0xca, 0x56, 0x22, + 0x73, 0x07, 0x9b, 0xef, 0x39, 0x4d, 0xd1, 0xa5, 0xf4, 0x80, + 0x1c, 0x68, 0xad, 0xd9, 0x45, 0x31, 0x60, 0x14, 0x88, 0xfc, + 0x2a, 0x5e, 0xc2, 0xb6, 0xe7, 0x93, 0x0f, 0x7b, 0xd4, 0xa0, + 0x3c, 0x48, 0x19, 0x6d, 0xf1, 0x85, 0x53, 0x27, 0xbb, 0xcf, + 0x9e, 0xea, 0x76, 0x02, 0xc7, 0xb3, 0x2f, 0x5b, 0x0a, 0x7e, + 0xe2, 0x96, 0x40, 0x34, 0xa8, 0xdc, 0x8d, 0xf9, 0x65, 0x11, + 0xf2, 0x86, 0x1a, 0x6e, 0x3f, 0x4b, 0xd7, 0xa3, 0x75, 0x01, + 0x9d, 0xe9, 0xb8, 0xcc, 0x50, 0x24, 0xe1, 0x95, 0x09, 0x7d, + 0x2c, 0x58, 0xc4, 0xb0, 0x66, 0x12, 0x8e, 0xfa, 0xab, 0xdf, + 0x43, 0x37, 0x00, 0x75, 0xea, 0x9f, 0xc9, 0xbc, 0x23, 0x56, + 0x8f, 0xfa, 0x65, 0x10, 0x46, 0x33, 0xac, 0xd9, 0x03, 0x76, + 0xe9, 0x9c, 0xca, 0xbf, 0x20, 0x55, 0x8c, 0xf9, 0x66, 0x13, + 0x45, 0x30, 0xaf, 0xda, 0x06, 0x73, 0xec, 0x99, 0xcf, 0xba, + 0x25, 0x50, 0x89, 0xfc, 0x63, 0x16, 0x40, 0x35, 0xaa, 0xdf, + 0x05, 0x70, 0xef, 0x9a, 0xcc, 0xb9, 0x26, 0x53, 0x8a, 0xff, + 0x60, 0x15, 0x43, 0x36, 0xa9, 0xdc, 0x0c, 0x79, 0xe6, 0x93, + 0xc5, 0xb0, 0x2f, 0x5a, 0x83, 0xf6, 0x69, 0x1c, 0x4a, 0x3f, + 0xa0, 0xd5, 0x0f, 0x7a, 0xe5, 0x90, 0xc6, 0xb3, 0x2c, 0x59, + 0x80, 0xf5, 0x6a, 0x1f, 0x49, 0x3c, 0xa3, 0xd6, 0x0a, 0x7f, + 0xe0, 0x95, 0xc3, 0xb6, 0x29, 0x5c, 0x85, 0xf0, 0x6f, 0x1a, + 0x4c, 0x39, 0xa6, 0xd3, 0x09, 0x7c, 0xe3, 0x96, 0xc0, 0xb5, + 0x2a, 0x5f, 0x86, 0xf3, 0x6c, 0x19, 0x4f, 0x3a, 0xa5, 0xd0, + 0x18, 0x6d, 0xf2, 0x87, 0xd1, 0xa4, 0x3b, 0x4e, 0x97, 0xe2, + 0x7d, 0x08, 0x5e, 0x2b, 0xb4, 0xc1, 0x1b, 0x6e, 0xf1, 0x84, + 0xd2, 0xa7, 0x38, 0x4d, 0x94, 0xe1, 0x7e, 0x0b, 0x5d, 0x28, + 0xb7, 0xc2, 0x1e, 0x6b, 0xf4, 0x81, 0xd7, 0xa2, 0x3d, 0x48, + 0x91, 0xe4, 0x7b, 0x0e, 0x58, 0x2d, 0xb2, 0xc7, 0x1d, 0x68, + 0xf7, 0x82, 0xd4, 0xa1, 0x3e, 0x4b, 0x92, 0xe7, 0x78, 0x0d, + 0x5b, 0x2e, 0xb1, 0xc4, 0x14, 0x61, 0xfe, 0x8b, 0xdd, 0xa8, + 0x37, 0x42, 0x9b, 0xee, 0x71, 0x04, 0x52, 0x27, 0xb8, 0xcd, + 0x17, 0x62, 0xfd, 0x88, 0xde, 0xab, 0x34, 0x41, 0x98, 0xed, + 0x72, 0x07, 0x51, 0x24, 0xbb, 0xce, 0x12, 0x67, 0xf8, 0x8d, + 0xdb, 0xae, 0x31, 0x44, 0x9d, 0xe8, 0x77, 0x02, 0x54, 0x21, + 0xbe, 0xcb, 0x11, 0x64, 0xfb, 0x8e, 0xd8, 0xad, 0x32, 0x47, + 0x9e, 0xeb, 0x74, 0x01, 0x57, 0x22, 0xbd, 0xc8, 0x00, 0x76, + 0xec, 0x9a, 0xc5, 0xb3, 0x29, 0x5f, 0x97, 0xe1, 0x7b, 0x0d, + 0x52, 0x24, 0xbe, 0xc8, 0x33, 0x45, 0xdf, 0xa9, 0xf6, 0x80, + 0x1a, 0x6c, 0xa4, 0xd2, 0x48, 0x3e, 0x61, 0x17, 0x8d, 0xfb, + 0x66, 0x10, 0x8a, 0xfc, 0xa3, 0xd5, 0x4f, 0x39, 0xf1, 0x87, + 0x1d, 0x6b, 0x34, 0x42, 0xd8, 0xae, 0x55, 0x23, 0xb9, 0xcf, + 0x90, 0xe6, 0x7c, 0x0a, 0xc2, 0xb4, 0x2e, 0x58, 0x07, 0x71, + 0xeb, 0x9d, 0xcc, 0xba, 0x20, 0x56, 0x09, 0x7f, 0xe5, 0x93, + 0x5b, 0x2d, 0xb7, 0xc1, 0x9e, 0xe8, 0x72, 0x04, 0xff, 0x89, + 0x13, 0x65, 0x3a, 0x4c, 0xd6, 0xa0, 0x68, 0x1e, 0x84, 0xf2, + 0xad, 0xdb, 0x41, 0x37, 0xaa, 0xdc, 0x46, 0x30, 0x6f, 0x19, + 0x83, 0xf5, 0x3d, 0x4b, 0xd1, 0xa7, 0xf8, 0x8e, 0x14, 0x62, + 0x99, 0xef, 0x75, 0x03, 0x5c, 0x2a, 0xb0, 0xc6, 0x0e, 0x78, + 0xe2, 0x94, 0xcb, 0xbd, 0x27, 0x51, 0x85, 0xf3, 0x69, 0x1f, + 0x40, 0x36, 0xac, 0xda, 0x12, 0x64, 0xfe, 0x88, 0xd7, 0xa1, + 0x3b, 0x4d, 0xb6, 0xc0, 0x5a, 0x2c, 0x73, 0x05, 0x9f, 0xe9, + 0x21, 0x57, 0xcd, 0xbb, 0xe4, 0x92, 0x08, 0x7e, 0xe3, 0x95, + 0x0f, 0x79, 0x26, 0x50, 0xca, 0xbc, 0x74, 0x02, 0x98, 0xee, + 0xb1, 0xc7, 0x5d, 0x2b, 0xd0, 0xa6, 0x3c, 0x4a, 0x15, 0x63, + 0xf9, 0x8f, 0x47, 0x31, 0xab, 0xdd, 0x82, 0xf4, 0x6e, 0x18, + 0x49, 0x3f, 0xa5, 0xd3, 0x8c, 0xfa, 0x60, 0x16, 0xde, 0xa8, + 0x32, 0x44, 0x1b, 0x6d, 0xf7, 0x81, 0x7a, 0x0c, 0x96, 0xe0, + 0xbf, 0xc9, 0x53, 0x25, 0xed, 0x9b, 0x01, 0x77, 0x28, 0x5e, + 0xc4, 0xb2, 0x2f, 0x59, 0xc3, 0xb5, 0xea, 0x9c, 0x06, 0x70, + 0xb8, 0xce, 0x54, 0x22, 0x7d, 0x0b, 0x91, 0xe7, 0x1c, 0x6a, + 0xf0, 0x86, 0xd9, 0xaf, 0x35, 0x43, 0x8b, 0xfd, 0x67, 0x11, + 0x4e, 0x38, 0xa2, 0xd4, 0x00, 0x77, 0xee, 0x99, 0xc1, 0xb6, + 0x2f, 0x58, 0x9f, 0xe8, 0x71, 0x06, 0x5e, 0x29, 0xb0, 0xc7, + 0x23, 0x54, 0xcd, 0xba, 0xe2, 0x95, 0x0c, 0x7b, 0xbc, 0xcb, + 0x52, 0x25, 0x7d, 0x0a, 0x93, 0xe4, 0x46, 0x31, 0xa8, 0xdf, + 0x87, 0xf0, 0x69, 0x1e, 0xd9, 0xae, 0x37, 0x40, 0x18, 0x6f, + 0xf6, 0x81, 0x65, 0x12, 0x8b, 0xfc, 0xa4, 0xd3, 0x4a, 0x3d, + 0xfa, 0x8d, 0x14, 0x63, 0x3b, 0x4c, 0xd5, 0xa2, 0x8c, 0xfb, + 0x62, 0x15, 0x4d, 0x3a, 0xa3, 0xd4, 0x13, 0x64, 0xfd, 0x8a, + 0xd2, 0xa5, 0x3c, 0x4b, 0xaf, 0xd8, 0x41, 0x36, 0x6e, 0x19, + 0x80, 0xf7, 0x30, 0x47, 0xde, 0xa9, 0xf1, 0x86, 0x1f, 0x68, + 0xca, 0xbd, 0x24, 0x53, 0x0b, 0x7c, 0xe5, 0x92, 0x55, 0x22, + 0xbb, 0xcc, 0x94, 0xe3, 0x7a, 0x0d, 0xe9, 0x9e, 0x07, 0x70, + 0x28, 0x5f, 0xc6, 0xb1, 0x76, 0x01, 0x98, 0xef, 0xb7, 0xc0, + 0x59, 0x2e, 0x05, 0x72, 0xeb, 0x9c, 0xc4, 0xb3, 0x2a, 0x5d, + 0x9a, 0xed, 0x74, 0x03, 0x5b, 0x2c, 0xb5, 0xc2, 0x26, 0x51, + 0xc8, 0xbf, 0xe7, 0x90, 0x09, 0x7e, 0xb9, 0xce, 0x57, 0x20, + 0x78, 0x0f, 0x96, 0xe1, 0x43, 0x34, 0xad, 0xda, 0x82, 0xf5, + 0x6c, 0x1b, 0xdc, 0xab, 0x32, 0x45, 0x1d, 0x6a, 0xf3, 0x84, + 0x60, 0x17, 0x8e, 0xf9, 0xa1, 0xd6, 0x4f, 0x38, 0xff, 0x88, + 0x11, 0x66, 0x3e, 0x49, 0xd0, 0xa7, 0x89, 0xfe, 0x67, 0x10, + 0x48, 0x3f, 0xa6, 0xd1, 0x16, 0x61, 0xf8, 0x8f, 0xd7, 0xa0, + 0x39, 0x4e, 0xaa, 0xdd, 0x44, 0x33, 0x6b, 0x1c, 0x85, 0xf2, + 0x35, 0x42, 0xdb, 0xac, 0xf4, 0x83, 0x1a, 0x6d, 0xcf, 0xb8, + 0x21, 0x56, 0x0e, 0x79, 0xe0, 0x97, 0x50, 0x27, 0xbe, 0xc9, + 0x91, 0xe6, 0x7f, 0x08, 0xec, 0x9b, 0x02, 0x75, 0x2d, 0x5a, + 0xc3, 0xb4, 0x73, 0x04, 0x9d, 0xea, 0xb2, 0xc5, 0x5c, 0x2b, + 0x00, 0x78, 0xf0, 0x88, 0xfd, 0x85, 0x0d, 0x75, 0xe7, 0x9f, + 0x17, 0x6f, 0x1a, 0x62, 0xea, 0x92, 0xd3, 0xab, 0x23, 0x5b, + 0x2e, 0x56, 0xde, 0xa6, 0x34, 0x4c, 0xc4, 0xbc, 0xc9, 0xb1, + 0x39, 0x41, 0xbb, 0xc3, 0x4b, 0x33, 0x46, 0x3e, 0xb6, 0xce, + 0x5c, 0x24, 0xac, 0xd4, 0xa1, 0xd9, 0x51, 0x29, 0x68, 0x10, + 0x98, 0xe0, 0x95, 0xed, 0x65, 0x1d, 0x8f, 0xf7, 0x7f, 0x07, + 0x72, 0x0a, 0x82, 0xfa, 0x6b, 0x13, 0x9b, 0xe3, 0x96, 0xee, + 0x66, 0x1e, 0x8c, 0xf4, 0x7c, 0x04, 0x71, 0x09, 0x81, 0xf9, + 0xb8, 0xc0, 0x48, 0x30, 0x45, 0x3d, 0xb5, 0xcd, 0x5f, 0x27, + 0xaf, 0xd7, 0xa2, 0xda, 0x52, 0x2a, 0xd0, 0xa8, 0x20, 0x58, + 0x2d, 0x55, 0xdd, 0xa5, 0x37, 0x4f, 0xc7, 0xbf, 0xca, 0xb2, + 0x3a, 0x42, 0x03, 0x7b, 0xf3, 0x8b, 0xfe, 0x86, 0x0e, 0x76, + 0xe4, 0x9c, 0x14, 0x6c, 0x19, 0x61, 0xe9, 0x91, 0xd6, 0xae, + 0x26, 0x5e, 0x2b, 0x53, 0xdb, 0xa3, 0x31, 0x49, 0xc1, 0xb9, + 0xcc, 0xb4, 0x3c, 0x44, 0x05, 0x7d, 0xf5, 0x8d, 0xf8, 0x80, + 0x08, 0x70, 0xe2, 0x9a, 0x12, 0x6a, 0x1f, 0x67, 0xef, 0x97, + 0x6d, 0x15, 0x9d, 0xe5, 0x90, 0xe8, 0x60, 0x18, 0x8a, 0xf2, + 0x7a, 0x02, 0x77, 0x0f, 0x87, 0xff, 0xbe, 0xc6, 0x4e, 0x36, + 0x43, 0x3b, 0xb3, 0xcb, 0x59, 0x21, 0xa9, 0xd1, 0xa4, 0xdc, + 0x54, 0x2c, 0xbd, 0xc5, 0x4d, 0x35, 0x40, 0x38, 0xb0, 0xc8, + 0x5a, 0x22, 0xaa, 0xd2, 0xa7, 0xdf, 0x57, 0x2f, 0x6e, 0x16, + 0x9e, 0xe6, 0x93, 0xeb, 0x63, 0x1b, 0x89, 0xf1, 0x79, 0x01, + 0x74, 0x0c, 0x84, 0xfc, 0x06, 0x7e, 0xf6, 0x8e, 0xfb, 0x83, + 0x0b, 0x73, 0xe1, 0x99, 0x11, 0x69, 0x1c, 0x64, 0xec, 0x94, + 0xd5, 0xad, 0x25, 0x5d, 0x28, 0x50, 0xd8, 0xa0, 0x32, 0x4a, + 0xc2, 0xba, 0xcf, 0xb7, 0x3f, 0x47, 0x00, 0x79, 0xf2, 0x8b, + 0xf9, 0x80, 0x0b, 0x72, 0xef, 0x96, 0x1d, 0x64, 0x16, 0x6f, + 0xe4, 0x9d, 0xc3, 0xba, 0x31, 0x48, 0x3a, 0x43, 0xc8, 0xb1, + 0x2c, 0x55, 0xde, 0xa7, 0xd5, 0xac, 0x27, 0x5e, 0x9b, 0xe2, + 0x69, 0x10, 0x62, 0x1b, 0x90, 0xe9, 0x74, 0x0d, 0x86, 0xff, + 0x8d, 0xf4, 0x7f, 0x06, 0x58, 0x21, 0xaa, 0xd3, 0xa1, 0xd8, + 0x53, 0x2a, 0xb7, 0xce, 0x45, 0x3c, 0x4e, 0x37, 0xbc, 0xc5, + 0x2b, 0x52, 0xd9, 0xa0, 0xd2, 0xab, 0x20, 0x59, 0xc4, 0xbd, + 0x36, 0x4f, 0x3d, 0x44, 0xcf, 0xb6, 0xe8, 0x91, 0x1a, 0x63, + 0x11, 0x68, 0xe3, 0x9a, 0x07, 0x7e, 0xf5, 0x8c, 0xfe, 0x87, + 0x0c, 0x75, 0xb0, 0xc9, 0x42, 0x3b, 0x49, 0x30, 0xbb, 0xc2, + 0x5f, 0x26, 0xad, 0xd4, 0xa6, 0xdf, 0x54, 0x2d, 0x73, 0x0a, + 0x81, 0xf8, 0x8a, 0xf3, 0x78, 0x01, 0x9c, 0xe5, 0x6e, 0x17, + 0x65, 0x1c, 0x97, 0xee, 0x56, 0x2f, 0xa4, 0xdd, 0xaf, 0xd6, + 0x5d, 0x24, 0xb9, 0xc0, 0x4b, 0x32, 0x40, 0x39, 0xb2, 0xcb, + 0x95, 0xec, 0x67, 0x1e, 0x6c, 0x15, 0x9e, 0xe7, 0x7a, 0x03, + 0x88, 0xf1, 0x83, 0xfa, 0x71, 0x08, 0xcd, 0xb4, 0x3f, 0x46, + 0x34, 0x4d, 0xc6, 0xbf, 0x22, 0x5b, 0xd0, 0xa9, 0xdb, 0xa2, + 0x29, 0x50, 0x0e, 0x77, 0xfc, 0x85, 0xf7, 0x8e, 0x05, 0x7c, + 0xe1, 0x98, 0x13, 0x6a, 0x18, 0x61, 0xea, 0x93, 0x7d, 0x04, + 0x8f, 0xf6, 0x84, 0xfd, 0x76, 0x0f, 0x92, 0xeb, 0x60, 0x19, + 0x6b, 0x12, 0x99, 0xe0, 0xbe, 0xc7, 0x4c, 0x35, 0x47, 0x3e, + 0xb5, 0xcc, 0x51, 0x28, 0xa3, 0xda, 0xa8, 0xd1, 0x5a, 0x23, + 0xe6, 0x9f, 0x14, 0x6d, 0x1f, 0x66, 0xed, 0x94, 0x09, 0x70, + 0xfb, 0x82, 0xf0, 0x89, 0x02, 0x7b, 0x25, 0x5c, 0xd7, 0xae, + 0xdc, 0xa5, 0x2e, 0x57, 0xca, 0xb3, 0x38, 0x41, 0x33, 0x4a, + 0xc1, 0xb8, 0x00, 0x7a, 0xf4, 0x8e, 0xf5, 0x8f, 0x01, 0x7b, + 0xf7, 0x8d, 0x03, 0x79, 0x02, 0x78, 0xf6, 0x8c, 0xf3, 0x89, + 0x07, 0x7d, 0x06, 0x7c, 0xf2, 0x88, 0x04, 0x7e, 0xf0, 0x8a, + 0xf1, 0x8b, 0x05, 0x7f, 0xfb, 0x81, 0x0f, 0x75, 0x0e, 0x74, + 0xfa, 0x80, 0x0c, 0x76, 0xf8, 0x82, 0xf9, 0x83, 0x0d, 0x77, + 0x08, 0x72, 0xfc, 0x86, 0xfd, 0x87, 0x09, 0x73, 0xff, 0x85, + 0x0b, 0x71, 0x0a, 0x70, 0xfe, 0x84, 0xeb, 0x91, 0x1f, 0x65, + 0x1e, 0x64, 0xea, 0x90, 0x1c, 0x66, 0xe8, 0x92, 0xe9, 0x93, + 0x1d, 0x67, 0x18, 0x62, 0xec, 0x96, 0xed, 0x97, 0x19, 0x63, + 0xef, 0x95, 0x1b, 0x61, 0x1a, 0x60, 0xee, 0x94, 0x10, 0x6a, + 0xe4, 0x9e, 0xe5, 0x9f, 0x11, 0x6b, 0xe7, 0x9d, 0x13, 0x69, + 0x12, 0x68, 0xe6, 0x9c, 0xe3, 0x99, 0x17, 0x6d, 0x16, 0x6c, + 0xe2, 0x98, 0x14, 0x6e, 0xe0, 0x9a, 0xe1, 0x9b, 0x15, 0x6f, + 0xcb, 0xb1, 0x3f, 0x45, 0x3e, 0x44, 0xca, 0xb0, 0x3c, 0x46, + 0xc8, 0xb2, 0xc9, 0xb3, 0x3d, 0x47, 0x38, 0x42, 0xcc, 0xb6, + 0xcd, 0xb7, 0x39, 0x43, 0xcf, 0xb5, 0x3b, 0x41, 0x3a, 0x40, + 0xce, 0xb4, 0x30, 0x4a, 0xc4, 0xbe, 0xc5, 0xbf, 0x31, 0x4b, + 0xc7, 0xbd, 0x33, 0x49, 0x32, 0x48, 0xc6, 0xbc, 0xc3, 0xb9, + 0x37, 0x4d, 0x36, 0x4c, 0xc2, 0xb8, 0x34, 0x4e, 0xc0, 0xba, + 0xc1, 0xbb, 0x35, 0x4f, 0x20, 0x5a, 0xd4, 0xae, 0xd5, 0xaf, + 0x21, 0x5b, 0xd7, 0xad, 0x23, 0x59, 0x22, 0x58, 0xd6, 0xac, + 0xd3, 0xa9, 0x27, 0x5d, 0x26, 0x5c, 0xd2, 0xa8, 0x24, 0x5e, + 0xd0, 0xaa, 0xd1, 0xab, 0x25, 0x5f, 0xdb, 0xa1, 0x2f, 0x55, + 0x2e, 0x54, 0xda, 0xa0, 0x2c, 0x56, 0xd8, 0xa2, 0xd9, 0xa3, + 0x2d, 0x57, 0x28, 0x52, 0xdc, 0xa6, 0xdd, 0xa7, 0x29, 0x53, + 0xdf, 0xa5, 0x2b, 0x51, 0x2a, 0x50, 0xde, 0xa4, 0x00, 0x7b, + 0xf6, 0x8d, 0xf1, 0x8a, 0x07, 0x7c, 0xff, 0x84, 0x09, 0x72, + 0x0e, 0x75, 0xf8, 0x83, 0xe3, 0x98, 0x15, 0x6e, 0x12, 0x69, + 0xe4, 0x9f, 0x1c, 0x67, 0xea, 0x91, 0xed, 0x96, 0x1b, 0x60, + 0xdb, 0xa0, 0x2d, 0x56, 0x2a, 0x51, 0xdc, 0xa7, 0x24, 0x5f, + 0xd2, 0xa9, 0xd5, 0xae, 0x23, 0x58, 0x38, 0x43, 0xce, 0xb5, + 0xc9, 0xb2, 0x3f, 0x44, 0xc7, 0xbc, 0x31, 0x4a, 0x36, 0x4d, + 0xc0, 0xbb, 0xab, 0xd0, 0x5d, 0x26, 0x5a, 0x21, 0xac, 0xd7, + 0x54, 0x2f, 0xa2, 0xd9, 0xa5, 0xde, 0x53, 0x28, 0x48, 0x33, + 0xbe, 0xc5, 0xb9, 0xc2, 0x4f, 0x34, 0xb7, 0xcc, 0x41, 0x3a, + 0x46, 0x3d, 0xb0, 0xcb, 0x70, 0x0b, 0x86, 0xfd, 0x81, 0xfa, + 0x77, 0x0c, 0x8f, 0xf4, 0x79, 0x02, 0x7e, 0x05, 0x88, 0xf3, + 0x93, 0xe8, 0x65, 0x1e, 0x62, 0x19, 0x94, 0xef, 0x6c, 0x17, + 0x9a, 0xe1, 0x9d, 0xe6, 0x6b, 0x10, 0x4b, 0x30, 0xbd, 0xc6, + 0xba, 0xc1, 0x4c, 0x37, 0xb4, 0xcf, 0x42, 0x39, 0x45, 0x3e, + 0xb3, 0xc8, 0xa8, 0xd3, 0x5e, 0x25, 0x59, 0x22, 0xaf, 0xd4, + 0x57, 0x2c, 0xa1, 0xda, 0xa6, 0xdd, 0x50, 0x2b, 0x90, 0xeb, + 0x66, 0x1d, 0x61, 0x1a, 0x97, 0xec, 0x6f, 0x14, 0x99, 0xe2, + 0x9e, 0xe5, 0x68, 0x13, 0x73, 0x08, 0x85, 0xfe, 0x82, 0xf9, + 0x74, 0x0f, 0x8c, 0xf7, 0x7a, 0x01, 0x7d, 0x06, 0x8b, 0xf0, + 0xe0, 0x9b, 0x16, 0x6d, 0x11, 0x6a, 0xe7, 0x9c, 0x1f, 0x64, + 0xe9, 0x92, 0xee, 0x95, 0x18, 0x63, 0x03, 0x78, 0xf5, 0x8e, + 0xf2, 0x89, 0x04, 0x7f, 0xfc, 0x87, 0x0a, 0x71, 0x0d, 0x76, + 0xfb, 0x80, 0x3b, 0x40, 0xcd, 0xb6, 0xca, 0xb1, 0x3c, 0x47, + 0xc4, 0xbf, 0x32, 0x49, 0x35, 0x4e, 0xc3, 0xb8, 0xd8, 0xa3, + 0x2e, 0x55, 0x29, 0x52, 0xdf, 0xa4, 0x27, 0x5c, 0xd1, 0xaa, + 0xd6, 0xad, 0x20, 0x5b, 0x00, 0x7c, 0xf8, 0x84, 0xed, 0x91, + 0x15, 0x69, 0xc7, 0xbb, 0x3f, 0x43, 0x2a, 0x56, 0xd2, 0xae, + 0x93, 0xef, 0x6b, 0x17, 0x7e, 0x02, 0x86, 0xfa, 0x54, 0x28, + 0xac, 0xd0, 0xb9, 0xc5, 0x41, 0x3d, 0x3b, 0x47, 0xc3, 0xbf, + 0xd6, 0xaa, 0x2e, 0x52, 0xfc, 0x80, 0x04, 0x78, 0x11, 0x6d, + 0xe9, 0x95, 0xa8, 0xd4, 0x50, 0x2c, 0x45, 0x39, 0xbd, 0xc1, + 0x6f, 0x13, 0x97, 0xeb, 0x82, 0xfe, 0x7a, 0x06, 0x76, 0x0a, + 0x8e, 0xf2, 0x9b, 0xe7, 0x63, 0x1f, 0xb1, 0xcd, 0x49, 0x35, + 0x5c, 0x20, 0xa4, 0xd8, 0xe5, 0x99, 0x1d, 0x61, 0x08, 0x74, + 0xf0, 0x8c, 0x22, 0x5e, 0xda, 0xa6, 0xcf, 0xb3, 0x37, 0x4b, + 0x4d, 0x31, 0xb5, 0xc9, 0xa0, 0xdc, 0x58, 0x24, 0x8a, 0xf6, + 0x72, 0x0e, 0x67, 0x1b, 0x9f, 0xe3, 0xde, 0xa2, 0x26, 0x5a, + 0x33, 0x4f, 0xcb, 0xb7, 0x19, 0x65, 0xe1, 0x9d, 0xf4, 0x88, + 0x0c, 0x70, 0xec, 0x90, 0x14, 0x68, 0x01, 0x7d, 0xf9, 0x85, + 0x2b, 0x57, 0xd3, 0xaf, 0xc6, 0xba, 0x3e, 0x42, 0x7f, 0x03, + 0x87, 0xfb, 0x92, 0xee, 0x6a, 0x16, 0xb8, 0xc4, 0x40, 0x3c, + 0x55, 0x29, 0xad, 0xd1, 0xd7, 0xab, 0x2f, 0x53, 0x3a, 0x46, + 0xc2, 0xbe, 0x10, 0x6c, 0xe8, 0x94, 0xfd, 0x81, 0x05, 0x79, + 0x44, 0x38, 0xbc, 0xc0, 0xa9, 0xd5, 0x51, 0x2d, 0x83, 0xff, + 0x7b, 0x07, 0x6e, 0x12, 0x96, 0xea, 0x9a, 0xe6, 0x62, 0x1e, + 0x77, 0x0b, 0x8f, 0xf3, 0x5d, 0x21, 0xa5, 0xd9, 0xb0, 0xcc, + 0x48, 0x34, 0x09, 0x75, 0xf1, 0x8d, 0xe4, 0x98, 0x1c, 0x60, + 0xce, 0xb2, 0x36, 0x4a, 0x23, 0x5f, 0xdb, 0xa7, 0xa1, 0xdd, + 0x59, 0x25, 0x4c, 0x30, 0xb4, 0xc8, 0x66, 0x1a, 0x9e, 0xe2, + 0x8b, 0xf7, 0x73, 0x0f, 0x32, 0x4e, 0xca, 0xb6, 0xdf, 0xa3, + 0x27, 0x5b, 0xf5, 0x89, 0x0d, 0x71, 0x18, 0x64, 0xe0, 0x9c, + 0x00, 0x7d, 0xfa, 0x87, 0xe9, 0x94, 0x13, 0x6e, 0xcf, 0xb2, + 0x35, 0x48, 0x26, 0x5b, 0xdc, 0xa1, 0x83, 0xfe, 0x79, 0x04, + 0x6a, 0x17, 0x90, 0xed, 0x4c, 0x31, 0xb6, 0xcb, 0xa5, 0xd8, + 0x5f, 0x22, 0x1b, 0x66, 0xe1, 0x9c, 0xf2, 0x8f, 0x08, 0x75, + 0xd4, 0xa9, 0x2e, 0x53, 0x3d, 0x40, 0xc7, 0xba, 0x98, 0xe5, + 0x62, 0x1f, 0x71, 0x0c, 0x8b, 0xf6, 0x57, 0x2a, 0xad, 0xd0, + 0xbe, 0xc3, 0x44, 0x39, 0x36, 0x4b, 0xcc, 0xb1, 0xdf, 0xa2, + 0x25, 0x58, 0xf9, 0x84, 0x03, 0x7e, 0x10, 0x6d, 0xea, 0x97, + 0xb5, 0xc8, 0x4f, 0x32, 0x5c, 0x21, 0xa6, 0xdb, 0x7a, 0x07, + 0x80, 0xfd, 0x93, 0xee, 0x69, 0x14, 0x2d, 0x50, 0xd7, 0xaa, + 0xc4, 0xb9, 0x3e, 0x43, 0xe2, 0x9f, 0x18, 0x65, 0x0b, 0x76, + 0xf1, 0x8c, 0xae, 0xd3, 0x54, 0x29, 0x47, 0x3a, 0xbd, 0xc0, + 0x61, 0x1c, 0x9b, 0xe6, 0x88, 0xf5, 0x72, 0x0f, 0x6c, 0x11, + 0x96, 0xeb, 0x85, 0xf8, 0x7f, 0x02, 0xa3, 0xde, 0x59, 0x24, + 0x4a, 0x37, 0xb0, 0xcd, 0xef, 0x92, 0x15, 0x68, 0x06, 0x7b, + 0xfc, 0x81, 0x20, 0x5d, 0xda, 0xa7, 0xc9, 0xb4, 0x33, 0x4e, + 0x77, 0x0a, 0x8d, 0xf0, 0x9e, 0xe3, 0x64, 0x19, 0xb8, 0xc5, + 0x42, 0x3f, 0x51, 0x2c, 0xab, 0xd6, 0xf4, 0x89, 0x0e, 0x73, + 0x1d, 0x60, 0xe7, 0x9a, 0x3b, 0x46, 0xc1, 0xbc, 0xd2, 0xaf, + 0x28, 0x55, 0x5a, 0x27, 0xa0, 0xdd, 0xb3, 0xce, 0x49, 0x34, + 0x95, 0xe8, 0x6f, 0x12, 0x7c, 0x01, 0x86, 0xfb, 0xd9, 0xa4, + 0x23, 0x5e, 0x30, 0x4d, 0xca, 0xb7, 0x16, 0x6b, 0xec, 0x91, + 0xff, 0x82, 0x05, 0x78, 0x41, 0x3c, 0xbb, 0xc6, 0xa8, 0xd5, + 0x52, 0x2f, 0x8e, 0xf3, 0x74, 0x09, 0x67, 0x1a, 0x9d, 0xe0, + 0xc2, 0xbf, 0x38, 0x45, 0x2b, 0x56, 0xd1, 0xac, 0x0d, 0x70, + 0xf7, 0x8a, 0xe4, 0x99, 0x1e, 0x63, 0x00, 0x7e, 0xfc, 0x82, + 0xe5, 0x9b, 0x19, 0x67, 0xd7, 0xa9, 0x2b, 0x55, 0x32, 0x4c, + 0xce, 0xb0, 0xb3, 0xcd, 0x4f, 0x31, 0x56, 0x28, 0xaa, 0xd4, + 0x64, 0x1a, 0x98, 0xe6, 0x81, 0xff, 0x7d, 0x03, 0x7b, 0x05, + 0x87, 0xf9, 0x9e, 0xe0, 0x62, 0x1c, 0xac, 0xd2, 0x50, 0x2e, + 0x49, 0x37, 0xb5, 0xcb, 0xc8, 0xb6, 0x34, 0x4a, 0x2d, 0x53, + 0xd1, 0xaf, 0x1f, 0x61, 0xe3, 0x9d, 0xfa, 0x84, 0x06, 0x78, + 0xf6, 0x88, 0x0a, 0x74, 0x13, 0x6d, 0xef, 0x91, 0x21, 0x5f, + 0xdd, 0xa3, 0xc4, 0xba, 0x38, 0x46, 0x45, 0x3b, 0xb9, 0xc7, + 0xa0, 0xde, 0x5c, 0x22, 0x92, 0xec, 0x6e, 0x10, 0x77, 0x09, + 0x8b, 0xf5, 0x8d, 0xf3, 0x71, 0x0f, 0x68, 0x16, 0x94, 0xea, + 0x5a, 0x24, 0xa6, 0xd8, 0xbf, 0xc1, 0x43, 0x3d, 0x3e, 0x40, + 0xc2, 0xbc, 0xdb, 0xa5, 0x27, 0x59, 0xe9, 0x97, 0x15, 0x6b, + 0x0c, 0x72, 0xf0, 0x8e, 0xf1, 0x8f, 0x0d, 0x73, 0x14, 0x6a, + 0xe8, 0x96, 0x26, 0x58, 0xda, 0xa4, 0xc3, 0xbd, 0x3f, 0x41, + 0x42, 0x3c, 0xbe, 0xc0, 0xa7, 0xd9, 0x5b, 0x25, 0x95, 0xeb, + 0x69, 0x17, 0x70, 0x0e, 0x8c, 0xf2, 0x8a, 0xf4, 0x76, 0x08, + 0x6f, 0x11, 0x93, 0xed, 0x5d, 0x23, 0xa1, 0xdf, 0xb8, 0xc6, + 0x44, 0x3a, 0x39, 0x47, 0xc5, 0xbb, 0xdc, 0xa2, 0x20, 0x5e, + 0xee, 0x90, 0x12, 0x6c, 0x0b, 0x75, 0xf7, 0x89, 0x07, 0x79, + 0xfb, 0x85, 0xe2, 0x9c, 0x1e, 0x60, 0xd0, 0xae, 0x2c, 0x52, + 0x35, 0x4b, 0xc9, 0xb7, 0xb4, 0xca, 0x48, 0x36, 0x51, 0x2f, + 0xad, 0xd3, 0x63, 0x1d, 0x9f, 0xe1, 0x86, 0xf8, 0x7a, 0x04, + 0x7c, 0x02, 0x80, 0xfe, 0x99, 0xe7, 0x65, 0x1b, 0xab, 0xd5, + 0x57, 0x29, 0x4e, 0x30, 0xb2, 0xcc, 0xcf, 0xb1, 0x33, 0x4d, + 0x2a, 0x54, 0xd6, 0xa8, 0x18, 0x66, 0xe4, 0x9a, 0xfd, 0x83, + 0x01, 0x7f, 0x00, 0x7f, 0xfe, 0x81, 0xe1, 0x9e, 0x1f, 0x60, + 0xdf, 0xa0, 0x21, 0x5e, 0x3e, 0x41, 0xc0, 0xbf, 0xa3, 0xdc, + 0x5d, 0x22, 0x42, 0x3d, 0xbc, 0xc3, 0x7c, 0x03, 0x82, 0xfd, + 0x9d, 0xe2, 0x63, 0x1c, 0x5b, 0x24, 0xa5, 0xda, 0xba, 0xc5, + 0x44, 0x3b, 0x84, 0xfb, 0x7a, 0x05, 0x65, 0x1a, 0x9b, 0xe4, + 0xf8, 0x87, 0x06, 0x79, 0x19, 0x66, 0xe7, 0x98, 0x27, 0x58, + 0xd9, 0xa6, 0xc6, 0xb9, 0x38, 0x47, 0xb6, 0xc9, 0x48, 0x37, + 0x57, 0x28, 0xa9, 0xd6, 0x69, 0x16, 0x97, 0xe8, 0x88, 0xf7, + 0x76, 0x09, 0x15, 0x6a, 0xeb, 0x94, 0xf4, 0x8b, 0x0a, 0x75, + 0xca, 0xb5, 0x34, 0x4b, 0x2b, 0x54, 0xd5, 0xaa, 0xed, 0x92, + 0x13, 0x6c, 0x0c, 0x73, 0xf2, 0x8d, 0x32, 0x4d, 0xcc, 0xb3, + 0xd3, 0xac, 0x2d, 0x52, 0x4e, 0x31, 0xb0, 0xcf, 0xaf, 0xd0, + 0x51, 0x2e, 0x91, 0xee, 0x6f, 0x10, 0x70, 0x0f, 0x8e, 0xf1, + 0x71, 0x0e, 0x8f, 0xf0, 0x90, 0xef, 0x6e, 0x11, 0xae, 0xd1, + 0x50, 0x2f, 0x4f, 0x30, 0xb1, 0xce, 0xd2, 0xad, 0x2c, 0x53, + 0x33, 0x4c, 0xcd, 0xb2, 0x0d, 0x72, 0xf3, 0x8c, 0xec, 0x93, + 0x12, 0x6d, 0x2a, 0x55, 0xd4, 0xab, 0xcb, 0xb4, 0x35, 0x4a, + 0xf5, 0x8a, 0x0b, 0x74, 0x14, 0x6b, 0xea, 0x95, 0x89, 0xf6, + 0x77, 0x08, 0x68, 0x17, 0x96, 0xe9, 0x56, 0x29, 0xa8, 0xd7, + 0xb7, 0xc8, 0x49, 0x36, 0xc7, 0xb8, 0x39, 0x46, 0x26, 0x59, + 0xd8, 0xa7, 0x18, 0x67, 0xe6, 0x99, 0xf9, 0x86, 0x07, 0x78, + 0x64, 0x1b, 0x9a, 0xe5, 0x85, 0xfa, 0x7b, 0x04, 0xbb, 0xc4, + 0x45, 0x3a, 0x5a, 0x25, 0xa4, 0xdb, 0x9c, 0xe3, 0x62, 0x1d, + 0x7d, 0x02, 0x83, 0xfc, 0x43, 0x3c, 0xbd, 0xc2, 0xa2, 0xdd, + 0x5c, 0x23, 0x3f, 0x40, 0xc1, 0xbe, 0xde, 0xa1, 0x20, 0x5f, + 0xe0, 0x9f, 0x1e, 0x61, 0x01, 0x7e, 0xff, 0x80, 0x00, 0x80, + 0x1d, 0x9d, 0x3a, 0xba, 0x27, 0xa7, 0x74, 0xf4, 0x69, 0xe9, + 0x4e, 0xce, 0x53, 0xd3, 0xe8, 0x68, 0xf5, 0x75, 0xd2, 0x52, + 0xcf, 0x4f, 0x9c, 0x1c, 0x81, 0x01, 0xa6, 0x26, 0xbb, 0x3b, + 0xcd, 0x4d, 0xd0, 0x50, 0xf7, 0x77, 0xea, 0x6a, 0xb9, 0x39, + 0xa4, 0x24, 0x83, 0x03, 0x9e, 0x1e, 0x25, 0xa5, 0x38, 0xb8, + 0x1f, 0x9f, 0x02, 0x82, 0x51, 0xd1, 0x4c, 0xcc, 0x6b, 0xeb, + 0x76, 0xf6, 0x87, 0x07, 0x9a, 0x1a, 0xbd, 0x3d, 0xa0, 0x20, + 0xf3, 0x73, 0xee, 0x6e, 0xc9, 0x49, 0xd4, 0x54, 0x6f, 0xef, + 0x72, 0xf2, 0x55, 0xd5, 0x48, 0xc8, 0x1b, 0x9b, 0x06, 0x86, + 0x21, 0xa1, 0x3c, 0xbc, 0x4a, 0xca, 0x57, 0xd7, 0x70, 0xf0, + 0x6d, 0xed, 0x3e, 0xbe, 0x23, 0xa3, 0x04, 0x84, 0x19, 0x99, + 0xa2, 0x22, 0xbf, 0x3f, 0x98, 0x18, 0x85, 0x05, 0xd6, 0x56, + 0xcb, 0x4b, 0xec, 0x6c, 0xf1, 0x71, 0x13, 0x93, 0x0e, 0x8e, + 0x29, 0xa9, 0x34, 0xb4, 0x67, 0xe7, 0x7a, 0xfa, 0x5d, 0xdd, + 0x40, 0xc0, 0xfb, 0x7b, 0xe6, 0x66, 0xc1, 0x41, 0xdc, 0x5c, + 0x8f, 0x0f, 0x92, 0x12, 0xb5, 0x35, 0xa8, 0x28, 0xde, 0x5e, + 0xc3, 0x43, 0xe4, 0x64, 0xf9, 0x79, 0xaa, 0x2a, 0xb7, 0x37, + 0x90, 0x10, 0x8d, 0x0d, 0x36, 0xb6, 0x2b, 0xab, 0x0c, 0x8c, + 0x11, 0x91, 0x42, 0xc2, 0x5f, 0xdf, 0x78, 0xf8, 0x65, 0xe5, + 0x94, 0x14, 0x89, 0x09, 0xae, 0x2e, 0xb3, 0x33, 0xe0, 0x60, + 0xfd, 0x7d, 0xda, 0x5a, 0xc7, 0x47, 0x7c, 0xfc, 0x61, 0xe1, + 0x46, 0xc6, 0x5b, 0xdb, 0x08, 0x88, 0x15, 0x95, 0x32, 0xb2, + 0x2f, 0xaf, 0x59, 0xd9, 0x44, 0xc4, 0x63, 0xe3, 0x7e, 0xfe, + 0x2d, 0xad, 0x30, 0xb0, 0x17, 0x97, 0x0a, 0x8a, 0xb1, 0x31, + 0xac, 0x2c, 0x8b, 0x0b, 0x96, 0x16, 0xc5, 0x45, 0xd8, 0x58, + 0xff, 0x7f, 0xe2, 0x62, 0x00, 0x81, 0x1f, 0x9e, 0x3e, 0xbf, + 0x21, 0xa0, 0x7c, 0xfd, 0x63, 0xe2, 0x42, 0xc3, 0x5d, 0xdc, + 0xf8, 0x79, 0xe7, 0x66, 0xc6, 0x47, 0xd9, 0x58, 0x84, 0x05, + 0x9b, 0x1a, 0xba, 0x3b, 0xa5, 0x24, 0xed, 0x6c, 0xf2, 0x73, + 0xd3, 0x52, 0xcc, 0x4d, 0x91, 0x10, 0x8e, 0x0f, 0xaf, 0x2e, + 0xb0, 0x31, 0x15, 0x94, 0x0a, 0x8b, 0x2b, 0xaa, 0x34, 0xb5, + 0x69, 0xe8, 0x76, 0xf7, 0x57, 0xd6, 0x48, 0xc9, 0xc7, 0x46, + 0xd8, 0x59, 0xf9, 0x78, 0xe6, 0x67, 0xbb, 0x3a, 0xa4, 0x25, + 0x85, 0x04, 0x9a, 0x1b, 0x3f, 0xbe, 0x20, 0xa1, 0x01, 0x80, + 0x1e, 0x9f, 0x43, 0xc2, 0x5c, 0xdd, 0x7d, 0xfc, 0x62, 0xe3, + 0x2a, 0xab, 0x35, 0xb4, 0x14, 0x95, 0x0b, 0x8a, 0x56, 0xd7, + 0x49, 0xc8, 0x68, 0xe9, 0x77, 0xf6, 0xd2, 0x53, 0xcd, 0x4c, + 0xec, 0x6d, 0xf3, 0x72, 0xae, 0x2f, 0xb1, 0x30, 0x90, 0x11, + 0x8f, 0x0e, 0x93, 0x12, 0x8c, 0x0d, 0xad, 0x2c, 0xb2, 0x33, + 0xef, 0x6e, 0xf0, 0x71, 0xd1, 0x50, 0xce, 0x4f, 0x6b, 0xea, + 0x74, 0xf5, 0x55, 0xd4, 0x4a, 0xcb, 0x17, 0x96, 0x08, 0x89, + 0x29, 0xa8, 0x36, 0xb7, 0x7e, 0xff, 0x61, 0xe0, 0x40, 0xc1, + 0x5f, 0xde, 0x02, 0x83, 0x1d, 0x9c, 0x3c, 0xbd, 0x23, 0xa2, + 0x86, 0x07, 0x99, 0x18, 0xb8, 0x39, 0xa7, 0x26, 0xfa, 0x7b, + 0xe5, 0x64, 0xc4, 0x45, 0xdb, 0x5a, 0x54, 0xd5, 0x4b, 0xca, + 0x6a, 0xeb, 0x75, 0xf4, 0x28, 0xa9, 0x37, 0xb6, 0x16, 0x97, + 0x09, 0x88, 0xac, 0x2d, 0xb3, 0x32, 0x92, 0x13, 0x8d, 0x0c, + 0xd0, 0x51, 0xcf, 0x4e, 0xee, 0x6f, 0xf1, 0x70, 0xb9, 0x38, + 0xa6, 0x27, 0x87, 0x06, 0x98, 0x19, 0xc5, 0x44, 0xda, 0x5b, + 0xfb, 0x7a, 0xe4, 0x65, 0x41, 0xc0, 0x5e, 0xdf, 0x7f, 0xfe, + 0x60, 0xe1, 0x3d, 0xbc, 0x22, 0xa3, 0x03, 0x82, 0x1c, 0x9d, + 0x00, 0x82, 0x19, 0x9b, 0x32, 0xb0, 0x2b, 0xa9, 0x64, 0xe6, + 0x7d, 0xff, 0x56, 0xd4, 0x4f, 0xcd, 0xc8, 0x4a, 0xd1, 0x53, + 0xfa, 0x78, 0xe3, 0x61, 0xac, 0x2e, 0xb5, 0x37, 0x9e, 0x1c, + 0x87, 0x05, 0x8d, 0x0f, 0x94, 0x16, 0xbf, 0x3d, 0xa6, 0x24, + 0xe9, 0x6b, 0xf0, 0x72, 0xdb, 0x59, 0xc2, 0x40, 0x45, 0xc7, + 0x5c, 0xde, 0x77, 0xf5, 0x6e, 0xec, 0x21, 0xa3, 0x38, 0xba, + 0x13, 0x91, 0x0a, 0x88, 0x07, 0x85, 0x1e, 0x9c, 0x35, 0xb7, + 0x2c, 0xae, 0x63, 0xe1, 0x7a, 0xf8, 0x51, 0xd3, 0x48, 0xca, + 0xcf, 0x4d, 0xd6, 0x54, 0xfd, 0x7f, 0xe4, 0x66, 0xab, 0x29, + 0xb2, 0x30, 0x99, 0x1b, 0x80, 0x02, 0x8a, 0x08, 0x93, 0x11, + 0xb8, 0x3a, 0xa1, 0x23, 0xee, 0x6c, 0xf7, 0x75, 0xdc, 0x5e, + 0xc5, 0x47, 0x42, 0xc0, 0x5b, 0xd9, 0x70, 0xf2, 0x69, 0xeb, + 0x26, 0xa4, 0x3f, 0xbd, 0x14, 0x96, 0x0d, 0x8f, 0x0e, 0x8c, + 0x17, 0x95, 0x3c, 0xbe, 0x25, 0xa7, 0x6a, 0xe8, 0x73, 0xf1, + 0x58, 0xda, 0x41, 0xc3, 0xc6, 0x44, 0xdf, 0x5d, 0xf4, 0x76, + 0xed, 0x6f, 0xa2, 0x20, 0xbb, 0x39, 0x90, 0x12, 0x89, 0x0b, + 0x83, 0x01, 0x9a, 0x18, 0xb1, 0x33, 0xa8, 0x2a, 0xe7, 0x65, + 0xfe, 0x7c, 0xd5, 0x57, 0xcc, 0x4e, 0x4b, 0xc9, 0x52, 0xd0, + 0x79, 0xfb, 0x60, 0xe2, 0x2f, 0xad, 0x36, 0xb4, 0x1d, 0x9f, + 0x04, 0x86, 0x09, 0x8b, 0x10, 0x92, 0x3b, 0xb9, 0x22, 0xa0, + 0x6d, 0xef, 0x74, 0xf6, 0x5f, 0xdd, 0x46, 0xc4, 0xc1, 0x43, + 0xd8, 0x5a, 0xf3, 0x71, 0xea, 0x68, 0xa5, 0x27, 0xbc, 0x3e, + 0x97, 0x15, 0x8e, 0x0c, 0x84, 0x06, 0x9d, 0x1f, 0xb6, 0x34, + 0xaf, 0x2d, 0xe0, 0x62, 0xf9, 0x7b, 0xd2, 0x50, 0xcb, 0x49, + 0x4c, 0xce, 0x55, 0xd7, 0x7e, 0xfc, 0x67, 0xe5, 0x28, 0xaa, + 0x31, 0xb3, 0x1a, 0x98, 0x03, 0x81, 0x00, 0x83, 0x1b, 0x98, + 0x36, 0xb5, 0x2d, 0xae, 0x6c, 0xef, 0x77, 0xf4, 0x5a, 0xd9, + 0x41, 0xc2, 0xd8, 0x5b, 0xc3, 0x40, 0xee, 0x6d, 0xf5, 0x76, + 0xb4, 0x37, 0xaf, 0x2c, 0x82, 0x01, 0x99, 0x1a, 0xad, 0x2e, + 0xb6, 0x35, 0x9b, 0x18, 0x80, 0x03, 0xc1, 0x42, 0xda, 0x59, + 0xf7, 0x74, 0xec, 0x6f, 0x75, 0xf6, 0x6e, 0xed, 0x43, 0xc0, + 0x58, 0xdb, 0x19, 0x9a, 0x02, 0x81, 0x2f, 0xac, 0x34, 0xb7, + 0x47, 0xc4, 0x5c, 0xdf, 0x71, 0xf2, 0x6a, 0xe9, 0x2b, 0xa8, + 0x30, 0xb3, 0x1d, 0x9e, 0x06, 0x85, 0x9f, 0x1c, 0x84, 0x07, + 0xa9, 0x2a, 0xb2, 0x31, 0xf3, 0x70, 0xe8, 0x6b, 0xc5, 0x46, + 0xde, 0x5d, 0xea, 0x69, 0xf1, 0x72, 0xdc, 0x5f, 0xc7, 0x44, + 0x86, 0x05, 0x9d, 0x1e, 0xb0, 0x33, 0xab, 0x28, 0x32, 0xb1, + 0x29, 0xaa, 0x04, 0x87, 0x1f, 0x9c, 0x5e, 0xdd, 0x45, 0xc6, + 0x68, 0xeb, 0x73, 0xf0, 0x8e, 0x0d, 0x95, 0x16, 0xb8, 0x3b, + 0xa3, 0x20, 0xe2, 0x61, 0xf9, 0x7a, 0xd4, 0x57, 0xcf, 0x4c, + 0x56, 0xd5, 0x4d, 0xce, 0x60, 0xe3, 0x7b, 0xf8, 0x3a, 0xb9, + 0x21, 0xa2, 0x0c, 0x8f, 0x17, 0x94, 0x23, 0xa0, 0x38, 0xbb, + 0x15, 0x96, 0x0e, 0x8d, 0x4f, 0xcc, 0x54, 0xd7, 0x79, 0xfa, + 0x62, 0xe1, 0xfb, 0x78, 0xe0, 0x63, 0xcd, 0x4e, 0xd6, 0x55, + 0x97, 0x14, 0x8c, 0x0f, 0xa1, 0x22, 0xba, 0x39, 0xc9, 0x4a, + 0xd2, 0x51, 0xff, 0x7c, 0xe4, 0x67, 0xa5, 0x26, 0xbe, 0x3d, + 0x93, 0x10, 0x88, 0x0b, 0x11, 0x92, 0x0a, 0x89, 0x27, 0xa4, + 0x3c, 0xbf, 0x7d, 0xfe, 0x66, 0xe5, 0x4b, 0xc8, 0x50, 0xd3, + 0x64, 0xe7, 0x7f, 0xfc, 0x52, 0xd1, 0x49, 0xca, 0x08, 0x8b, + 0x13, 0x90, 0x3e, 0xbd, 0x25, 0xa6, 0xbc, 0x3f, 0xa7, 0x24, + 0x8a, 0x09, 0x91, 0x12, 0xd0, 0x53, 0xcb, 0x48, 0xe6, 0x65, + 0xfd, 0x7e, 0x00, 0x84, 0x15, 0x91, 0x2a, 0xae, 0x3f, 0xbb, + 0x54, 0xd0, 0x41, 0xc5, 0x7e, 0xfa, 0x6b, 0xef, 0xa8, 0x2c, + 0xbd, 0x39, 0x82, 0x06, 0x97, 0x13, 0xfc, 0x78, 0xe9, 0x6d, + 0xd6, 0x52, 0xc3, 0x47, 0x4d, 0xc9, 0x58, 0xdc, 0x67, 0xe3, + 0x72, 0xf6, 0x19, 0x9d, 0x0c, 0x88, 0x33, 0xb7, 0x26, 0xa2, + 0xe5, 0x61, 0xf0, 0x74, 0xcf, 0x4b, 0xda, 0x5e, 0xb1, 0x35, + 0xa4, 0x20, 0x9b, 0x1f, 0x8e, 0x0a, 0x9a, 0x1e, 0x8f, 0x0b, + 0xb0, 0x34, 0xa5, 0x21, 0xce, 0x4a, 0xdb, 0x5f, 0xe4, 0x60, + 0xf1, 0x75, 0x32, 0xb6, 0x27, 0xa3, 0x18, 0x9c, 0x0d, 0x89, + 0x66, 0xe2, 0x73, 0xf7, 0x4c, 0xc8, 0x59, 0xdd, 0xd7, 0x53, + 0xc2, 0x46, 0xfd, 0x79, 0xe8, 0x6c, 0x83, 0x07, 0x96, 0x12, + 0xa9, 0x2d, 0xbc, 0x38, 0x7f, 0xfb, 0x6a, 0xee, 0x55, 0xd1, + 0x40, 0xc4, 0x2b, 0xaf, 0x3e, 0xba, 0x01, 0x85, 0x14, 0x90, + 0x29, 0xad, 0x3c, 0xb8, 0x03, 0x87, 0x16, 0x92, 0x7d, 0xf9, + 0x68, 0xec, 0x57, 0xd3, 0x42, 0xc6, 0x81, 0x05, 0x94, 0x10, + 0xab, 0x2f, 0xbe, 0x3a, 0xd5, 0x51, 0xc0, 0x44, 0xff, 0x7b, + 0xea, 0x6e, 0x64, 0xe0, 0x71, 0xf5, 0x4e, 0xca, 0x5b, 0xdf, + 0x30, 0xb4, 0x25, 0xa1, 0x1a, 0x9e, 0x0f, 0x8b, 0xcc, 0x48, + 0xd9, 0x5d, 0xe6, 0x62, 0xf3, 0x77, 0x98, 0x1c, 0x8d, 0x09, + 0xb2, 0x36, 0xa7, 0x23, 0xb3, 0x37, 0xa6, 0x22, 0x99, 0x1d, + 0x8c, 0x08, 0xe7, 0x63, 0xf2, 0x76, 0xcd, 0x49, 0xd8, 0x5c, + 0x1b, 0x9f, 0x0e, 0x8a, 0x31, 0xb5, 0x24, 0xa0, 0x4f, 0xcb, + 0x5a, 0xde, 0x65, 0xe1, 0x70, 0xf4, 0xfe, 0x7a, 0xeb, 0x6f, + 0xd4, 0x50, 0xc1, 0x45, 0xaa, 0x2e, 0xbf, 0x3b, 0x80, 0x04, + 0x95, 0x11, 0x56, 0xd2, 0x43, 0xc7, 0x7c, 0xf8, 0x69, 0xed, + 0x02, 0x86, 0x17, 0x93, 0x28, 0xac, 0x3d, 0xb9, 0x00, 0x85, + 0x17, 0x92, 0x2e, 0xab, 0x39, 0xbc, 0x5c, 0xd9, 0x4b, 0xce, + 0x72, 0xf7, 0x65, 0xe0, 0xb8, 0x3d, 0xaf, 0x2a, 0x96, 0x13, + 0x81, 0x04, 0xe4, 0x61, 0xf3, 0x76, 0xca, 0x4f, 0xdd, 0x58, + 0x6d, 0xe8, 0x7a, 0xff, 0x43, 0xc6, 0x54, 0xd1, 0x31, 0xb4, + 0x26, 0xa3, 0x1f, 0x9a, 0x08, 0x8d, 0xd5, 0x50, 0xc2, 0x47, + 0xfb, 0x7e, 0xec, 0x69, 0x89, 0x0c, 0x9e, 0x1b, 0xa7, 0x22, + 0xb0, 0x35, 0xda, 0x5f, 0xcd, 0x48, 0xf4, 0x71, 0xe3, 0x66, + 0x86, 0x03, 0x91, 0x14, 0xa8, 0x2d, 0xbf, 0x3a, 0x62, 0xe7, + 0x75, 0xf0, 0x4c, 0xc9, 0x5b, 0xde, 0x3e, 0xbb, 0x29, 0xac, + 0x10, 0x95, 0x07, 0x82, 0xb7, 0x32, 0xa0, 0x25, 0x99, 0x1c, + 0x8e, 0x0b, 0xeb, 0x6e, 0xfc, 0x79, 0xc5, 0x40, 0xd2, 0x57, + 0x0f, 0x8a, 0x18, 0x9d, 0x21, 0xa4, 0x36, 0xb3, 0x53, 0xd6, + 0x44, 0xc1, 0x7d, 0xf8, 0x6a, 0xef, 0xa9, 0x2c, 0xbe, 0x3b, + 0x87, 0x02, 0x90, 0x15, 0xf5, 0x70, 0xe2, 0x67, 0xdb, 0x5e, + 0xcc, 0x49, 0x11, 0x94, 0x06, 0x83, 0x3f, 0xba, 0x28, 0xad, + 0x4d, 0xc8, 0x5a, 0xdf, 0x63, 0xe6, 0x74, 0xf1, 0xc4, 0x41, + 0xd3, 0x56, 0xea, 0x6f, 0xfd, 0x78, 0x98, 0x1d, 0x8f, 0x0a, + 0xb6, 0x33, 0xa1, 0x24, 0x7c, 0xf9, 0x6b, 0xee, 0x52, 0xd7, + 0x45, 0xc0, 0x20, 0xa5, 0x37, 0xb2, 0x0e, 0x8b, 0x19, 0x9c, + 0x73, 0xf6, 0x64, 0xe1, 0x5d, 0xd8, 0x4a, 0xcf, 0x2f, 0xaa, + 0x38, 0xbd, 0x01, 0x84, 0x16, 0x93, 0xcb, 0x4e, 0xdc, 0x59, + 0xe5, 0x60, 0xf2, 0x77, 0x97, 0x12, 0x80, 0x05, 0xb9, 0x3c, + 0xae, 0x2b, 0x1e, 0x9b, 0x09, 0x8c, 0x30, 0xb5, 0x27, 0xa2, + 0x42, 0xc7, 0x55, 0xd0, 0x6c, 0xe9, 0x7b, 0xfe, 0xa6, 0x23, + 0xb1, 0x34, 0x88, 0x0d, 0x9f, 0x1a, 0xfa, 0x7f, 0xed, 0x68, + 0xd4, 0x51, 0xc3, 0x46, 0x00, 0x86, 0x11, 0x97, 0x22, 0xa4, + 0x33, 0xb5, 0x44, 0xc2, 0x55, 0xd3, 0x66, 0xe0, 0x77, 0xf1, + 0x88, 0x0e, 0x99, 0x1f, 0xaa, 0x2c, 0xbb, 0x3d, 0xcc, 0x4a, + 0xdd, 0x5b, 0xee, 0x68, 0xff, 0x79, 0x0d, 0x8b, 0x1c, 0x9a, + 0x2f, 0xa9, 0x3e, 0xb8, 0x49, 0xcf, 0x58, 0xde, 0x6b, 0xed, + 0x7a, 0xfc, 0x85, 0x03, 0x94, 0x12, 0xa7, 0x21, 0xb6, 0x30, + 0xc1, 0x47, 0xd0, 0x56, 0xe3, 0x65, 0xf2, 0x74, 0x1a, 0x9c, + 0x0b, 0x8d, 0x38, 0xbe, 0x29, 0xaf, 0x5e, 0xd8, 0x4f, 0xc9, + 0x7c, 0xfa, 0x6d, 0xeb, 0x92, 0x14, 0x83, 0x05, 0xb0, 0x36, + 0xa1, 0x27, 0xd6, 0x50, 0xc7, 0x41, 0xf4, 0x72, 0xe5, 0x63, + 0x17, 0x91, 0x06, 0x80, 0x35, 0xb3, 0x24, 0xa2, 0x53, 0xd5, + 0x42, 0xc4, 0x71, 0xf7, 0x60, 0xe6, 0x9f, 0x19, 0x8e, 0x08, + 0xbd, 0x3b, 0xac, 0x2a, 0xdb, 0x5d, 0xca, 0x4c, 0xf9, 0x7f, + 0xe8, 0x6e, 0x34, 0xb2, 0x25, 0xa3, 0x16, 0x90, 0x07, 0x81, + 0x70, 0xf6, 0x61, 0xe7, 0x52, 0xd4, 0x43, 0xc5, 0xbc, 0x3a, + 0xad, 0x2b, 0x9e, 0x18, 0x8f, 0x09, 0xf8, 0x7e, 0xe9, 0x6f, + 0xda, 0x5c, 0xcb, 0x4d, 0x39, 0xbf, 0x28, 0xae, 0x1b, 0x9d, + 0x0a, 0x8c, 0x7d, 0xfb, 0x6c, 0xea, 0x5f, 0xd9, 0x4e, 0xc8, + 0xb1, 0x37, 0xa0, 0x26, 0x93, 0x15, 0x82, 0x04, 0xf5, 0x73, + 0xe4, 0x62, 0xd7, 0x51, 0xc6, 0x40, 0x2e, 0xa8, 0x3f, 0xb9, + 0x0c, 0x8a, 0x1d, 0x9b, 0x6a, 0xec, 0x7b, 0xfd, 0x48, 0xce, + 0x59, 0xdf, 0xa6, 0x20, 0xb7, 0x31, 0x84, 0x02, 0x95, 0x13, + 0xe2, 0x64, 0xf3, 0x75, 0xc0, 0x46, 0xd1, 0x57, 0x23, 0xa5, + 0x32, 0xb4, 0x01, 0x87, 0x10, 0x96, 0x67, 0xe1, 0x76, 0xf0, + 0x45, 0xc3, 0x54, 0xd2, 0xab, 0x2d, 0xba, 0x3c, 0x89, 0x0f, + 0x98, 0x1e, 0xef, 0x69, 0xfe, 0x78, 0xcd, 0x4b, 0xdc, 0x5a, + 0x00, 0x87, 0x13, 0x94, 0x26, 0xa1, 0x35, 0xb2, 0x4c, 0xcb, + 0x5f, 0xd8, 0x6a, 0xed, 0x79, 0xfe, 0x98, 0x1f, 0x8b, 0x0c, + 0xbe, 0x39, 0xad, 0x2a, 0xd4, 0x53, 0xc7, 0x40, 0xf2, 0x75, + 0xe1, 0x66, 0x2d, 0xaa, 0x3e, 0xb9, 0x0b, 0x8c, 0x18, 0x9f, + 0x61, 0xe6, 0x72, 0xf5, 0x47, 0xc0, 0x54, 0xd3, 0xb5, 0x32, + 0xa6, 0x21, 0x93, 0x14, 0x80, 0x07, 0xf9, 0x7e, 0xea, 0x6d, + 0xdf, 0x58, 0xcc, 0x4b, 0x5a, 0xdd, 0x49, 0xce, 0x7c, 0xfb, + 0x6f, 0xe8, 0x16, 0x91, 0x05, 0x82, 0x30, 0xb7, 0x23, 0xa4, + 0xc2, 0x45, 0xd1, 0x56, 0xe4, 0x63, 0xf7, 0x70, 0x8e, 0x09, + 0x9d, 0x1a, 0xa8, 0x2f, 0xbb, 0x3c, 0x77, 0xf0, 0x64, 0xe3, + 0x51, 0xd6, 0x42, 0xc5, 0x3b, 0xbc, 0x28, 0xaf, 0x1d, 0x9a, + 0x0e, 0x89, 0xef, 0x68, 0xfc, 0x7b, 0xc9, 0x4e, 0xda, 0x5d, + 0xa3, 0x24, 0xb0, 0x37, 0x85, 0x02, 0x96, 0x11, 0xb4, 0x33, + 0xa7, 0x20, 0x92, 0x15, 0x81, 0x06, 0xf8, 0x7f, 0xeb, 0x6c, + 0xde, 0x59, 0xcd, 0x4a, 0x2c, 0xab, 0x3f, 0xb8, 0x0a, 0x8d, + 0x19, 0x9e, 0x60, 0xe7, 0x73, 0xf4, 0x46, 0xc1, 0x55, 0xd2, + 0x99, 0x1e, 0x8a, 0x0d, 0xbf, 0x38, 0xac, 0x2b, 0xd5, 0x52, + 0xc6, 0x41, 0xf3, 0x74, 0xe0, 0x67, 0x01, 0x86, 0x12, 0x95, + 0x27, 0xa0, 0x34, 0xb3, 0x4d, 0xca, 0x5e, 0xd9, 0x6b, 0xec, + 0x78, 0xff, 0xee, 0x69, 0xfd, 0x7a, 0xc8, 0x4f, 0xdb, 0x5c, + 0xa2, 0x25, 0xb1, 0x36, 0x84, 0x03, 0x97, 0x10, 0x76, 0xf1, + 0x65, 0xe2, 0x50, 0xd7, 0x43, 0xc4, 0x3a, 0xbd, 0x29, 0xae, + 0x1c, 0x9b, 0x0f, 0x88, 0xc3, 0x44, 0xd0, 0x57, 0xe5, 0x62, + 0xf6, 0x71, 0x8f, 0x08, 0x9c, 0x1b, 0xa9, 0x2e, 0xba, 0x3d, + 0x5b, 0xdc, 0x48, 0xcf, 0x7d, 0xfa, 0x6e, 0xe9, 0x17, 0x90, + 0x04, 0x83, 0x31, 0xb6, 0x22, 0xa5, 0x00, 0x88, 0x0d, 0x85, + 0x1a, 0x92, 0x17, 0x9f, 0x34, 0xbc, 0x39, 0xb1, 0x2e, 0xa6, + 0x23, 0xab, 0x68, 0xe0, 0x65, 0xed, 0x72, 0xfa, 0x7f, 0xf7, + 0x5c, 0xd4, 0x51, 0xd9, 0x46, 0xce, 0x4b, 0xc3, 0xd0, 0x58, + 0xdd, 0x55, 0xca, 0x42, 0xc7, 0x4f, 0xe4, 0x6c, 0xe9, 0x61, + 0xfe, 0x76, 0xf3, 0x7b, 0xb8, 0x30, 0xb5, 0x3d, 0xa2, 0x2a, + 0xaf, 0x27, 0x8c, 0x04, 0x81, 0x09, 0x96, 0x1e, 0x9b, 0x13, + 0xbd, 0x35, 0xb0, 0x38, 0xa7, 0x2f, 0xaa, 0x22, 0x89, 0x01, + 0x84, 0x0c, 0x93, 0x1b, 0x9e, 0x16, 0xd5, 0x5d, 0xd8, 0x50, + 0xcf, 0x47, 0xc2, 0x4a, 0xe1, 0x69, 0xec, 0x64, 0xfb, 0x73, + 0xf6, 0x7e, 0x6d, 0xe5, 0x60, 0xe8, 0x77, 0xff, 0x7a, 0xf2, + 0x59, 0xd1, 0x54, 0xdc, 0x43, 0xcb, 0x4e, 0xc6, 0x05, 0x8d, + 0x08, 0x80, 0x1f, 0x97, 0x12, 0x9a, 0x31, 0xb9, 0x3c, 0xb4, + 0x2b, 0xa3, 0x26, 0xae, 0x67, 0xef, 0x6a, 0xe2, 0x7d, 0xf5, + 0x70, 0xf8, 0x53, 0xdb, 0x5e, 0xd6, 0x49, 0xc1, 0x44, 0xcc, + 0x0f, 0x87, 0x02, 0x8a, 0x15, 0x9d, 0x18, 0x90, 0x3b, 0xb3, + 0x36, 0xbe, 0x21, 0xa9, 0x2c, 0xa4, 0xb7, 0x3f, 0xba, 0x32, + 0xad, 0x25, 0xa0, 0x28, 0x83, 0x0b, 0x8e, 0x06, 0x99, 0x11, + 0x94, 0x1c, 0xdf, 0x57, 0xd2, 0x5a, 0xc5, 0x4d, 0xc8, 0x40, + 0xeb, 0x63, 0xe6, 0x6e, 0xf1, 0x79, 0xfc, 0x74, 0xda, 0x52, + 0xd7, 0x5f, 0xc0, 0x48, 0xcd, 0x45, 0xee, 0x66, 0xe3, 0x6b, + 0xf4, 0x7c, 0xf9, 0x71, 0xb2, 0x3a, 0xbf, 0x37, 0xa8, 0x20, + 0xa5, 0x2d, 0x86, 0x0e, 0x8b, 0x03, 0x9c, 0x14, 0x91, 0x19, + 0x0a, 0x82, 0x07, 0x8f, 0x10, 0x98, 0x1d, 0x95, 0x3e, 0xb6, + 0x33, 0xbb, 0x24, 0xac, 0x29, 0xa1, 0x62, 0xea, 0x6f, 0xe7, + 0x78, 0xf0, 0x75, 0xfd, 0x56, 0xde, 0x5b, 0xd3, 0x4c, 0xc4, + 0x41, 0xc9, 0x00, 0x89, 0x0f, 0x86, 0x1e, 0x97, 0x11, 0x98, + 0x3c, 0xb5, 0x33, 0xba, 0x22, 0xab, 0x2d, 0xa4, 0x78, 0xf1, + 0x77, 0xfe, 0x66, 0xef, 0x69, 0xe0, 0x44, 0xcd, 0x4b, 0xc2, + 0x5a, 0xd3, 0x55, 0xdc, 0xf0, 0x79, 0xff, 0x76, 0xee, 0x67, + 0xe1, 0x68, 0xcc, 0x45, 0xc3, 0x4a, 0xd2, 0x5b, 0xdd, 0x54, + 0x88, 0x01, 0x87, 0x0e, 0x96, 0x1f, 0x99, 0x10, 0xb4, 0x3d, + 0xbb, 0x32, 0xaa, 0x23, 0xa5, 0x2c, 0xfd, 0x74, 0xf2, 0x7b, + 0xe3, 0x6a, 0xec, 0x65, 0xc1, 0x48, 0xce, 0x47, 0xdf, 0x56, + 0xd0, 0x59, 0x85, 0x0c, 0x8a, 0x03, 0x9b, 0x12, 0x94, 0x1d, + 0xb9, 0x30, 0xb6, 0x3f, 0xa7, 0x2e, 0xa8, 0x21, 0x0d, 0x84, + 0x02, 0x8b, 0x13, 0x9a, 0x1c, 0x95, 0x31, 0xb8, 0x3e, 0xb7, + 0x2f, 0xa6, 0x20, 0xa9, 0x75, 0xfc, 0x7a, 0xf3, 0x6b, 0xe2, + 0x64, 0xed, 0x49, 0xc0, 0x46, 0xcf, 0x57, 0xde, 0x58, 0xd1, + 0xe7, 0x6e, 0xe8, 0x61, 0xf9, 0x70, 0xf6, 0x7f, 0xdb, 0x52, + 0xd4, 0x5d, 0xc5, 0x4c, 0xca, 0x43, 0x9f, 0x16, 0x90, 0x19, + 0x81, 0x08, 0x8e, 0x07, 0xa3, 0x2a, 0xac, 0x25, 0xbd, 0x34, + 0xb2, 0x3b, 0x17, 0x9e, 0x18, 0x91, 0x09, 0x80, 0x06, 0x8f, + 0x2b, 0xa2, 0x24, 0xad, 0x35, 0xbc, 0x3a, 0xb3, 0x6f, 0xe6, + 0x60, 0xe9, 0x71, 0xf8, 0x7e, 0xf7, 0x53, 0xda, 0x5c, 0xd5, + 0x4d, 0xc4, 0x42, 0xcb, 0x1a, 0x93, 0x15, 0x9c, 0x04, 0x8d, + 0x0b, 0x82, 0x26, 0xaf, 0x29, 0xa0, 0x38, 0xb1, 0x37, 0xbe, + 0x62, 0xeb, 0x6d, 0xe4, 0x7c, 0xf5, 0x73, 0xfa, 0x5e, 0xd7, + 0x51, 0xd8, 0x40, 0xc9, 0x4f, 0xc6, 0xea, 0x63, 0xe5, 0x6c, + 0xf4, 0x7d, 0xfb, 0x72, 0xd6, 0x5f, 0xd9, 0x50, 0xc8, 0x41, + 0xc7, 0x4e, 0x92, 0x1b, 0x9d, 0x14, 0x8c, 0x05, 0x83, 0x0a, + 0xae, 0x27, 0xa1, 0x28, 0xb0, 0x39, 0xbf, 0x36, 0x00, 0x8a, + 0x09, 0x83, 0x12, 0x98, 0x1b, 0x91, 0x24, 0xae, 0x2d, 0xa7, + 0x36, 0xbc, 0x3f, 0xb5, 0x48, 0xc2, 0x41, 0xcb, 0x5a, 0xd0, + 0x53, 0xd9, 0x6c, 0xe6, 0x65, 0xef, 0x7e, 0xf4, 0x77, 0xfd, + 0x90, 0x1a, 0x99, 0x13, 0x82, 0x08, 0x8b, 0x01, 0xb4, 0x3e, + 0xbd, 0x37, 0xa6, 0x2c, 0xaf, 0x25, 0xd8, 0x52, 0xd1, 0x5b, + 0xca, 0x40, 0xc3, 0x49, 0xfc, 0x76, 0xf5, 0x7f, 0xee, 0x64, + 0xe7, 0x6d, 0x3d, 0xb7, 0x34, 0xbe, 0x2f, 0xa5, 0x26, 0xac, + 0x19, 0x93, 0x10, 0x9a, 0x0b, 0x81, 0x02, 0x88, 0x75, 0xff, + 0x7c, 0xf6, 0x67, 0xed, 0x6e, 0xe4, 0x51, 0xdb, 0x58, 0xd2, + 0x43, 0xc9, 0x4a, 0xc0, 0xad, 0x27, 0xa4, 0x2e, 0xbf, 0x35, + 0xb6, 0x3c, 0x89, 0x03, 0x80, 0x0a, 0x9b, 0x11, 0x92, 0x18, + 0xe5, 0x6f, 0xec, 0x66, 0xf7, 0x7d, 0xfe, 0x74, 0xc1, 0x4b, + 0xc8, 0x42, 0xd3, 0x59, 0xda, 0x50, 0x7a, 0xf0, 0x73, 0xf9, + 0x68, 0xe2, 0x61, 0xeb, 0x5e, 0xd4, 0x57, 0xdd, 0x4c, 0xc6, + 0x45, 0xcf, 0x32, 0xb8, 0x3b, 0xb1, 0x20, 0xaa, 0x29, 0xa3, + 0x16, 0x9c, 0x1f, 0x95, 0x04, 0x8e, 0x0d, 0x87, 0xea, 0x60, + 0xe3, 0x69, 0xf8, 0x72, 0xf1, 0x7b, 0xce, 0x44, 0xc7, 0x4d, + 0xdc, 0x56, 0xd5, 0x5f, 0xa2, 0x28, 0xab, 0x21, 0xb0, 0x3a, + 0xb9, 0x33, 0x86, 0x0c, 0x8f, 0x05, 0x94, 0x1e, 0x9d, 0x17, + 0x47, 0xcd, 0x4e, 0xc4, 0x55, 0xdf, 0x5c, 0xd6, 0x63, 0xe9, + 0x6a, 0xe0, 0x71, 0xfb, 0x78, 0xf2, 0x0f, 0x85, 0x06, 0x8c, + 0x1d, 0x97, 0x14, 0x9e, 0x2b, 0xa1, 0x22, 0xa8, 0x39, 0xb3, + 0x30, 0xba, 0xd7, 0x5d, 0xde, 0x54, 0xc5, 0x4f, 0xcc, 0x46, + 0xf3, 0x79, 0xfa, 0x70, 0xe1, 0x6b, 0xe8, 0x62, 0x9f, 0x15, + 0x96, 0x1c, 0x8d, 0x07, 0x84, 0x0e, 0xbb, 0x31, 0xb2, 0x38, + 0xa9, 0x23, 0xa0, 0x2a, 0x00, 0x8b, 0x0b, 0x80, 0x16, 0x9d, + 0x1d, 0x96, 0x2c, 0xa7, 0x27, 0xac, 0x3a, 0xb1, 0x31, 0xba, + 0x58, 0xd3, 0x53, 0xd8, 0x4e, 0xc5, 0x45, 0xce, 0x74, 0xff, + 0x7f, 0xf4, 0x62, 0xe9, 0x69, 0xe2, 0xb0, 0x3b, 0xbb, 0x30, + 0xa6, 0x2d, 0xad, 0x26, 0x9c, 0x17, 0x97, 0x1c, 0x8a, 0x01, + 0x81, 0x0a, 0xe8, 0x63, 0xe3, 0x68, 0xfe, 0x75, 0xf5, 0x7e, + 0xc4, 0x4f, 0xcf, 0x44, 0xd2, 0x59, 0xd9, 0x52, 0x7d, 0xf6, + 0x76, 0xfd, 0x6b, 0xe0, 0x60, 0xeb, 0x51, 0xda, 0x5a, 0xd1, + 0x47, 0xcc, 0x4c, 0xc7, 0x25, 0xae, 0x2e, 0xa5, 0x33, 0xb8, + 0x38, 0xb3, 0x09, 0x82, 0x02, 0x89, 0x1f, 0x94, 0x14, 0x9f, + 0xcd, 0x46, 0xc6, 0x4d, 0xdb, 0x50, 0xd0, 0x5b, 0xe1, 0x6a, + 0xea, 0x61, 0xf7, 0x7c, 0xfc, 0x77, 0x95, 0x1e, 0x9e, 0x15, + 0x83, 0x08, 0x88, 0x03, 0xb9, 0x32, 0xb2, 0x39, 0xaf, 0x24, + 0xa4, 0x2f, 0xfa, 0x71, 0xf1, 0x7a, 0xec, 0x67, 0xe7, 0x6c, + 0xd6, 0x5d, 0xdd, 0x56, 0xc0, 0x4b, 0xcb, 0x40, 0xa2, 0x29, + 0xa9, 0x22, 0xb4, 0x3f, 0xbf, 0x34, 0x8e, 0x05, 0x85, 0x0e, + 0x98, 0x13, 0x93, 0x18, 0x4a, 0xc1, 0x41, 0xca, 0x5c, 0xd7, + 0x57, 0xdc, 0x66, 0xed, 0x6d, 0xe6, 0x70, 0xfb, 0x7b, 0xf0, + 0x12, 0x99, 0x19, 0x92, 0x04, 0x8f, 0x0f, 0x84, 0x3e, 0xb5, + 0x35, 0xbe, 0x28, 0xa3, 0x23, 0xa8, 0x87, 0x0c, 0x8c, 0x07, + 0x91, 0x1a, 0x9a, 0x11, 0xab, 0x20, 0xa0, 0x2b, 0xbd, 0x36, + 0xb6, 0x3d, 0xdf, 0x54, 0xd4, 0x5f, 0xc9, 0x42, 0xc2, 0x49, + 0xf3, 0x78, 0xf8, 0x73, 0xe5, 0x6e, 0xee, 0x65, 0x37, 0xbc, + 0x3c, 0xb7, 0x21, 0xaa, 0x2a, 0xa1, 0x1b, 0x90, 0x10, 0x9b, + 0x0d, 0x86, 0x06, 0x8d, 0x6f, 0xe4, 0x64, 0xef, 0x79, 0xf2, + 0x72, 0xf9, 0x43, 0xc8, 0x48, 0xc3, 0x55, 0xde, 0x5e, 0xd5, + 0x00, 0x8c, 0x05, 0x89, 0x0a, 0x86, 0x0f, 0x83, 0x14, 0x98, + 0x11, 0x9d, 0x1e, 0x92, 0x1b, 0x97, 0x28, 0xa4, 0x2d, 0xa1, + 0x22, 0xae, 0x27, 0xab, 0x3c, 0xb0, 0x39, 0xb5, 0x36, 0xba, + 0x33, 0xbf, 0x50, 0xdc, 0x55, 0xd9, 0x5a, 0xd6, 0x5f, 0xd3, + 0x44, 0xc8, 0x41, 0xcd, 0x4e, 0xc2, 0x4b, 0xc7, 0x78, 0xf4, + 0x7d, 0xf1, 0x72, 0xfe, 0x77, 0xfb, 0x6c, 0xe0, 0x69, 0xe5, + 0x66, 0xea, 0x63, 0xef, 0xa0, 0x2c, 0xa5, 0x29, 0xaa, 0x26, + 0xaf, 0x23, 0xb4, 0x38, 0xb1, 0x3d, 0xbe, 0x32, 0xbb, 0x37, + 0x88, 0x04, 0x8d, 0x01, 0x82, 0x0e, 0x87, 0x0b, 0x9c, 0x10, + 0x99, 0x15, 0x96, 0x1a, 0x93, 0x1f, 0xf0, 0x7c, 0xf5, 0x79, + 0xfa, 0x76, 0xff, 0x73, 0xe4, 0x68, 0xe1, 0x6d, 0xee, 0x62, + 0xeb, 0x67, 0xd8, 0x54, 0xdd, 0x51, 0xd2, 0x5e, 0xd7, 0x5b, + 0xcc, 0x40, 0xc9, 0x45, 0xc6, 0x4a, 0xc3, 0x4f, 0x5d, 0xd1, + 0x58, 0xd4, 0x57, 0xdb, 0x52, 0xde, 0x49, 0xc5, 0x4c, 0xc0, + 0x43, 0xcf, 0x46, 0xca, 0x75, 0xf9, 0x70, 0xfc, 0x7f, 0xf3, + 0x7a, 0xf6, 0x61, 0xed, 0x64, 0xe8, 0x6b, 0xe7, 0x6e, 0xe2, + 0x0d, 0x81, 0x08, 0x84, 0x07, 0x8b, 0x02, 0x8e, 0x19, 0x95, + 0x1c, 0x90, 0x13, 0x9f, 0x16, 0x9a, 0x25, 0xa9, 0x20, 0xac, + 0x2f, 0xa3, 0x2a, 0xa6, 0x31, 0xbd, 0x34, 0xb8, 0x3b, 0xb7, + 0x3e, 0xb2, 0xfd, 0x71, 0xf8, 0x74, 0xf7, 0x7b, 0xf2, 0x7e, + 0xe9, 0x65, 0xec, 0x60, 0xe3, 0x6f, 0xe6, 0x6a, 0xd5, 0x59, + 0xd0, 0x5c, 0xdf, 0x53, 0xda, 0x56, 0xc1, 0x4d, 0xc4, 0x48, + 0xcb, 0x47, 0xce, 0x42, 0xad, 0x21, 0xa8, 0x24, 0xa7, 0x2b, + 0xa2, 0x2e, 0xb9, 0x35, 0xbc, 0x30, 0xb3, 0x3f, 0xb6, 0x3a, + 0x85, 0x09, 0x80, 0x0c, 0x8f, 0x03, 0x8a, 0x06, 0x91, 0x1d, + 0x94, 0x18, 0x9b, 0x17, 0x9e, 0x12, 0x00, 0x8d, 0x07, 0x8a, + 0x0e, 0x83, 0x09, 0x84, 0x1c, 0x91, 0x1b, 0x96, 0x12, 0x9f, + 0x15, 0x98, 0x38, 0xb5, 0x3f, 0xb2, 0x36, 0xbb, 0x31, 0xbc, + 0x24, 0xa9, 0x23, 0xae, 0x2a, 0xa7, 0x2d, 0xa0, 0x70, 0xfd, + 0x77, 0xfa, 0x7e, 0xf3, 0x79, 0xf4, 0x6c, 0xe1, 0x6b, 0xe6, + 0x62, 0xef, 0x65, 0xe8, 0x48, 0xc5, 0x4f, 0xc2, 0x46, 0xcb, + 0x41, 0xcc, 0x54, 0xd9, 0x53, 0xde, 0x5a, 0xd7, 0x5d, 0xd0, + 0xe0, 0x6d, 0xe7, 0x6a, 0xee, 0x63, 0xe9, 0x64, 0xfc, 0x71, + 0xfb, 0x76, 0xf2, 0x7f, 0xf5, 0x78, 0xd8, 0x55, 0xdf, 0x52, + 0xd6, 0x5b, 0xd1, 0x5c, 0xc4, 0x49, 0xc3, 0x4e, 0xca, 0x47, + 0xcd, 0x40, 0x90, 0x1d, 0x97, 0x1a, 0x9e, 0x13, 0x99, 0x14, + 0x8c, 0x01, 0x8b, 0x06, 0x82, 0x0f, 0x85, 0x08, 0xa8, 0x25, + 0xaf, 0x22, 0xa6, 0x2b, 0xa1, 0x2c, 0xb4, 0x39, 0xb3, 0x3e, + 0xba, 0x37, 0xbd, 0x30, 0xdd, 0x50, 0xda, 0x57, 0xd3, 0x5e, + 0xd4, 0x59, 0xc1, 0x4c, 0xc6, 0x4b, 0xcf, 0x42, 0xc8, 0x45, + 0xe5, 0x68, 0xe2, 0x6f, 0xeb, 0x66, 0xec, 0x61, 0xf9, 0x74, + 0xfe, 0x73, 0xf7, 0x7a, 0xf0, 0x7d, 0xad, 0x20, 0xaa, 0x27, + 0xa3, 0x2e, 0xa4, 0x29, 0xb1, 0x3c, 0xb6, 0x3b, 0xbf, 0x32, + 0xb8, 0x35, 0x95, 0x18, 0x92, 0x1f, 0x9b, 0x16, 0x9c, 0x11, + 0x89, 0x04, 0x8e, 0x03, 0x87, 0x0a, 0x80, 0x0d, 0x3d, 0xb0, + 0x3a, 0xb7, 0x33, 0xbe, 0x34, 0xb9, 0x21, 0xac, 0x26, 0xab, + 0x2f, 0xa2, 0x28, 0xa5, 0x05, 0x88, 0x02, 0x8f, 0x0b, 0x86, + 0x0c, 0x81, 0x19, 0x94, 0x1e, 0x93, 0x17, 0x9a, 0x10, 0x9d, + 0x4d, 0xc0, 0x4a, 0xc7, 0x43, 0xce, 0x44, 0xc9, 0x51, 0xdc, + 0x56, 0xdb, 0x5f, 0xd2, 0x58, 0xd5, 0x75, 0xf8, 0x72, 0xff, + 0x7b, 0xf6, 0x7c, 0xf1, 0x69, 0xe4, 0x6e, 0xe3, 0x67, 0xea, + 0x60, 0xed, 0x00, 0x8e, 0x01, 0x8f, 0x02, 0x8c, 0x03, 0x8d, + 0x04, 0x8a, 0x05, 0x8b, 0x06, 0x88, 0x07, 0x89, 0x08, 0x86, + 0x09, 0x87, 0x0a, 0x84, 0x0b, 0x85, 0x0c, 0x82, 0x0d, 0x83, + 0x0e, 0x80, 0x0f, 0x81, 0x10, 0x9e, 0x11, 0x9f, 0x12, 0x9c, + 0x13, 0x9d, 0x14, 0x9a, 0x15, 0x9b, 0x16, 0x98, 0x17, 0x99, + 0x18, 0x96, 0x19, 0x97, 0x1a, 0x94, 0x1b, 0x95, 0x1c, 0x92, + 0x1d, 0x93, 0x1e, 0x90, 0x1f, 0x91, 0x20, 0xae, 0x21, 0xaf, + 0x22, 0xac, 0x23, 0xad, 0x24, 0xaa, 0x25, 0xab, 0x26, 0xa8, + 0x27, 0xa9, 0x28, 0xa6, 0x29, 0xa7, 0x2a, 0xa4, 0x2b, 0xa5, + 0x2c, 0xa2, 0x2d, 0xa3, 0x2e, 0xa0, 0x2f, 0xa1, 0x30, 0xbe, + 0x31, 0xbf, 0x32, 0xbc, 0x33, 0xbd, 0x34, 0xba, 0x35, 0xbb, + 0x36, 0xb8, 0x37, 0xb9, 0x38, 0xb6, 0x39, 0xb7, 0x3a, 0xb4, + 0x3b, 0xb5, 0x3c, 0xb2, 0x3d, 0xb3, 0x3e, 0xb0, 0x3f, 0xb1, + 0x40, 0xce, 0x41, 0xcf, 0x42, 0xcc, 0x43, 0xcd, 0x44, 0xca, + 0x45, 0xcb, 0x46, 0xc8, 0x47, 0xc9, 0x48, 0xc6, 0x49, 0xc7, + 0x4a, 0xc4, 0x4b, 0xc5, 0x4c, 0xc2, 0x4d, 0xc3, 0x4e, 0xc0, + 0x4f, 0xc1, 0x50, 0xde, 0x51, 0xdf, 0x52, 0xdc, 0x53, 0xdd, + 0x54, 0xda, 0x55, 0xdb, 0x56, 0xd8, 0x57, 0xd9, 0x58, 0xd6, + 0x59, 0xd7, 0x5a, 0xd4, 0x5b, 0xd5, 0x5c, 0xd2, 0x5d, 0xd3, + 0x5e, 0xd0, 0x5f, 0xd1, 0x60, 0xee, 0x61, 0xef, 0x62, 0xec, + 0x63, 0xed, 0x64, 0xea, 0x65, 0xeb, 0x66, 0xe8, 0x67, 0xe9, + 0x68, 0xe6, 0x69, 0xe7, 0x6a, 0xe4, 0x6b, 0xe5, 0x6c, 0xe2, + 0x6d, 0xe3, 0x6e, 0xe0, 0x6f, 0xe1, 0x70, 0xfe, 0x71, 0xff, + 0x72, 0xfc, 0x73, 0xfd, 0x74, 0xfa, 0x75, 0xfb, 0x76, 0xf8, + 0x77, 0xf9, 0x78, 0xf6, 0x79, 0xf7, 0x7a, 0xf4, 0x7b, 0xf5, + 0x7c, 0xf2, 0x7d, 0xf3, 0x7e, 0xf0, 0x7f, 0xf1, 0x00, 0x8f, + 0x03, 0x8c, 0x06, 0x89, 0x05, 0x8a, 0x0c, 0x83, 0x0f, 0x80, + 0x0a, 0x85, 0x09, 0x86, 0x18, 0x97, 0x1b, 0x94, 0x1e, 0x91, + 0x1d, 0x92, 0x14, 0x9b, 0x17, 0x98, 0x12, 0x9d, 0x11, 0x9e, + 0x30, 0xbf, 0x33, 0xbc, 0x36, 0xb9, 0x35, 0xba, 0x3c, 0xb3, + 0x3f, 0xb0, 0x3a, 0xb5, 0x39, 0xb6, 0x28, 0xa7, 0x2b, 0xa4, + 0x2e, 0xa1, 0x2d, 0xa2, 0x24, 0xab, 0x27, 0xa8, 0x22, 0xad, + 0x21, 0xae, 0x60, 0xef, 0x63, 0xec, 0x66, 0xe9, 0x65, 0xea, + 0x6c, 0xe3, 0x6f, 0xe0, 0x6a, 0xe5, 0x69, 0xe6, 0x78, 0xf7, + 0x7b, 0xf4, 0x7e, 0xf1, 0x7d, 0xf2, 0x74, 0xfb, 0x77, 0xf8, + 0x72, 0xfd, 0x71, 0xfe, 0x50, 0xdf, 0x53, 0xdc, 0x56, 0xd9, + 0x55, 0xda, 0x5c, 0xd3, 0x5f, 0xd0, 0x5a, 0xd5, 0x59, 0xd6, + 0x48, 0xc7, 0x4b, 0xc4, 0x4e, 0xc1, 0x4d, 0xc2, 0x44, 0xcb, + 0x47, 0xc8, 0x42, 0xcd, 0x41, 0xce, 0xc0, 0x4f, 0xc3, 0x4c, + 0xc6, 0x49, 0xc5, 0x4a, 0xcc, 0x43, 0xcf, 0x40, 0xca, 0x45, + 0xc9, 0x46, 0xd8, 0x57, 0xdb, 0x54, 0xde, 0x51, 0xdd, 0x52, + 0xd4, 0x5b, 0xd7, 0x58, 0xd2, 0x5d, 0xd1, 0x5e, 0xf0, 0x7f, + 0xf3, 0x7c, 0xf6, 0x79, 0xf5, 0x7a, 0xfc, 0x73, 0xff, 0x70, + 0xfa, 0x75, 0xf9, 0x76, 0xe8, 0x67, 0xeb, 0x64, 0xee, 0x61, + 0xed, 0x62, 0xe4, 0x6b, 0xe7, 0x68, 0xe2, 0x6d, 0xe1, 0x6e, + 0xa0, 0x2f, 0xa3, 0x2c, 0xa6, 0x29, 0xa5, 0x2a, 0xac, 0x23, + 0xaf, 0x20, 0xaa, 0x25, 0xa9, 0x26, 0xb8, 0x37, 0xbb, 0x34, + 0xbe, 0x31, 0xbd, 0x32, 0xb4, 0x3b, 0xb7, 0x38, 0xb2, 0x3d, + 0xb1, 0x3e, 0x90, 0x1f, 0x93, 0x1c, 0x96, 0x19, 0x95, 0x1a, + 0x9c, 0x13, 0x9f, 0x10, 0x9a, 0x15, 0x99, 0x16, 0x88, 0x07, + 0x8b, 0x04, 0x8e, 0x01, 0x8d, 0x02, 0x84, 0x0b, 0x87, 0x08, + 0x82, 0x0d, 0x81, 0x0e, 0x00, 0x90, 0x3d, 0xad, 0x7a, 0xea, + 0x47, 0xd7, 0xf4, 0x64, 0xc9, 0x59, 0x8e, 0x1e, 0xb3, 0x23, + 0xf5, 0x65, 0xc8, 0x58, 0x8f, 0x1f, 0xb2, 0x22, 0x01, 0x91, + 0x3c, 0xac, 0x7b, 0xeb, 0x46, 0xd6, 0xf7, 0x67, 0xca, 0x5a, + 0x8d, 0x1d, 0xb0, 0x20, 0x03, 0x93, 0x3e, 0xae, 0x79, 0xe9, + 0x44, 0xd4, 0x02, 0x92, 0x3f, 0xaf, 0x78, 0xe8, 0x45, 0xd5, + 0xf6, 0x66, 0xcb, 0x5b, 0x8c, 0x1c, 0xb1, 0x21, 0xf3, 0x63, + 0xce, 0x5e, 0x89, 0x19, 0xb4, 0x24, 0x07, 0x97, 0x3a, 0xaa, + 0x7d, 0xed, 0x40, 0xd0, 0x06, 0x96, 0x3b, 0xab, 0x7c, 0xec, + 0x41, 0xd1, 0xf2, 0x62, 0xcf, 0x5f, 0x88, 0x18, 0xb5, 0x25, + 0x04, 0x94, 0x39, 0xa9, 0x7e, 0xee, 0x43, 0xd3, 0xf0, 0x60, + 0xcd, 0x5d, 0x8a, 0x1a, 0xb7, 0x27, 0xf1, 0x61, 0xcc, 0x5c, + 0x8b, 0x1b, 0xb6, 0x26, 0x05, 0x95, 0x38, 0xa8, 0x7f, 0xef, + 0x42, 0xd2, 0xfb, 0x6b, 0xc6, 0x56, 0x81, 0x11, 0xbc, 0x2c, + 0x0f, 0x9f, 0x32, 0xa2, 0x75, 0xe5, 0x48, 0xd8, 0x0e, 0x9e, + 0x33, 0xa3, 0x74, 0xe4, 0x49, 0xd9, 0xfa, 0x6a, 0xc7, 0x57, + 0x80, 0x10, 0xbd, 0x2d, 0x0c, 0x9c, 0x31, 0xa1, 0x76, 0xe6, + 0x4b, 0xdb, 0xf8, 0x68, 0xc5, 0x55, 0x82, 0x12, 0xbf, 0x2f, + 0xf9, 0x69, 0xc4, 0x54, 0x83, 0x13, 0xbe, 0x2e, 0x0d, 0x9d, + 0x30, 0xa0, 0x77, 0xe7, 0x4a, 0xda, 0x08, 0x98, 0x35, 0xa5, + 0x72, 0xe2, 0x4f, 0xdf, 0xfc, 0x6c, 0xc1, 0x51, 0x86, 0x16, + 0xbb, 0x2b, 0xfd, 0x6d, 0xc0, 0x50, 0x87, 0x17, 0xba, 0x2a, + 0x09, 0x99, 0x34, 0xa4, 0x73, 0xe3, 0x4e, 0xde, 0xff, 0x6f, + 0xc2, 0x52, 0x85, 0x15, 0xb8, 0x28, 0x0b, 0x9b, 0x36, 0xa6, + 0x71, 0xe1, 0x4c, 0xdc, 0x0a, 0x9a, 0x37, 0xa7, 0x70, 0xe0, + 0x4d, 0xdd, 0xfe, 0x6e, 0xc3, 0x53, 0x84, 0x14, 0xb9, 0x29, + 0x00, 0x91, 0x3f, 0xae, 0x7e, 0xef, 0x41, 0xd0, 0xfc, 0x6d, + 0xc3, 0x52, 0x82, 0x13, 0xbd, 0x2c, 0xe5, 0x74, 0xda, 0x4b, + 0x9b, 0x0a, 0xa4, 0x35, 0x19, 0x88, 0x26, 0xb7, 0x67, 0xf6, + 0x58, 0xc9, 0xd7, 0x46, 0xe8, 0x79, 0xa9, 0x38, 0x96, 0x07, + 0x2b, 0xba, 0x14, 0x85, 0x55, 0xc4, 0x6a, 0xfb, 0x32, 0xa3, + 0x0d, 0x9c, 0x4c, 0xdd, 0x73, 0xe2, 0xce, 0x5f, 0xf1, 0x60, + 0xb0, 0x21, 0x8f, 0x1e, 0xb3, 0x22, 0x8c, 0x1d, 0xcd, 0x5c, + 0xf2, 0x63, 0x4f, 0xde, 0x70, 0xe1, 0x31, 0xa0, 0x0e, 0x9f, + 0x56, 0xc7, 0x69, 0xf8, 0x28, 0xb9, 0x17, 0x86, 0xaa, 0x3b, + 0x95, 0x04, 0xd4, 0x45, 0xeb, 0x7a, 0x64, 0xf5, 0x5b, 0xca, + 0x1a, 0x8b, 0x25, 0xb4, 0x98, 0x09, 0xa7, 0x36, 0xe6, 0x77, + 0xd9, 0x48, 0x81, 0x10, 0xbe, 0x2f, 0xff, 0x6e, 0xc0, 0x51, + 0x7d, 0xec, 0x42, 0xd3, 0x03, 0x92, 0x3c, 0xad, 0x7b, 0xea, + 0x44, 0xd5, 0x05, 0x94, 0x3a, 0xab, 0x87, 0x16, 0xb8, 0x29, + 0xf9, 0x68, 0xc6, 0x57, 0x9e, 0x0f, 0xa1, 0x30, 0xe0, 0x71, + 0xdf, 0x4e, 0x62, 0xf3, 0x5d, 0xcc, 0x1c, 0x8d, 0x23, 0xb2, + 0xac, 0x3d, 0x93, 0x02, 0xd2, 0x43, 0xed, 0x7c, 0x50, 0xc1, + 0x6f, 0xfe, 0x2e, 0xbf, 0x11, 0x80, 0x49, 0xd8, 0x76, 0xe7, + 0x37, 0xa6, 0x08, 0x99, 0xb5, 0x24, 0x8a, 0x1b, 0xcb, 0x5a, + 0xf4, 0x65, 0xc8, 0x59, 0xf7, 0x66, 0xb6, 0x27, 0x89, 0x18, + 0x34, 0xa5, 0x0b, 0x9a, 0x4a, 0xdb, 0x75, 0xe4, 0x2d, 0xbc, + 0x12, 0x83, 0x53, 0xc2, 0x6c, 0xfd, 0xd1, 0x40, 0xee, 0x7f, + 0xaf, 0x3e, 0x90, 0x01, 0x1f, 0x8e, 0x20, 0xb1, 0x61, 0xf0, + 0x5e, 0xcf, 0xe3, 0x72, 0xdc, 0x4d, 0x9d, 0x0c, 0xa2, 0x33, + 0xfa, 0x6b, 0xc5, 0x54, 0x84, 0x15, 0xbb, 0x2a, 0x06, 0x97, + 0x39, 0xa8, 0x78, 0xe9, 0x47, 0xd6, 0x00, 0x92, 0x39, 0xab, + 0x72, 0xe0, 0x4b, 0xd9, 0xe4, 0x76, 0xdd, 0x4f, 0x96, 0x04, + 0xaf, 0x3d, 0xd5, 0x47, 0xec, 0x7e, 0xa7, 0x35, 0x9e, 0x0c, + 0x31, 0xa3, 0x08, 0x9a, 0x43, 0xd1, 0x7a, 0xe8, 0xb7, 0x25, + 0x8e, 0x1c, 0xc5, 0x57, 0xfc, 0x6e, 0x53, 0xc1, 0x6a, 0xf8, + 0x21, 0xb3, 0x18, 0x8a, 0x62, 0xf0, 0x5b, 0xc9, 0x10, 0x82, + 0x29, 0xbb, 0x86, 0x14, 0xbf, 0x2d, 0xf4, 0x66, 0xcd, 0x5f, + 0x73, 0xe1, 0x4a, 0xd8, 0x01, 0x93, 0x38, 0xaa, 0x97, 0x05, + 0xae, 0x3c, 0xe5, 0x77, 0xdc, 0x4e, 0xa6, 0x34, 0x9f, 0x0d, + 0xd4, 0x46, 0xed, 0x7f, 0x42, 0xd0, 0x7b, 0xe9, 0x30, 0xa2, + 0x09, 0x9b, 0xc4, 0x56, 0xfd, 0x6f, 0xb6, 0x24, 0x8f, 0x1d, + 0x20, 0xb2, 0x19, 0x8b, 0x52, 0xc0, 0x6b, 0xf9, 0x11, 0x83, + 0x28, 0xba, 0x63, 0xf1, 0x5a, 0xc8, 0xf5, 0x67, 0xcc, 0x5e, + 0x87, 0x15, 0xbe, 0x2c, 0xe6, 0x74, 0xdf, 0x4d, 0x94, 0x06, + 0xad, 0x3f, 0x02, 0x90, 0x3b, 0xa9, 0x70, 0xe2, 0x49, 0xdb, + 0x33, 0xa1, 0x0a, 0x98, 0x41, 0xd3, 0x78, 0xea, 0xd7, 0x45, + 0xee, 0x7c, 0xa5, 0x37, 0x9c, 0x0e, 0x51, 0xc3, 0x68, 0xfa, + 0x23, 0xb1, 0x1a, 0x88, 0xb5, 0x27, 0x8c, 0x1e, 0xc7, 0x55, + 0xfe, 0x6c, 0x84, 0x16, 0xbd, 0x2f, 0xf6, 0x64, 0xcf, 0x5d, + 0x60, 0xf2, 0x59, 0xcb, 0x12, 0x80, 0x2b, 0xb9, 0x95, 0x07, + 0xac, 0x3e, 0xe7, 0x75, 0xde, 0x4c, 0x71, 0xe3, 0x48, 0xda, + 0x03, 0x91, 0x3a, 0xa8, 0x40, 0xd2, 0x79, 0xeb, 0x32, 0xa0, + 0x0b, 0x99, 0xa4, 0x36, 0x9d, 0x0f, 0xd6, 0x44, 0xef, 0x7d, + 0x22, 0xb0, 0x1b, 0x89, 0x50, 0xc2, 0x69, 0xfb, 0xc6, 0x54, + 0xff, 0x6d, 0xb4, 0x26, 0x8d, 0x1f, 0xf7, 0x65, 0xce, 0x5c, + 0x85, 0x17, 0xbc, 0x2e, 0x13, 0x81, 0x2a, 0xb8, 0x61, 0xf3, + 0x58, 0xca, 0x00, 0x93, 0x3b, 0xa8, 0x76, 0xe5, 0x4d, 0xde, + 0xec, 0x7f, 0xd7, 0x44, 0x9a, 0x09, 0xa1, 0x32, 0xc5, 0x56, + 0xfe, 0x6d, 0xb3, 0x20, 0x88, 0x1b, 0x29, 0xba, 0x12, 0x81, + 0x5f, 0xcc, 0x64, 0xf7, 0x97, 0x04, 0xac, 0x3f, 0xe1, 0x72, + 0xda, 0x49, 0x7b, 0xe8, 0x40, 0xd3, 0x0d, 0x9e, 0x36, 0xa5, + 0x52, 0xc1, 0x69, 0xfa, 0x24, 0xb7, 0x1f, 0x8c, 0xbe, 0x2d, + 0x85, 0x16, 0xc8, 0x5b, 0xf3, 0x60, 0x33, 0xa0, 0x08, 0x9b, + 0x45, 0xd6, 0x7e, 0xed, 0xdf, 0x4c, 0xe4, 0x77, 0xa9, 0x3a, + 0x92, 0x01, 0xf6, 0x65, 0xcd, 0x5e, 0x80, 0x13, 0xbb, 0x28, + 0x1a, 0x89, 0x21, 0xb2, 0x6c, 0xff, 0x57, 0xc4, 0xa4, 0x37, + 0x9f, 0x0c, 0xd2, 0x41, 0xe9, 0x7a, 0x48, 0xdb, 0x73, 0xe0, + 0x3e, 0xad, 0x05, 0x96, 0x61, 0xf2, 0x5a, 0xc9, 0x17, 0x84, + 0x2c, 0xbf, 0x8d, 0x1e, 0xb6, 0x25, 0xfb, 0x68, 0xc0, 0x53, + 0x66, 0xf5, 0x5d, 0xce, 0x10, 0x83, 0x2b, 0xb8, 0x8a, 0x19, + 0xb1, 0x22, 0xfc, 0x6f, 0xc7, 0x54, 0xa3, 0x30, 0x98, 0x0b, + 0xd5, 0x46, 0xee, 0x7d, 0x4f, 0xdc, 0x74, 0xe7, 0x39, 0xaa, + 0x02, 0x91, 0xf1, 0x62, 0xca, 0x59, 0x87, 0x14, 0xbc, 0x2f, + 0x1d, 0x8e, 0x26, 0xb5, 0x6b, 0xf8, 0x50, 0xc3, 0x34, 0xa7, + 0x0f, 0x9c, 0x42, 0xd1, 0x79, 0xea, 0xd8, 0x4b, 0xe3, 0x70, + 0xae, 0x3d, 0x95, 0x06, 0x55, 0xc6, 0x6e, 0xfd, 0x23, 0xb0, + 0x18, 0x8b, 0xb9, 0x2a, 0x82, 0x11, 0xcf, 0x5c, 0xf4, 0x67, + 0x90, 0x03, 0xab, 0x38, 0xe6, 0x75, 0xdd, 0x4e, 0x7c, 0xef, + 0x47, 0xd4, 0x0a, 0x99, 0x31, 0xa2, 0xc2, 0x51, 0xf9, 0x6a, + 0xb4, 0x27, 0x8f, 0x1c, 0x2e, 0xbd, 0x15, 0x86, 0x58, 0xcb, + 0x63, 0xf0, 0x07, 0x94, 0x3c, 0xaf, 0x71, 0xe2, 0x4a, 0xd9, + 0xeb, 0x78, 0xd0, 0x43, 0x9d, 0x0e, 0xa6, 0x35, 0x00, 0x94, + 0x35, 0xa1, 0x6a, 0xfe, 0x5f, 0xcb, 0xd4, 0x40, 0xe1, 0x75, + 0xbe, 0x2a, 0x8b, 0x1f, 0xb5, 0x21, 0x80, 0x14, 0xdf, 0x4b, + 0xea, 0x7e, 0x61, 0xf5, 0x54, 0xc0, 0x0b, 0x9f, 0x3e, 0xaa, + 0x77, 0xe3, 0x42, 0xd6, 0x1d, 0x89, 0x28, 0xbc, 0xa3, 0x37, + 0x96, 0x02, 0xc9, 0x5d, 0xfc, 0x68, 0xc2, 0x56, 0xf7, 0x63, + 0xa8, 0x3c, 0x9d, 0x09, 0x16, 0x82, 0x23, 0xb7, 0x7c, 0xe8, + 0x49, 0xdd, 0xee, 0x7a, 0xdb, 0x4f, 0x84, 0x10, 0xb1, 0x25, + 0x3a, 0xae, 0x0f, 0x9b, 0x50, 0xc4, 0x65, 0xf1, 0x5b, 0xcf, + 0x6e, 0xfa, 0x31, 0xa5, 0x04, 0x90, 0x8f, 0x1b, 0xba, 0x2e, + 0xe5, 0x71, 0xd0, 0x44, 0x99, 0x0d, 0xac, 0x38, 0xf3, 0x67, + 0xc6, 0x52, 0x4d, 0xd9, 0x78, 0xec, 0x27, 0xb3, 0x12, 0x86, + 0x2c, 0xb8, 0x19, 0x8d, 0x46, 0xd2, 0x73, 0xe7, 0xf8, 0x6c, + 0xcd, 0x59, 0x92, 0x06, 0xa7, 0x33, 0xc1, 0x55, 0xf4, 0x60, + 0xab, 0x3f, 0x9e, 0x0a, 0x15, 0x81, 0x20, 0xb4, 0x7f, 0xeb, + 0x4a, 0xde, 0x74, 0xe0, 0x41, 0xd5, 0x1e, 0x8a, 0x2b, 0xbf, + 0xa0, 0x34, 0x95, 0x01, 0xca, 0x5e, 0xff, 0x6b, 0xb6, 0x22, + 0x83, 0x17, 0xdc, 0x48, 0xe9, 0x7d, 0x62, 0xf6, 0x57, 0xc3, + 0x08, 0x9c, 0x3d, 0xa9, 0x03, 0x97, 0x36, 0xa2, 0x69, 0xfd, + 0x5c, 0xc8, 0xd7, 0x43, 0xe2, 0x76, 0xbd, 0x29, 0x88, 0x1c, + 0x2f, 0xbb, 0x1a, 0x8e, 0x45, 0xd1, 0x70, 0xe4, 0xfb, 0x6f, + 0xce, 0x5a, 0x91, 0x05, 0xa4, 0x30, 0x9a, 0x0e, 0xaf, 0x3b, + 0xf0, 0x64, 0xc5, 0x51, 0x4e, 0xda, 0x7b, 0xef, 0x24, 0xb0, + 0x11, 0x85, 0x58, 0xcc, 0x6d, 0xf9, 0x32, 0xa6, 0x07, 0x93, + 0x8c, 0x18, 0xb9, 0x2d, 0xe6, 0x72, 0xd3, 0x47, 0xed, 0x79, + 0xd8, 0x4c, 0x87, 0x13, 0xb2, 0x26, 0x39, 0xad, 0x0c, 0x98, + 0x53, 0xc7, 0x66, 0xf2, 0x00, 0x95, 0x37, 0xa2, 0x6e, 0xfb, + 0x59, 0xcc, 0xdc, 0x49, 0xeb, 0x7e, 0xb2, 0x27, 0x85, 0x10, + 0xa5, 0x30, 0x92, 0x07, 0xcb, 0x5e, 0xfc, 0x69, 0x79, 0xec, + 0x4e, 0xdb, 0x17, 0x82, 0x20, 0xb5, 0x57, 0xc2, 0x60, 0xf5, + 0x39, 0xac, 0x0e, 0x9b, 0x8b, 0x1e, 0xbc, 0x29, 0xe5, 0x70, + 0xd2, 0x47, 0xf2, 0x67, 0xc5, 0x50, 0x9c, 0x09, 0xab, 0x3e, + 0x2e, 0xbb, 0x19, 0x8c, 0x40, 0xd5, 0x77, 0xe2, 0xae, 0x3b, + 0x99, 0x0c, 0xc0, 0x55, 0xf7, 0x62, 0x72, 0xe7, 0x45, 0xd0, + 0x1c, 0x89, 0x2b, 0xbe, 0x0b, 0x9e, 0x3c, 0xa9, 0x65, 0xf0, + 0x52, 0xc7, 0xd7, 0x42, 0xe0, 0x75, 0xb9, 0x2c, 0x8e, 0x1b, + 0xf9, 0x6c, 0xce, 0x5b, 0x97, 0x02, 0xa0, 0x35, 0x25, 0xb0, + 0x12, 0x87, 0x4b, 0xde, 0x7c, 0xe9, 0x5c, 0xc9, 0x6b, 0xfe, + 0x32, 0xa7, 0x05, 0x90, 0x80, 0x15, 0xb7, 0x22, 0xee, 0x7b, + 0xd9, 0x4c, 0x41, 0xd4, 0x76, 0xe3, 0x2f, 0xba, 0x18, 0x8d, + 0x9d, 0x08, 0xaa, 0x3f, 0xf3, 0x66, 0xc4, 0x51, 0xe4, 0x71, + 0xd3, 0x46, 0x8a, 0x1f, 0xbd, 0x28, 0x38, 0xad, 0x0f, 0x9a, + 0x56, 0xc3, 0x61, 0xf4, 0x16, 0x83, 0x21, 0xb4, 0x78, 0xed, + 0x4f, 0xda, 0xca, 0x5f, 0xfd, 0x68, 0xa4, 0x31, 0x93, 0x06, + 0xb3, 0x26, 0x84, 0x11, 0xdd, 0x48, 0xea, 0x7f, 0x6f, 0xfa, + 0x58, 0xcd, 0x01, 0x94, 0x36, 0xa3, 0xef, 0x7a, 0xd8, 0x4d, + 0x81, 0x14, 0xb6, 0x23, 0x33, 0xa6, 0x04, 0x91, 0x5d, 0xc8, + 0x6a, 0xff, 0x4a, 0xdf, 0x7d, 0xe8, 0x24, 0xb1, 0x13, 0x86, + 0x96, 0x03, 0xa1, 0x34, 0xf8, 0x6d, 0xcf, 0x5a, 0xb8, 0x2d, + 0x8f, 0x1a, 0xd6, 0x43, 0xe1, 0x74, 0x64, 0xf1, 0x53, 0xc6, + 0x0a, 0x9f, 0x3d, 0xa8, 0x1d, 0x88, 0x2a, 0xbf, 0x73, 0xe6, + 0x44, 0xd1, 0xc1, 0x54, 0xf6, 0x63, 0xaf, 0x3a, 0x98, 0x0d, + 0x00, 0x96, 0x31, 0xa7, 0x62, 0xf4, 0x53, 0xc5, 0xc4, 0x52, + 0xf5, 0x63, 0xa6, 0x30, 0x97, 0x01, 0x95, 0x03, 0xa4, 0x32, + 0xf7, 0x61, 0xc6, 0x50, 0x51, 0xc7, 0x60, 0xf6, 0x33, 0xa5, + 0x02, 0x94, 0x37, 0xa1, 0x06, 0x90, 0x55, 0xc3, 0x64, 0xf2, + 0xf3, 0x65, 0xc2, 0x54, 0x91, 0x07, 0xa0, 0x36, 0xa2, 0x34, + 0x93, 0x05, 0xc0, 0x56, 0xf1, 0x67, 0x66, 0xf0, 0x57, 0xc1, + 0x04, 0x92, 0x35, 0xa3, 0x6e, 0xf8, 0x5f, 0xc9, 0x0c, 0x9a, + 0x3d, 0xab, 0xaa, 0x3c, 0x9b, 0x0d, 0xc8, 0x5e, 0xf9, 0x6f, + 0xfb, 0x6d, 0xca, 0x5c, 0x99, 0x0f, 0xa8, 0x3e, 0x3f, 0xa9, + 0x0e, 0x98, 0x5d, 0xcb, 0x6c, 0xfa, 0x59, 0xcf, 0x68, 0xfe, + 0x3b, 0xad, 0x0a, 0x9c, 0x9d, 0x0b, 0xac, 0x3a, 0xff, 0x69, + 0xce, 0x58, 0xcc, 0x5a, 0xfd, 0x6b, 0xae, 0x38, 0x9f, 0x09, + 0x08, 0x9e, 0x39, 0xaf, 0x6a, 0xfc, 0x5b, 0xcd, 0xdc, 0x4a, + 0xed, 0x7b, 0xbe, 0x28, 0x8f, 0x19, 0x18, 0x8e, 0x29, 0xbf, + 0x7a, 0xec, 0x4b, 0xdd, 0x49, 0xdf, 0x78, 0xee, 0x2b, 0xbd, + 0x1a, 0x8c, 0x8d, 0x1b, 0xbc, 0x2a, 0xef, 0x79, 0xde, 0x48, + 0xeb, 0x7d, 0xda, 0x4c, 0x89, 0x1f, 0xb8, 0x2e, 0x2f, 0xb9, + 0x1e, 0x88, 0x4d, 0xdb, 0x7c, 0xea, 0x7e, 0xe8, 0x4f, 0xd9, + 0x1c, 0x8a, 0x2d, 0xbb, 0xba, 0x2c, 0x8b, 0x1d, 0xd8, 0x4e, + 0xe9, 0x7f, 0xb2, 0x24, 0x83, 0x15, 0xd0, 0x46, 0xe1, 0x77, + 0x76, 0xe0, 0x47, 0xd1, 0x14, 0x82, 0x25, 0xb3, 0x27, 0xb1, + 0x16, 0x80, 0x45, 0xd3, 0x74, 0xe2, 0xe3, 0x75, 0xd2, 0x44, + 0x81, 0x17, 0xb0, 0x26, 0x85, 0x13, 0xb4, 0x22, 0xe7, 0x71, + 0xd6, 0x40, 0x41, 0xd7, 0x70, 0xe6, 0x23, 0xb5, 0x12, 0x84, + 0x10, 0x86, 0x21, 0xb7, 0x72, 0xe4, 0x43, 0xd5, 0xd4, 0x42, + 0xe5, 0x73, 0xb6, 0x20, 0x87, 0x11, 0x00, 0x97, 0x33, 0xa4, + 0x66, 0xf1, 0x55, 0xc2, 0xcc, 0x5b, 0xff, 0x68, 0xaa, 0x3d, + 0x99, 0x0e, 0x85, 0x12, 0xb6, 0x21, 0xe3, 0x74, 0xd0, 0x47, + 0x49, 0xde, 0x7a, 0xed, 0x2f, 0xb8, 0x1c, 0x8b, 0x17, 0x80, + 0x24, 0xb3, 0x71, 0xe6, 0x42, 0xd5, 0xdb, 0x4c, 0xe8, 0x7f, + 0xbd, 0x2a, 0x8e, 0x19, 0x92, 0x05, 0xa1, 0x36, 0xf4, 0x63, + 0xc7, 0x50, 0x5e, 0xc9, 0x6d, 0xfa, 0x38, 0xaf, 0x0b, 0x9c, + 0x2e, 0xb9, 0x1d, 0x8a, 0x48, 0xdf, 0x7b, 0xec, 0xe2, 0x75, + 0xd1, 0x46, 0x84, 0x13, 0xb7, 0x20, 0xab, 0x3c, 0x98, 0x0f, + 0xcd, 0x5a, 0xfe, 0x69, 0x67, 0xf0, 0x54, 0xc3, 0x01, 0x96, + 0x32, 0xa5, 0x39, 0xae, 0x0a, 0x9d, 0x5f, 0xc8, 0x6c, 0xfb, + 0xf5, 0x62, 0xc6, 0x51, 0x93, 0x04, 0xa0, 0x37, 0xbc, 0x2b, + 0x8f, 0x18, 0xda, 0x4d, 0xe9, 0x7e, 0x70, 0xe7, 0x43, 0xd4, + 0x16, 0x81, 0x25, 0xb2, 0x5c, 0xcb, 0x6f, 0xf8, 0x3a, 0xad, + 0x09, 0x9e, 0x90, 0x07, 0xa3, 0x34, 0xf6, 0x61, 0xc5, 0x52, + 0xd9, 0x4e, 0xea, 0x7d, 0xbf, 0x28, 0x8c, 0x1b, 0x15, 0x82, + 0x26, 0xb1, 0x73, 0xe4, 0x40, 0xd7, 0x4b, 0xdc, 0x78, 0xef, + 0x2d, 0xba, 0x1e, 0x89, 0x87, 0x10, 0xb4, 0x23, 0xe1, 0x76, + 0xd2, 0x45, 0xce, 0x59, 0xfd, 0x6a, 0xa8, 0x3f, 0x9b, 0x0c, + 0x02, 0x95, 0x31, 0xa6, 0x64, 0xf3, 0x57, 0xc0, 0x72, 0xe5, + 0x41, 0xd6, 0x14, 0x83, 0x27, 0xb0, 0xbe, 0x29, 0x8d, 0x1a, + 0xd8, 0x4f, 0xeb, 0x7c, 0xf7, 0x60, 0xc4, 0x53, 0x91, 0x06, + 0xa2, 0x35, 0x3b, 0xac, 0x08, 0x9f, 0x5d, 0xca, 0x6e, 0xf9, + 0x65, 0xf2, 0x56, 0xc1, 0x03, 0x94, 0x30, 0xa7, 0xa9, 0x3e, + 0x9a, 0x0d, 0xcf, 0x58, 0xfc, 0x6b, 0xe0, 0x77, 0xd3, 0x44, + 0x86, 0x11, 0xb5, 0x22, 0x2c, 0xbb, 0x1f, 0x88, 0x4a, 0xdd, + 0x79, 0xee, 0x00, 0x98, 0x2d, 0xb5, 0x5a, 0xc2, 0x77, 0xef, + 0xb4, 0x2c, 0x99, 0x01, 0xee, 0x76, 0xc3, 0x5b, 0x75, 0xed, + 0x58, 0xc0, 0x2f, 0xb7, 0x02, 0x9a, 0xc1, 0x59, 0xec, 0x74, + 0x9b, 0x03, 0xb6, 0x2e, 0xea, 0x72, 0xc7, 0x5f, 0xb0, 0x28, + 0x9d, 0x05, 0x5e, 0xc6, 0x73, 0xeb, 0x04, 0x9c, 0x29, 0xb1, + 0x9f, 0x07, 0xb2, 0x2a, 0xc5, 0x5d, 0xe8, 0x70, 0x2b, 0xb3, + 0x06, 0x9e, 0x71, 0xe9, 0x5c, 0xc4, 0xc9, 0x51, 0xe4, 0x7c, + 0x93, 0x0b, 0xbe, 0x26, 0x7d, 0xe5, 0x50, 0xc8, 0x27, 0xbf, + 0x0a, 0x92, 0xbc, 0x24, 0x91, 0x09, 0xe6, 0x7e, 0xcb, 0x53, + 0x08, 0x90, 0x25, 0xbd, 0x52, 0xca, 0x7f, 0xe7, 0x23, 0xbb, + 0x0e, 0x96, 0x79, 0xe1, 0x54, 0xcc, 0x97, 0x0f, 0xba, 0x22, + 0xcd, 0x55, 0xe0, 0x78, 0x56, 0xce, 0x7b, 0xe3, 0x0c, 0x94, + 0x21, 0xb9, 0xe2, 0x7a, 0xcf, 0x57, 0xb8, 0x20, 0x95, 0x0d, + 0x8f, 0x17, 0xa2, 0x3a, 0xd5, 0x4d, 0xf8, 0x60, 0x3b, 0xa3, + 0x16, 0x8e, 0x61, 0xf9, 0x4c, 0xd4, 0xfa, 0x62, 0xd7, 0x4f, + 0xa0, 0x38, 0x8d, 0x15, 0x4e, 0xd6, 0x63, 0xfb, 0x14, 0x8c, + 0x39, 0xa1, 0x65, 0xfd, 0x48, 0xd0, 0x3f, 0xa7, 0x12, 0x8a, + 0xd1, 0x49, 0xfc, 0x64, 0x8b, 0x13, 0xa6, 0x3e, 0x10, 0x88, + 0x3d, 0xa5, 0x4a, 0xd2, 0x67, 0xff, 0xa4, 0x3c, 0x89, 0x11, + 0xfe, 0x66, 0xd3, 0x4b, 0x46, 0xde, 0x6b, 0xf3, 0x1c, 0x84, + 0x31, 0xa9, 0xf2, 0x6a, 0xdf, 0x47, 0xa8, 0x30, 0x85, 0x1d, + 0x33, 0xab, 0x1e, 0x86, 0x69, 0xf1, 0x44, 0xdc, 0x87, 0x1f, + 0xaa, 0x32, 0xdd, 0x45, 0xf0, 0x68, 0xac, 0x34, 0x81, 0x19, + 0xf6, 0x6e, 0xdb, 0x43, 0x18, 0x80, 0x35, 0xad, 0x42, 0xda, + 0x6f, 0xf7, 0xd9, 0x41, 0xf4, 0x6c, 0x83, 0x1b, 0xae, 0x36, + 0x6d, 0xf5, 0x40, 0xd8, 0x37, 0xaf, 0x1a, 0x82, 0x00, 0x99, + 0x2f, 0xb6, 0x5e, 0xc7, 0x71, 0xe8, 0xbc, 0x25, 0x93, 0x0a, + 0xe2, 0x7b, 0xcd, 0x54, 0x65, 0xfc, 0x4a, 0xd3, 0x3b, 0xa2, + 0x14, 0x8d, 0xd9, 0x40, 0xf6, 0x6f, 0x87, 0x1e, 0xa8, 0x31, + 0xca, 0x53, 0xe5, 0x7c, 0x94, 0x0d, 0xbb, 0x22, 0x76, 0xef, + 0x59, 0xc0, 0x28, 0xb1, 0x07, 0x9e, 0xaf, 0x36, 0x80, 0x19, + 0xf1, 0x68, 0xde, 0x47, 0x13, 0x8a, 0x3c, 0xa5, 0x4d, 0xd4, + 0x62, 0xfb, 0x89, 0x10, 0xa6, 0x3f, 0xd7, 0x4e, 0xf8, 0x61, + 0x35, 0xac, 0x1a, 0x83, 0x6b, 0xf2, 0x44, 0xdd, 0xec, 0x75, + 0xc3, 0x5a, 0xb2, 0x2b, 0x9d, 0x04, 0x50, 0xc9, 0x7f, 0xe6, + 0x0e, 0x97, 0x21, 0xb8, 0x43, 0xda, 0x6c, 0xf5, 0x1d, 0x84, + 0x32, 0xab, 0xff, 0x66, 0xd0, 0x49, 0xa1, 0x38, 0x8e, 0x17, + 0x26, 0xbf, 0x09, 0x90, 0x78, 0xe1, 0x57, 0xce, 0x9a, 0x03, + 0xb5, 0x2c, 0xc4, 0x5d, 0xeb, 0x72, 0x0f, 0x96, 0x20, 0xb9, + 0x51, 0xc8, 0x7e, 0xe7, 0xb3, 0x2a, 0x9c, 0x05, 0xed, 0x74, + 0xc2, 0x5b, 0x6a, 0xf3, 0x45, 0xdc, 0x34, 0xad, 0x1b, 0x82, + 0xd6, 0x4f, 0xf9, 0x60, 0x88, 0x11, 0xa7, 0x3e, 0xc5, 0x5c, + 0xea, 0x73, 0x9b, 0x02, 0xb4, 0x2d, 0x79, 0xe0, 0x56, 0xcf, + 0x27, 0xbe, 0x08, 0x91, 0xa0, 0x39, 0x8f, 0x16, 0xfe, 0x67, + 0xd1, 0x48, 0x1c, 0x85, 0x33, 0xaa, 0x42, 0xdb, 0x6d, 0xf4, + 0x86, 0x1f, 0xa9, 0x30, 0xd8, 0x41, 0xf7, 0x6e, 0x3a, 0xa3, + 0x15, 0x8c, 0x64, 0xfd, 0x4b, 0xd2, 0xe3, 0x7a, 0xcc, 0x55, + 0xbd, 0x24, 0x92, 0x0b, 0x5f, 0xc6, 0x70, 0xe9, 0x01, 0x98, + 0x2e, 0xb7, 0x4c, 0xd5, 0x63, 0xfa, 0x12, 0x8b, 0x3d, 0xa4, + 0xf0, 0x69, 0xdf, 0x46, 0xae, 0x37, 0x81, 0x18, 0x29, 0xb0, + 0x06, 0x9f, 0x77, 0xee, 0x58, 0xc1, 0x95, 0x0c, 0xba, 0x23, + 0xcb, 0x52, 0xe4, 0x7d, 0x00, 0x9a, 0x29, 0xb3, 0x52, 0xc8, + 0x7b, 0xe1, 0xa4, 0x3e, 0x8d, 0x17, 0xf6, 0x6c, 0xdf, 0x45, + 0x55, 0xcf, 0x7c, 0xe6, 0x07, 0x9d, 0x2e, 0xb4, 0xf1, 0x6b, + 0xd8, 0x42, 0xa3, 0x39, 0x8a, 0x10, 0xaa, 0x30, 0x83, 0x19, + 0xf8, 0x62, 0xd1, 0x4b, 0x0e, 0x94, 0x27, 0xbd, 0x5c, 0xc6, + 0x75, 0xef, 0xff, 0x65, 0xd6, 0x4c, 0xad, 0x37, 0x84, 0x1e, + 0x5b, 0xc1, 0x72, 0xe8, 0x09, 0x93, 0x20, 0xba, 0x49, 0xd3, + 0x60, 0xfa, 0x1b, 0x81, 0x32, 0xa8, 0xed, 0x77, 0xc4, 0x5e, + 0xbf, 0x25, 0x96, 0x0c, 0x1c, 0x86, 0x35, 0xaf, 0x4e, 0xd4, + 0x67, 0xfd, 0xb8, 0x22, 0x91, 0x0b, 0xea, 0x70, 0xc3, 0x59, + 0xe3, 0x79, 0xca, 0x50, 0xb1, 0x2b, 0x98, 0x02, 0x47, 0xdd, + 0x6e, 0xf4, 0x15, 0x8f, 0x3c, 0xa6, 0xb6, 0x2c, 0x9f, 0x05, + 0xe4, 0x7e, 0xcd, 0x57, 0x12, 0x88, 0x3b, 0xa1, 0x40, 0xda, + 0x69, 0xf3, 0x92, 0x08, 0xbb, 0x21, 0xc0, 0x5a, 0xe9, 0x73, + 0x36, 0xac, 0x1f, 0x85, 0x64, 0xfe, 0x4d, 0xd7, 0xc7, 0x5d, + 0xee, 0x74, 0x95, 0x0f, 0xbc, 0x26, 0x63, 0xf9, 0x4a, 0xd0, + 0x31, 0xab, 0x18, 0x82, 0x38, 0xa2, 0x11, 0x8b, 0x6a, 0xf0, + 0x43, 0xd9, 0x9c, 0x06, 0xb5, 0x2f, 0xce, 0x54, 0xe7, 0x7d, + 0x6d, 0xf7, 0x44, 0xde, 0x3f, 0xa5, 0x16, 0x8c, 0xc9, 0x53, + 0xe0, 0x7a, 0x9b, 0x01, 0xb2, 0x28, 0xdb, 0x41, 0xf2, 0x68, + 0x89, 0x13, 0xa0, 0x3a, 0x7f, 0xe5, 0x56, 0xcc, 0x2d, 0xb7, + 0x04, 0x9e, 0x8e, 0x14, 0xa7, 0x3d, 0xdc, 0x46, 0xf5, 0x6f, + 0x2a, 0xb0, 0x03, 0x99, 0x78, 0xe2, 0x51, 0xcb, 0x71, 0xeb, + 0x58, 0xc2, 0x23, 0xb9, 0x0a, 0x90, 0xd5, 0x4f, 0xfc, 0x66, + 0x87, 0x1d, 0xae, 0x34, 0x24, 0xbe, 0x0d, 0x97, 0x76, 0xec, + 0x5f, 0xc5, 0x80, 0x1a, 0xa9, 0x33, 0xd2, 0x48, 0xfb, 0x61, + 0x00, 0x9b, 0x2b, 0xb0, 0x56, 0xcd, 0x7d, 0xe6, 0xac, 0x37, + 0x87, 0x1c, 0xfa, 0x61, 0xd1, 0x4a, 0x45, 0xde, 0x6e, 0xf5, + 0x13, 0x88, 0x38, 0xa3, 0xe9, 0x72, 0xc2, 0x59, 0xbf, 0x24, + 0x94, 0x0f, 0x8a, 0x11, 0xa1, 0x3a, 0xdc, 0x47, 0xf7, 0x6c, + 0x26, 0xbd, 0x0d, 0x96, 0x70, 0xeb, 0x5b, 0xc0, 0xcf, 0x54, + 0xe4, 0x7f, 0x99, 0x02, 0xb2, 0x29, 0x63, 0xf8, 0x48, 0xd3, + 0x35, 0xae, 0x1e, 0x85, 0x09, 0x92, 0x22, 0xb9, 0x5f, 0xc4, + 0x74, 0xef, 0xa5, 0x3e, 0x8e, 0x15, 0xf3, 0x68, 0xd8, 0x43, + 0x4c, 0xd7, 0x67, 0xfc, 0x1a, 0x81, 0x31, 0xaa, 0xe0, 0x7b, + 0xcb, 0x50, 0xb6, 0x2d, 0x9d, 0x06, 0x83, 0x18, 0xa8, 0x33, + 0xd5, 0x4e, 0xfe, 0x65, 0x2f, 0xb4, 0x04, 0x9f, 0x79, 0xe2, + 0x52, 0xc9, 0xc6, 0x5d, 0xed, 0x76, 0x90, 0x0b, 0xbb, 0x20, + 0x6a, 0xf1, 0x41, 0xda, 0x3c, 0xa7, 0x17, 0x8c, 0x12, 0x89, + 0x39, 0xa2, 0x44, 0xdf, 0x6f, 0xf4, 0xbe, 0x25, 0x95, 0x0e, + 0xe8, 0x73, 0xc3, 0x58, 0x57, 0xcc, 0x7c, 0xe7, 0x01, 0x9a, + 0x2a, 0xb1, 0xfb, 0x60, 0xd0, 0x4b, 0xad, 0x36, 0x86, 0x1d, + 0x98, 0x03, 0xb3, 0x28, 0xce, 0x55, 0xe5, 0x7e, 0x34, 0xaf, + 0x1f, 0x84, 0x62, 0xf9, 0x49, 0xd2, 0xdd, 0x46, 0xf6, 0x6d, + 0x8b, 0x10, 0xa0, 0x3b, 0x71, 0xea, 0x5a, 0xc1, 0x27, 0xbc, + 0x0c, 0x97, 0x1b, 0x80, 0x30, 0xab, 0x4d, 0xd6, 0x66, 0xfd, + 0xb7, 0x2c, 0x9c, 0x07, 0xe1, 0x7a, 0xca, 0x51, 0x5e, 0xc5, + 0x75, 0xee, 0x08, 0x93, 0x23, 0xb8, 0xf2, 0x69, 0xd9, 0x42, + 0xa4, 0x3f, 0x8f, 0x14, 0x91, 0x0a, 0xba, 0x21, 0xc7, 0x5c, + 0xec, 0x77, 0x3d, 0xa6, 0x16, 0x8d, 0x6b, 0xf0, 0x40, 0xdb, + 0xd4, 0x4f, 0xff, 0x64, 0x82, 0x19, 0xa9, 0x32, 0x78, 0xe3, + 0x53, 0xc8, 0x2e, 0xb5, 0x05, 0x9e, 0x00, 0x9c, 0x25, 0xb9, + 0x4a, 0xd6, 0x6f, 0xf3, 0x94, 0x08, 0xb1, 0x2d, 0xde, 0x42, + 0xfb, 0x67, 0x35, 0xa9, 0x10, 0x8c, 0x7f, 0xe3, 0x5a, 0xc6, + 0xa1, 0x3d, 0x84, 0x18, 0xeb, 0x77, 0xce, 0x52, 0x6a, 0xf6, + 0x4f, 0xd3, 0x20, 0xbc, 0x05, 0x99, 0xfe, 0x62, 0xdb, 0x47, + 0xb4, 0x28, 0x91, 0x0d, 0x5f, 0xc3, 0x7a, 0xe6, 0x15, 0x89, + 0x30, 0xac, 0xcb, 0x57, 0xee, 0x72, 0x81, 0x1d, 0xa4, 0x38, + 0xd4, 0x48, 0xf1, 0x6d, 0x9e, 0x02, 0xbb, 0x27, 0x40, 0xdc, + 0x65, 0xf9, 0x0a, 0x96, 0x2f, 0xb3, 0xe1, 0x7d, 0xc4, 0x58, + 0xab, 0x37, 0x8e, 0x12, 0x75, 0xe9, 0x50, 0xcc, 0x3f, 0xa3, + 0x1a, 0x86, 0xbe, 0x22, 0x9b, 0x07, 0xf4, 0x68, 0xd1, 0x4d, + 0x2a, 0xb6, 0x0f, 0x93, 0x60, 0xfc, 0x45, 0xd9, 0x8b, 0x17, + 0xae, 0x32, 0xc1, 0x5d, 0xe4, 0x78, 0x1f, 0x83, 0x3a, 0xa6, + 0x55, 0xc9, 0x70, 0xec, 0xb5, 0x29, 0x90, 0x0c, 0xff, 0x63, + 0xda, 0x46, 0x21, 0xbd, 0x04, 0x98, 0x6b, 0xf7, 0x4e, 0xd2, + 0x80, 0x1c, 0xa5, 0x39, 0xca, 0x56, 0xef, 0x73, 0x14, 0x88, + 0x31, 0xad, 0x5e, 0xc2, 0x7b, 0xe7, 0xdf, 0x43, 0xfa, 0x66, + 0x95, 0x09, 0xb0, 0x2c, 0x4b, 0xd7, 0x6e, 0xf2, 0x01, 0x9d, + 0x24, 0xb8, 0xea, 0x76, 0xcf, 0x53, 0xa0, 0x3c, 0x85, 0x19, + 0x7e, 0xe2, 0x5b, 0xc7, 0x34, 0xa8, 0x11, 0x8d, 0x61, 0xfd, + 0x44, 0xd8, 0x2b, 0xb7, 0x0e, 0x92, 0xf5, 0x69, 0xd0, 0x4c, + 0xbf, 0x23, 0x9a, 0x06, 0x54, 0xc8, 0x71, 0xed, 0x1e, 0x82, + 0x3b, 0xa7, 0xc0, 0x5c, 0xe5, 0x79, 0x8a, 0x16, 0xaf, 0x33, + 0x0b, 0x97, 0x2e, 0xb2, 0x41, 0xdd, 0x64, 0xf8, 0x9f, 0x03, + 0xba, 0x26, 0xd5, 0x49, 0xf0, 0x6c, 0x3e, 0xa2, 0x1b, 0x87, + 0x74, 0xe8, 0x51, 0xcd, 0xaa, 0x36, 0x8f, 0x13, 0xe0, 0x7c, + 0xc5, 0x59, 0x00, 0x9d, 0x27, 0xba, 0x4e, 0xd3, 0x69, 0xf4, + 0x9c, 0x01, 0xbb, 0x26, 0xd2, 0x4f, 0xf5, 0x68, 0x25, 0xb8, + 0x02, 0x9f, 0x6b, 0xf6, 0x4c, 0xd1, 0xb9, 0x24, 0x9e, 0x03, + 0xf7, 0x6a, 0xd0, 0x4d, 0x4a, 0xd7, 0x6d, 0xf0, 0x04, 0x99, + 0x23, 0xbe, 0xd6, 0x4b, 0xf1, 0x6c, 0x98, 0x05, 0xbf, 0x22, + 0x6f, 0xf2, 0x48, 0xd5, 0x21, 0xbc, 0x06, 0x9b, 0xf3, 0x6e, + 0xd4, 0x49, 0xbd, 0x20, 0x9a, 0x07, 0x94, 0x09, 0xb3, 0x2e, + 0xda, 0x47, 0xfd, 0x60, 0x08, 0x95, 0x2f, 0xb2, 0x46, 0xdb, + 0x61, 0xfc, 0xb1, 0x2c, 0x96, 0x0b, 0xff, 0x62, 0xd8, 0x45, + 0x2d, 0xb0, 0x0a, 0x97, 0x63, 0xfe, 0x44, 0xd9, 0xde, 0x43, + 0xf9, 0x64, 0x90, 0x0d, 0xb7, 0x2a, 0x42, 0xdf, 0x65, 0xf8, + 0x0c, 0x91, 0x2b, 0xb6, 0xfb, 0x66, 0xdc, 0x41, 0xb5, 0x28, + 0x92, 0x0f, 0x67, 0xfa, 0x40, 0xdd, 0x29, 0xb4, 0x0e, 0x93, + 0x35, 0xa8, 0x12, 0x8f, 0x7b, 0xe6, 0x5c, 0xc1, 0xa9, 0x34, + 0x8e, 0x13, 0xe7, 0x7a, 0xc0, 0x5d, 0x10, 0x8d, 0x37, 0xaa, + 0x5e, 0xc3, 0x79, 0xe4, 0x8c, 0x11, 0xab, 0x36, 0xc2, 0x5f, + 0xe5, 0x78, 0x7f, 0xe2, 0x58, 0xc5, 0x31, 0xac, 0x16, 0x8b, + 0xe3, 0x7e, 0xc4, 0x59, 0xad, 0x30, 0x8a, 0x17, 0x5a, 0xc7, + 0x7d, 0xe0, 0x14, 0x89, 0x33, 0xae, 0xc6, 0x5b, 0xe1, 0x7c, + 0x88, 0x15, 0xaf, 0x32, 0xa1, 0x3c, 0x86, 0x1b, 0xef, 0x72, + 0xc8, 0x55, 0x3d, 0xa0, 0x1a, 0x87, 0x73, 0xee, 0x54, 0xc9, + 0x84, 0x19, 0xa3, 0x3e, 0xca, 0x57, 0xed, 0x70, 0x18, 0x85, + 0x3f, 0xa2, 0x56, 0xcb, 0x71, 0xec, 0xeb, 0x76, 0xcc, 0x51, + 0xa5, 0x38, 0x82, 0x1f, 0x77, 0xea, 0x50, 0xcd, 0x39, 0xa4, + 0x1e, 0x83, 0xce, 0x53, 0xe9, 0x74, 0x80, 0x1d, 0xa7, 0x3a, + 0x52, 0xcf, 0x75, 0xe8, 0x1c, 0x81, 0x3b, 0xa6, 0x00, 0x9e, + 0x21, 0xbf, 0x42, 0xdc, 0x63, 0xfd, 0x84, 0x1a, 0xa5, 0x3b, + 0xc6, 0x58, 0xe7, 0x79, 0x15, 0x8b, 0x34, 0xaa, 0x57, 0xc9, + 0x76, 0xe8, 0x91, 0x0f, 0xb0, 0x2e, 0xd3, 0x4d, 0xf2, 0x6c, + 0x2a, 0xb4, 0x0b, 0x95, 0x68, 0xf6, 0x49, 0xd7, 0xae, 0x30, + 0x8f, 0x11, 0xec, 0x72, 0xcd, 0x53, 0x3f, 0xa1, 0x1e, 0x80, + 0x7d, 0xe3, 0x5c, 0xc2, 0xbb, 0x25, 0x9a, 0x04, 0xf9, 0x67, + 0xd8, 0x46, 0x54, 0xca, 0x75, 0xeb, 0x16, 0x88, 0x37, 0xa9, + 0xd0, 0x4e, 0xf1, 0x6f, 0x92, 0x0c, 0xb3, 0x2d, 0x41, 0xdf, + 0x60, 0xfe, 0x03, 0x9d, 0x22, 0xbc, 0xc5, 0x5b, 0xe4, 0x7a, + 0x87, 0x19, 0xa6, 0x38, 0x7e, 0xe0, 0x5f, 0xc1, 0x3c, 0xa2, + 0x1d, 0x83, 0xfa, 0x64, 0xdb, 0x45, 0xb8, 0x26, 0x99, 0x07, + 0x6b, 0xf5, 0x4a, 0xd4, 0x29, 0xb7, 0x08, 0x96, 0xef, 0x71, + 0xce, 0x50, 0xad, 0x33, 0x8c, 0x12, 0xa8, 0x36, 0x89, 0x17, + 0xea, 0x74, 0xcb, 0x55, 0x2c, 0xb2, 0x0d, 0x93, 0x6e, 0xf0, + 0x4f, 0xd1, 0xbd, 0x23, 0x9c, 0x02, 0xff, 0x61, 0xde, 0x40, + 0x39, 0xa7, 0x18, 0x86, 0x7b, 0xe5, 0x5a, 0xc4, 0x82, 0x1c, + 0xa3, 0x3d, 0xc0, 0x5e, 0xe1, 0x7f, 0x06, 0x98, 0x27, 0xb9, + 0x44, 0xda, 0x65, 0xfb, 0x97, 0x09, 0xb6, 0x28, 0xd5, 0x4b, + 0xf4, 0x6a, 0x13, 0x8d, 0x32, 0xac, 0x51, 0xcf, 0x70, 0xee, + 0xfc, 0x62, 0xdd, 0x43, 0xbe, 0x20, 0x9f, 0x01, 0x78, 0xe6, + 0x59, 0xc7, 0x3a, 0xa4, 0x1b, 0x85, 0xe9, 0x77, 0xc8, 0x56, + 0xab, 0x35, 0x8a, 0x14, 0x6d, 0xf3, 0x4c, 0xd2, 0x2f, 0xb1, + 0x0e, 0x90, 0xd6, 0x48, 0xf7, 0x69, 0x94, 0x0a, 0xb5, 0x2b, + 0x52, 0xcc, 0x73, 0xed, 0x10, 0x8e, 0x31, 0xaf, 0xc3, 0x5d, + 0xe2, 0x7c, 0x81, 0x1f, 0xa0, 0x3e, 0x47, 0xd9, 0x66, 0xf8, + 0x05, 0x9b, 0x24, 0xba, 0x00, 0x9f, 0x23, 0xbc, 0x46, 0xd9, + 0x65, 0xfa, 0x8c, 0x13, 0xaf, 0x30, 0xca, 0x55, 0xe9, 0x76, + 0x05, 0x9a, 0x26, 0xb9, 0x43, 0xdc, 0x60, 0xff, 0x89, 0x16, + 0xaa, 0x35, 0xcf, 0x50, 0xec, 0x73, 0x0a, 0x95, 0x29, 0xb6, + 0x4c, 0xd3, 0x6f, 0xf0, 0x86, 0x19, 0xa5, 0x3a, 0xc0, 0x5f, + 0xe3, 0x7c, 0x0f, 0x90, 0x2c, 0xb3, 0x49, 0xd6, 0x6a, 0xf5, + 0x83, 0x1c, 0xa0, 0x3f, 0xc5, 0x5a, 0xe6, 0x79, 0x14, 0x8b, + 0x37, 0xa8, 0x52, 0xcd, 0x71, 0xee, 0x98, 0x07, 0xbb, 0x24, + 0xde, 0x41, 0xfd, 0x62, 0x11, 0x8e, 0x32, 0xad, 0x57, 0xc8, + 0x74, 0xeb, 0x9d, 0x02, 0xbe, 0x21, 0xdb, 0x44, 0xf8, 0x67, + 0x1e, 0x81, 0x3d, 0xa2, 0x58, 0xc7, 0x7b, 0xe4, 0x92, 0x0d, + 0xb1, 0x2e, 0xd4, 0x4b, 0xf7, 0x68, 0x1b, 0x84, 0x38, 0xa7, + 0x5d, 0xc2, 0x7e, 0xe1, 0x97, 0x08, 0xb4, 0x2b, 0xd1, 0x4e, + 0xf2, 0x6d, 0x28, 0xb7, 0x0b, 0x94, 0x6e, 0xf1, 0x4d, 0xd2, + 0xa4, 0x3b, 0x87, 0x18, 0xe2, 0x7d, 0xc1, 0x5e, 0x2d, 0xb2, + 0x0e, 0x91, 0x6b, 0xf4, 0x48, 0xd7, 0xa1, 0x3e, 0x82, 0x1d, + 0xe7, 0x78, 0xc4, 0x5b, 0x22, 0xbd, 0x01, 0x9e, 0x64, 0xfb, + 0x47, 0xd8, 0xae, 0x31, 0x8d, 0x12, 0xe8, 0x77, 0xcb, 0x54, + 0x27, 0xb8, 0x04, 0x9b, 0x61, 0xfe, 0x42, 0xdd, 0xab, 0x34, + 0x88, 0x17, 0xed, 0x72, 0xce, 0x51, 0x3c, 0xa3, 0x1f, 0x80, + 0x7a, 0xe5, 0x59, 0xc6, 0xb0, 0x2f, 0x93, 0x0c, 0xf6, 0x69, + 0xd5, 0x4a, 0x39, 0xa6, 0x1a, 0x85, 0x7f, 0xe0, 0x5c, 0xc3, + 0xb5, 0x2a, 0x96, 0x09, 0xf3, 0x6c, 0xd0, 0x4f, 0x36, 0xa9, + 0x15, 0x8a, 0x70, 0xef, 0x53, 0xcc, 0xba, 0x25, 0x99, 0x06, + 0xfc, 0x63, 0xdf, 0x40, 0x33, 0xac, 0x10, 0x8f, 0x75, 0xea, + 0x56, 0xc9, 0xbf, 0x20, 0x9c, 0x03, 0xf9, 0x66, 0xda, 0x45, + 0x00, 0xa0, 0x5d, 0xfd, 0xba, 0x1a, 0xe7, 0x47, 0x69, 0xc9, + 0x34, 0x94, 0xd3, 0x73, 0x8e, 0x2e, 0xd2, 0x72, 0x8f, 0x2f, + 0x68, 0xc8, 0x35, 0x95, 0xbb, 0x1b, 0xe6, 0x46, 0x01, 0xa1, + 0x5c, 0xfc, 0xb9, 0x19, 0xe4, 0x44, 0x03, 0xa3, 0x5e, 0xfe, + 0xd0, 0x70, 0x8d, 0x2d, 0x6a, 0xca, 0x37, 0x97, 0x6b, 0xcb, + 0x36, 0x96, 0xd1, 0x71, 0x8c, 0x2c, 0x02, 0xa2, 0x5f, 0xff, + 0xb8, 0x18, 0xe5, 0x45, 0x6f, 0xcf, 0x32, 0x92, 0xd5, 0x75, + 0x88, 0x28, 0x06, 0xa6, 0x5b, 0xfb, 0xbc, 0x1c, 0xe1, 0x41, + 0xbd, 0x1d, 0xe0, 0x40, 0x07, 0xa7, 0x5a, 0xfa, 0xd4, 0x74, + 0x89, 0x29, 0x6e, 0xce, 0x33, 0x93, 0xd6, 0x76, 0x8b, 0x2b, + 0x6c, 0xcc, 0x31, 0x91, 0xbf, 0x1f, 0xe2, 0x42, 0x05, 0xa5, + 0x58, 0xf8, 0x04, 0xa4, 0x59, 0xf9, 0xbe, 0x1e, 0xe3, 0x43, + 0x6d, 0xcd, 0x30, 0x90, 0xd7, 0x77, 0x8a, 0x2a, 0xde, 0x7e, + 0x83, 0x23, 0x64, 0xc4, 0x39, 0x99, 0xb7, 0x17, 0xea, 0x4a, + 0x0d, 0xad, 0x50, 0xf0, 0x0c, 0xac, 0x51, 0xf1, 0xb6, 0x16, + 0xeb, 0x4b, 0x65, 0xc5, 0x38, 0x98, 0xdf, 0x7f, 0x82, 0x22, + 0x67, 0xc7, 0x3a, 0x9a, 0xdd, 0x7d, 0x80, 0x20, 0x0e, 0xae, + 0x53, 0xf3, 0xb4, 0x14, 0xe9, 0x49, 0xb5, 0x15, 0xe8, 0x48, + 0x0f, 0xaf, 0x52, 0xf2, 0xdc, 0x7c, 0x81, 0x21, 0x66, 0xc6, + 0x3b, 0x9b, 0xb1, 0x11, 0xec, 0x4c, 0x0b, 0xab, 0x56, 0xf6, + 0xd8, 0x78, 0x85, 0x25, 0x62, 0xc2, 0x3f, 0x9f, 0x63, 0xc3, + 0x3e, 0x9e, 0xd9, 0x79, 0x84, 0x24, 0x0a, 0xaa, 0x57, 0xf7, + 0xb0, 0x10, 0xed, 0x4d, 0x08, 0xa8, 0x55, 0xf5, 0xb2, 0x12, + 0xef, 0x4f, 0x61, 0xc1, 0x3c, 0x9c, 0xdb, 0x7b, 0x86, 0x26, + 0xda, 0x7a, 0x87, 0x27, 0x60, 0xc0, 0x3d, 0x9d, 0xb3, 0x13, + 0xee, 0x4e, 0x09, 0xa9, 0x54, 0xf4, 0x00, 0xa1, 0x5f, 0xfe, + 0xbe, 0x1f, 0xe1, 0x40, 0x61, 0xc0, 0x3e, 0x9f, 0xdf, 0x7e, + 0x80, 0x21, 0xc2, 0x63, 0x9d, 0x3c, 0x7c, 0xdd, 0x23, 0x82, + 0xa3, 0x02, 0xfc, 0x5d, 0x1d, 0xbc, 0x42, 0xe3, 0x99, 0x38, + 0xc6, 0x67, 0x27, 0x86, 0x78, 0xd9, 0xf8, 0x59, 0xa7, 0x06, + 0x46, 0xe7, 0x19, 0xb8, 0x5b, 0xfa, 0x04, 0xa5, 0xe5, 0x44, + 0xba, 0x1b, 0x3a, 0x9b, 0x65, 0xc4, 0x84, 0x25, 0xdb, 0x7a, + 0x2f, 0x8e, 0x70, 0xd1, 0x91, 0x30, 0xce, 0x6f, 0x4e, 0xef, + 0x11, 0xb0, 0xf0, 0x51, 0xaf, 0x0e, 0xed, 0x4c, 0xb2, 0x13, + 0x53, 0xf2, 0x0c, 0xad, 0x8c, 0x2d, 0xd3, 0x72, 0x32, 0x93, + 0x6d, 0xcc, 0xb6, 0x17, 0xe9, 0x48, 0x08, 0xa9, 0x57, 0xf6, + 0xd7, 0x76, 0x88, 0x29, 0x69, 0xc8, 0x36, 0x97, 0x74, 0xd5, + 0x2b, 0x8a, 0xca, 0x6b, 0x95, 0x34, 0x15, 0xb4, 0x4a, 0xeb, + 0xab, 0x0a, 0xf4, 0x55, 0x5e, 0xff, 0x01, 0xa0, 0xe0, 0x41, + 0xbf, 0x1e, 0x3f, 0x9e, 0x60, 0xc1, 0x81, 0x20, 0xde, 0x7f, + 0x9c, 0x3d, 0xc3, 0x62, 0x22, 0x83, 0x7d, 0xdc, 0xfd, 0x5c, + 0xa2, 0x03, 0x43, 0xe2, 0x1c, 0xbd, 0xc7, 0x66, 0x98, 0x39, + 0x79, 0xd8, 0x26, 0x87, 0xa6, 0x07, 0xf9, 0x58, 0x18, 0xb9, + 0x47, 0xe6, 0x05, 0xa4, 0x5a, 0xfb, 0xbb, 0x1a, 0xe4, 0x45, + 0x64, 0xc5, 0x3b, 0x9a, 0xda, 0x7b, 0x85, 0x24, 0x71, 0xd0, + 0x2e, 0x8f, 0xcf, 0x6e, 0x90, 0x31, 0x10, 0xb1, 0x4f, 0xee, + 0xae, 0x0f, 0xf1, 0x50, 0xb3, 0x12, 0xec, 0x4d, 0x0d, 0xac, + 0x52, 0xf3, 0xd2, 0x73, 0x8d, 0x2c, 0x6c, 0xcd, 0x33, 0x92, + 0xe8, 0x49, 0xb7, 0x16, 0x56, 0xf7, 0x09, 0xa8, 0x89, 0x28, + 0xd6, 0x77, 0x37, 0x96, 0x68, 0xc9, 0x2a, 0x8b, 0x75, 0xd4, + 0x94, 0x35, 0xcb, 0x6a, 0x4b, 0xea, 0x14, 0xb5, 0xf5, 0x54, + 0xaa, 0x0b, 0x00, 0xa2, 0x59, 0xfb, 0xb2, 0x10, 0xeb, 0x49, + 0x79, 0xdb, 0x20, 0x82, 0xcb, 0x69, 0x92, 0x30, 0xf2, 0x50, + 0xab, 0x09, 0x40, 0xe2, 0x19, 0xbb, 0x8b, 0x29, 0xd2, 0x70, + 0x39, 0x9b, 0x60, 0xc2, 0xf9, 0x5b, 0xa0, 0x02, 0x4b, 0xe9, + 0x12, 0xb0, 0x80, 0x22, 0xd9, 0x7b, 0x32, 0x90, 0x6b, 0xc9, + 0x0b, 0xa9, 0x52, 0xf0, 0xb9, 0x1b, 0xe0, 0x42, 0x72, 0xd0, + 0x2b, 0x89, 0xc0, 0x62, 0x99, 0x3b, 0xef, 0x4d, 0xb6, 0x14, + 0x5d, 0xff, 0x04, 0xa6, 0x96, 0x34, 0xcf, 0x6d, 0x24, 0x86, + 0x7d, 0xdf, 0x1d, 0xbf, 0x44, 0xe6, 0xaf, 0x0d, 0xf6, 0x54, + 0x64, 0xc6, 0x3d, 0x9f, 0xd6, 0x74, 0x8f, 0x2d, 0x16, 0xb4, + 0x4f, 0xed, 0xa4, 0x06, 0xfd, 0x5f, 0x6f, 0xcd, 0x36, 0x94, + 0xdd, 0x7f, 0x84, 0x26, 0xe4, 0x46, 0xbd, 0x1f, 0x56, 0xf4, + 0x0f, 0xad, 0x9d, 0x3f, 0xc4, 0x66, 0x2f, 0x8d, 0x76, 0xd4, + 0xc3, 0x61, 0x9a, 0x38, 0x71, 0xd3, 0x28, 0x8a, 0xba, 0x18, + 0xe3, 0x41, 0x08, 0xaa, 0x51, 0xf3, 0x31, 0x93, 0x68, 0xca, + 0x83, 0x21, 0xda, 0x78, 0x48, 0xea, 0x11, 0xb3, 0xfa, 0x58, + 0xa3, 0x01, 0x3a, 0x98, 0x63, 0xc1, 0x88, 0x2a, 0xd1, 0x73, + 0x43, 0xe1, 0x1a, 0xb8, 0xf1, 0x53, 0xa8, 0x0a, 0xc8, 0x6a, + 0x91, 0x33, 0x7a, 0xd8, 0x23, 0x81, 0xb1, 0x13, 0xe8, 0x4a, + 0x03, 0xa1, 0x5a, 0xf8, 0x2c, 0x8e, 0x75, 0xd7, 0x9e, 0x3c, + 0xc7, 0x65, 0x55, 0xf7, 0x0c, 0xae, 0xe7, 0x45, 0xbe, 0x1c, + 0xde, 0x7c, 0x87, 0x25, 0x6c, 0xce, 0x35, 0x97, 0xa7, 0x05, + 0xfe, 0x5c, 0x15, 0xb7, 0x4c, 0xee, 0xd5, 0x77, 0x8c, 0x2e, + 0x67, 0xc5, 0x3e, 0x9c, 0xac, 0x0e, 0xf5, 0x57, 0x1e, 0xbc, + 0x47, 0xe5, 0x27, 0x85, 0x7e, 0xdc, 0x95, 0x37, 0xcc, 0x6e, + 0x5e, 0xfc, 0x07, 0xa5, 0xec, 0x4e, 0xb5, 0x17, 0x00, 0xa3, + 0x5b, 0xf8, 0xb6, 0x15, 0xed, 0x4e, 0x71, 0xd2, 0x2a, 0x89, + 0xc7, 0x64, 0x9c, 0x3f, 0xe2, 0x41, 0xb9, 0x1a, 0x54, 0xf7, + 0x0f, 0xac, 0x93, 0x30, 0xc8, 0x6b, 0x25, 0x86, 0x7e, 0xdd, + 0xd9, 0x7a, 0x82, 0x21, 0x6f, 0xcc, 0x34, 0x97, 0xa8, 0x0b, + 0xf3, 0x50, 0x1e, 0xbd, 0x45, 0xe6, 0x3b, 0x98, 0x60, 0xc3, + 0x8d, 0x2e, 0xd6, 0x75, 0x4a, 0xe9, 0x11, 0xb2, 0xfc, 0x5f, + 0xa7, 0x04, 0xaf, 0x0c, 0xf4, 0x57, 0x19, 0xba, 0x42, 0xe1, + 0xde, 0x7d, 0x85, 0x26, 0x68, 0xcb, 0x33, 0x90, 0x4d, 0xee, + 0x16, 0xb5, 0xfb, 0x58, 0xa0, 0x03, 0x3c, 0x9f, 0x67, 0xc4, + 0x8a, 0x29, 0xd1, 0x72, 0x76, 0xd5, 0x2d, 0x8e, 0xc0, 0x63, + 0x9b, 0x38, 0x07, 0xa4, 0x5c, 0xff, 0xb1, 0x12, 0xea, 0x49, + 0x94, 0x37, 0xcf, 0x6c, 0x22, 0x81, 0x79, 0xda, 0xe5, 0x46, + 0xbe, 0x1d, 0x53, 0xf0, 0x08, 0xab, 0x43, 0xe0, 0x18, 0xbb, + 0xf5, 0x56, 0xae, 0x0d, 0x32, 0x91, 0x69, 0xca, 0x84, 0x27, + 0xdf, 0x7c, 0xa1, 0x02, 0xfa, 0x59, 0x17, 0xb4, 0x4c, 0xef, + 0xd0, 0x73, 0x8b, 0x28, 0x66, 0xc5, 0x3d, 0x9e, 0x9a, 0x39, + 0xc1, 0x62, 0x2c, 0x8f, 0x77, 0xd4, 0xeb, 0x48, 0xb0, 0x13, + 0x5d, 0xfe, 0x06, 0xa5, 0x78, 0xdb, 0x23, 0x80, 0xce, 0x6d, + 0x95, 0x36, 0x09, 0xaa, 0x52, 0xf1, 0xbf, 0x1c, 0xe4, 0x47, + 0xec, 0x4f, 0xb7, 0x14, 0x5a, 0xf9, 0x01, 0xa2, 0x9d, 0x3e, + 0xc6, 0x65, 0x2b, 0x88, 0x70, 0xd3, 0x0e, 0xad, 0x55, 0xf6, + 0xb8, 0x1b, 0xe3, 0x40, 0x7f, 0xdc, 0x24, 0x87, 0xc9, 0x6a, + 0x92, 0x31, 0x35, 0x96, 0x6e, 0xcd, 0x83, 0x20, 0xd8, 0x7b, + 0x44, 0xe7, 0x1f, 0xbc, 0xf2, 0x51, 0xa9, 0x0a, 0xd7, 0x74, + 0x8c, 0x2f, 0x61, 0xc2, 0x3a, 0x99, 0xa6, 0x05, 0xfd, 0x5e, + 0x10, 0xb3, 0x4b, 0xe8, 0x00, 0xa4, 0x55, 0xf1, 0xaa, 0x0e, + 0xff, 0x5b, 0x49, 0xed, 0x1c, 0xb8, 0xe3, 0x47, 0xb6, 0x12, + 0x92, 0x36, 0xc7, 0x63, 0x38, 0x9c, 0x6d, 0xc9, 0xdb, 0x7f, + 0x8e, 0x2a, 0x71, 0xd5, 0x24, 0x80, 0x39, 0x9d, 0x6c, 0xc8, + 0x93, 0x37, 0xc6, 0x62, 0x70, 0xd4, 0x25, 0x81, 0xda, 0x7e, + 0x8f, 0x2b, 0xab, 0x0f, 0xfe, 0x5a, 0x01, 0xa5, 0x54, 0xf0, + 0xe2, 0x46, 0xb7, 0x13, 0x48, 0xec, 0x1d, 0xb9, 0x72, 0xd6, + 0x27, 0x83, 0xd8, 0x7c, 0x8d, 0x29, 0x3b, 0x9f, 0x6e, 0xca, + 0x91, 0x35, 0xc4, 0x60, 0xe0, 0x44, 0xb5, 0x11, 0x4a, 0xee, + 0x1f, 0xbb, 0xa9, 0x0d, 0xfc, 0x58, 0x03, 0xa7, 0x56, 0xf2, + 0x4b, 0xef, 0x1e, 0xba, 0xe1, 0x45, 0xb4, 0x10, 0x02, 0xa6, + 0x57, 0xf3, 0xa8, 0x0c, 0xfd, 0x59, 0xd9, 0x7d, 0x8c, 0x28, + 0x73, 0xd7, 0x26, 0x82, 0x90, 0x34, 0xc5, 0x61, 0x3a, 0x9e, + 0x6f, 0xcb, 0xe4, 0x40, 0xb1, 0x15, 0x4e, 0xea, 0x1b, 0xbf, + 0xad, 0x09, 0xf8, 0x5c, 0x07, 0xa3, 0x52, 0xf6, 0x76, 0xd2, + 0x23, 0x87, 0xdc, 0x78, 0x89, 0x2d, 0x3f, 0x9b, 0x6a, 0xce, + 0x95, 0x31, 0xc0, 0x64, 0xdd, 0x79, 0x88, 0x2c, 0x77, 0xd3, + 0x22, 0x86, 0x94, 0x30, 0xc1, 0x65, 0x3e, 0x9a, 0x6b, 0xcf, + 0x4f, 0xeb, 0x1a, 0xbe, 0xe5, 0x41, 0xb0, 0x14, 0x06, 0xa2, + 0x53, 0xf7, 0xac, 0x08, 0xf9, 0x5d, 0x96, 0x32, 0xc3, 0x67, + 0x3c, 0x98, 0x69, 0xcd, 0xdf, 0x7b, 0x8a, 0x2e, 0x75, 0xd1, + 0x20, 0x84, 0x04, 0xa0, 0x51, 0xf5, 0xae, 0x0a, 0xfb, 0x5f, + 0x4d, 0xe9, 0x18, 0xbc, 0xe7, 0x43, 0xb2, 0x16, 0xaf, 0x0b, + 0xfa, 0x5e, 0x05, 0xa1, 0x50, 0xf4, 0xe6, 0x42, 0xb3, 0x17, + 0x4c, 0xe8, 0x19, 0xbd, 0x3d, 0x99, 0x68, 0xcc, 0x97, 0x33, + 0xc2, 0x66, 0x74, 0xd0, 0x21, 0x85, 0xde, 0x7a, 0x8b, 0x2f, + 0x00, 0xa5, 0x57, 0xf2, 0xae, 0x0b, 0xf9, 0x5c, 0x41, 0xe4, + 0x16, 0xb3, 0xef, 0x4a, 0xb8, 0x1d, 0x82, 0x27, 0xd5, 0x70, + 0x2c, 0x89, 0x7b, 0xde, 0xc3, 0x66, 0x94, 0x31, 0x6d, 0xc8, + 0x3a, 0x9f, 0x19, 0xbc, 0x4e, 0xeb, 0xb7, 0x12, 0xe0, 0x45, + 0x58, 0xfd, 0x0f, 0xaa, 0xf6, 0x53, 0xa1, 0x04, 0x9b, 0x3e, + 0xcc, 0x69, 0x35, 0x90, 0x62, 0xc7, 0xda, 0x7f, 0x8d, 0x28, + 0x74, 0xd1, 0x23, 0x86, 0x32, 0x97, 0x65, 0xc0, 0x9c, 0x39, + 0xcb, 0x6e, 0x73, 0xd6, 0x24, 0x81, 0xdd, 0x78, 0x8a, 0x2f, + 0xb0, 0x15, 0xe7, 0x42, 0x1e, 0xbb, 0x49, 0xec, 0xf1, 0x54, + 0xa6, 0x03, 0x5f, 0xfa, 0x08, 0xad, 0x2b, 0x8e, 0x7c, 0xd9, + 0x85, 0x20, 0xd2, 0x77, 0x6a, 0xcf, 0x3d, 0x98, 0xc4, 0x61, + 0x93, 0x36, 0xa9, 0x0c, 0xfe, 0x5b, 0x07, 0xa2, 0x50, 0xf5, + 0xe8, 0x4d, 0xbf, 0x1a, 0x46, 0xe3, 0x11, 0xb4, 0x64, 0xc1, + 0x33, 0x96, 0xca, 0x6f, 0x9d, 0x38, 0x25, 0x80, 0x72, 0xd7, + 0x8b, 0x2e, 0xdc, 0x79, 0xe6, 0x43, 0xb1, 0x14, 0x48, 0xed, + 0x1f, 0xba, 0xa7, 0x02, 0xf0, 0x55, 0x09, 0xac, 0x5e, 0xfb, + 0x7d, 0xd8, 0x2a, 0x8f, 0xd3, 0x76, 0x84, 0x21, 0x3c, 0x99, + 0x6b, 0xce, 0x92, 0x37, 0xc5, 0x60, 0xff, 0x5a, 0xa8, 0x0d, + 0x51, 0xf4, 0x06, 0xa3, 0xbe, 0x1b, 0xe9, 0x4c, 0x10, 0xb5, + 0x47, 0xe2, 0x56, 0xf3, 0x01, 0xa4, 0xf8, 0x5d, 0xaf, 0x0a, + 0x17, 0xb2, 0x40, 0xe5, 0xb9, 0x1c, 0xee, 0x4b, 0xd4, 0x71, + 0x83, 0x26, 0x7a, 0xdf, 0x2d, 0x88, 0x95, 0x30, 0xc2, 0x67, + 0x3b, 0x9e, 0x6c, 0xc9, 0x4f, 0xea, 0x18, 0xbd, 0xe1, 0x44, + 0xb6, 0x13, 0x0e, 0xab, 0x59, 0xfc, 0xa0, 0x05, 0xf7, 0x52, + 0xcd, 0x68, 0x9a, 0x3f, 0x63, 0xc6, 0x34, 0x91, 0x8c, 0x29, + 0xdb, 0x7e, 0x22, 0x87, 0x75, 0xd0, 0x00, 0xa6, 0x51, 0xf7, + 0xa2, 0x04, 0xf3, 0x55, 0x59, 0xff, 0x08, 0xae, 0xfb, 0x5d, + 0xaa, 0x0c, 0xb2, 0x14, 0xe3, 0x45, 0x10, 0xb6, 0x41, 0xe7, + 0xeb, 0x4d, 0xba, 0x1c, 0x49, 0xef, 0x18, 0xbe, 0x79, 0xdf, + 0x28, 0x8e, 0xdb, 0x7d, 0x8a, 0x2c, 0x20, 0x86, 0x71, 0xd7, + 0x82, 0x24, 0xd3, 0x75, 0xcb, 0x6d, 0x9a, 0x3c, 0x69, 0xcf, + 0x38, 0x9e, 0x92, 0x34, 0xc3, 0x65, 0x30, 0x96, 0x61, 0xc7, + 0xf2, 0x54, 0xa3, 0x05, 0x50, 0xf6, 0x01, 0xa7, 0xab, 0x0d, + 0xfa, 0x5c, 0x09, 0xaf, 0x58, 0xfe, 0x40, 0xe6, 0x11, 0xb7, + 0xe2, 0x44, 0xb3, 0x15, 0x19, 0xbf, 0x48, 0xee, 0xbb, 0x1d, + 0xea, 0x4c, 0x8b, 0x2d, 0xda, 0x7c, 0x29, 0x8f, 0x78, 0xde, + 0xd2, 0x74, 0x83, 0x25, 0x70, 0xd6, 0x21, 0x87, 0x39, 0x9f, + 0x68, 0xce, 0x9b, 0x3d, 0xca, 0x6c, 0x60, 0xc6, 0x31, 0x97, + 0xc2, 0x64, 0x93, 0x35, 0xf9, 0x5f, 0xa8, 0x0e, 0x5b, 0xfd, + 0x0a, 0xac, 0xa0, 0x06, 0xf1, 0x57, 0x02, 0xa4, 0x53, 0xf5, + 0x4b, 0xed, 0x1a, 0xbc, 0xe9, 0x4f, 0xb8, 0x1e, 0x12, 0xb4, + 0x43, 0xe5, 0xb0, 0x16, 0xe1, 0x47, 0x80, 0x26, 0xd1, 0x77, + 0x22, 0x84, 0x73, 0xd5, 0xd9, 0x7f, 0x88, 0x2e, 0x7b, 0xdd, + 0x2a, 0x8c, 0x32, 0x94, 0x63, 0xc5, 0x90, 0x36, 0xc1, 0x67, + 0x6b, 0xcd, 0x3a, 0x9c, 0xc9, 0x6f, 0x98, 0x3e, 0x0b, 0xad, + 0x5a, 0xfc, 0xa9, 0x0f, 0xf8, 0x5e, 0x52, 0xf4, 0x03, 0xa5, + 0xf0, 0x56, 0xa1, 0x07, 0xb9, 0x1f, 0xe8, 0x4e, 0x1b, 0xbd, + 0x4a, 0xec, 0xe0, 0x46, 0xb1, 0x17, 0x42, 0xe4, 0x13, 0xb5, + 0x72, 0xd4, 0x23, 0x85, 0xd0, 0x76, 0x81, 0x27, 0x2b, 0x8d, + 0x7a, 0xdc, 0x89, 0x2f, 0xd8, 0x7e, 0xc0, 0x66, 0x91, 0x37, + 0x62, 0xc4, 0x33, 0x95, 0x99, 0x3f, 0xc8, 0x6e, 0x3b, 0x9d, + 0x6a, 0xcc, 0x00, 0xa7, 0x53, 0xf4, 0xa6, 0x01, 0xf5, 0x52, + 0x51, 0xf6, 0x02, 0xa5, 0xf7, 0x50, 0xa4, 0x03, 0xa2, 0x05, + 0xf1, 0x56, 0x04, 0xa3, 0x57, 0xf0, 0xf3, 0x54, 0xa0, 0x07, + 0x55, 0xf2, 0x06, 0xa1, 0x59, 0xfe, 0x0a, 0xad, 0xff, 0x58, + 0xac, 0x0b, 0x08, 0xaf, 0x5b, 0xfc, 0xae, 0x09, 0xfd, 0x5a, + 0xfb, 0x5c, 0xa8, 0x0f, 0x5d, 0xfa, 0x0e, 0xa9, 0xaa, 0x0d, + 0xf9, 0x5e, 0x0c, 0xab, 0x5f, 0xf8, 0xb2, 0x15, 0xe1, 0x46, + 0x14, 0xb3, 0x47, 0xe0, 0xe3, 0x44, 0xb0, 0x17, 0x45, 0xe2, + 0x16, 0xb1, 0x10, 0xb7, 0x43, 0xe4, 0xb6, 0x11, 0xe5, 0x42, + 0x41, 0xe6, 0x12, 0xb5, 0xe7, 0x40, 0xb4, 0x13, 0xeb, 0x4c, + 0xb8, 0x1f, 0x4d, 0xea, 0x1e, 0xb9, 0xba, 0x1d, 0xe9, 0x4e, + 0x1c, 0xbb, 0x4f, 0xe8, 0x49, 0xee, 0x1a, 0xbd, 0xef, 0x48, + 0xbc, 0x1b, 0x18, 0xbf, 0x4b, 0xec, 0xbe, 0x19, 0xed, 0x4a, + 0x79, 0xde, 0x2a, 0x8d, 0xdf, 0x78, 0x8c, 0x2b, 0x28, 0x8f, + 0x7b, 0xdc, 0x8e, 0x29, 0xdd, 0x7a, 0xdb, 0x7c, 0x88, 0x2f, + 0x7d, 0xda, 0x2e, 0x89, 0x8a, 0x2d, 0xd9, 0x7e, 0x2c, 0x8b, + 0x7f, 0xd8, 0x20, 0x87, 0x73, 0xd4, 0x86, 0x21, 0xd5, 0x72, + 0x71, 0xd6, 0x22, 0x85, 0xd7, 0x70, 0x84, 0x23, 0x82, 0x25, + 0xd1, 0x76, 0x24, 0x83, 0x77, 0xd0, 0xd3, 0x74, 0x80, 0x27, + 0x75, 0xd2, 0x26, 0x81, 0xcb, 0x6c, 0x98, 0x3f, 0x6d, 0xca, + 0x3e, 0x99, 0x9a, 0x3d, 0xc9, 0x6e, 0x3c, 0x9b, 0x6f, 0xc8, + 0x69, 0xce, 0x3a, 0x9d, 0xcf, 0x68, 0x9c, 0x3b, 0x38, 0x9f, + 0x6b, 0xcc, 0x9e, 0x39, 0xcd, 0x6a, 0x92, 0x35, 0xc1, 0x66, + 0x34, 0x93, 0x67, 0xc0, 0xc3, 0x64, 0x90, 0x37, 0x65, 0xc2, + 0x36, 0x91, 0x30, 0x97, 0x63, 0xc4, 0x96, 0x31, 0xc5, 0x62, + 0x61, 0xc6, 0x32, 0x95, 0xc7, 0x60, 0x94, 0x33, 0x00, 0xa8, + 0x4d, 0xe5, 0x9a, 0x32, 0xd7, 0x7f, 0x29, 0x81, 0x64, 0xcc, + 0xb3, 0x1b, 0xfe, 0x56, 0x52, 0xfa, 0x1f, 0xb7, 0xc8, 0x60, + 0x85, 0x2d, 0x7b, 0xd3, 0x36, 0x9e, 0xe1, 0x49, 0xac, 0x04, + 0xa4, 0x0c, 0xe9, 0x41, 0x3e, 0x96, 0x73, 0xdb, 0x8d, 0x25, + 0xc0, 0x68, 0x17, 0xbf, 0x5a, 0xf2, 0xf6, 0x5e, 0xbb, 0x13, + 0x6c, 0xc4, 0x21, 0x89, 0xdf, 0x77, 0x92, 0x3a, 0x45, 0xed, + 0x08, 0xa0, 0x55, 0xfd, 0x18, 0xb0, 0xcf, 0x67, 0x82, 0x2a, + 0x7c, 0xd4, 0x31, 0x99, 0xe6, 0x4e, 0xab, 0x03, 0x07, 0xaf, + 0x4a, 0xe2, 0x9d, 0x35, 0xd0, 0x78, 0x2e, 0x86, 0x63, 0xcb, + 0xb4, 0x1c, 0xf9, 0x51, 0xf1, 0x59, 0xbc, 0x14, 0x6b, 0xc3, + 0x26, 0x8e, 0xd8, 0x70, 0x95, 0x3d, 0x42, 0xea, 0x0f, 0xa7, + 0xa3, 0x0b, 0xee, 0x46, 0x39, 0x91, 0x74, 0xdc, 0x8a, 0x22, + 0xc7, 0x6f, 0x10, 0xb8, 0x5d, 0xf5, 0xaa, 0x02, 0xe7, 0x4f, + 0x30, 0x98, 0x7d, 0xd5, 0x83, 0x2b, 0xce, 0x66, 0x19, 0xb1, + 0x54, 0xfc, 0xf8, 0x50, 0xb5, 0x1d, 0x62, 0xca, 0x2f, 0x87, + 0xd1, 0x79, 0x9c, 0x34, 0x4b, 0xe3, 0x06, 0xae, 0x0e, 0xa6, + 0x43, 0xeb, 0x94, 0x3c, 0xd9, 0x71, 0x27, 0x8f, 0x6a, 0xc2, + 0xbd, 0x15, 0xf0, 0x58, 0x5c, 0xf4, 0x11, 0xb9, 0xc6, 0x6e, + 0x8b, 0x23, 0x75, 0xdd, 0x38, 0x90, 0xef, 0x47, 0xa2, 0x0a, + 0xff, 0x57, 0xb2, 0x1a, 0x65, 0xcd, 0x28, 0x80, 0xd6, 0x7e, + 0x9b, 0x33, 0x4c, 0xe4, 0x01, 0xa9, 0xad, 0x05, 0xe0, 0x48, + 0x37, 0x9f, 0x7a, 0xd2, 0x84, 0x2c, 0xc9, 0x61, 0x1e, 0xb6, + 0x53, 0xfb, 0x5b, 0xf3, 0x16, 0xbe, 0xc1, 0x69, 0x8c, 0x24, + 0x72, 0xda, 0x3f, 0x97, 0xe8, 0x40, 0xa5, 0x0d, 0x09, 0xa1, + 0x44, 0xec, 0x93, 0x3b, 0xde, 0x76, 0x20, 0x88, 0x6d, 0xc5, + 0xba, 0x12, 0xf7, 0x5f, 0x00, 0xa9, 0x4f, 0xe6, 0x9e, 0x37, + 0xd1, 0x78, 0x21, 0x88, 0x6e, 0xc7, 0xbf, 0x16, 0xf0, 0x59, + 0x42, 0xeb, 0x0d, 0xa4, 0xdc, 0x75, 0x93, 0x3a, 0x63, 0xca, + 0x2c, 0x85, 0xfd, 0x54, 0xb2, 0x1b, 0x84, 0x2d, 0xcb, 0x62, + 0x1a, 0xb3, 0x55, 0xfc, 0xa5, 0x0c, 0xea, 0x43, 0x3b, 0x92, + 0x74, 0xdd, 0xc6, 0x6f, 0x89, 0x20, 0x58, 0xf1, 0x17, 0xbe, + 0xe7, 0x4e, 0xa8, 0x01, 0x79, 0xd0, 0x36, 0x9f, 0x15, 0xbc, + 0x5a, 0xf3, 0x8b, 0x22, 0xc4, 0x6d, 0x34, 0x9d, 0x7b, 0xd2, + 0xaa, 0x03, 0xe5, 0x4c, 0x57, 0xfe, 0x18, 0xb1, 0xc9, 0x60, + 0x86, 0x2f, 0x76, 0xdf, 0x39, 0x90, 0xe8, 0x41, 0xa7, 0x0e, + 0x91, 0x38, 0xde, 0x77, 0x0f, 0xa6, 0x40, 0xe9, 0xb0, 0x19, + 0xff, 0x56, 0x2e, 0x87, 0x61, 0xc8, 0xd3, 0x7a, 0x9c, 0x35, + 0x4d, 0xe4, 0x02, 0xab, 0xf2, 0x5b, 0xbd, 0x14, 0x6c, 0xc5, + 0x23, 0x8a, 0x2a, 0x83, 0x65, 0xcc, 0xb4, 0x1d, 0xfb, 0x52, + 0x0b, 0xa2, 0x44, 0xed, 0x95, 0x3c, 0xda, 0x73, 0x68, 0xc1, + 0x27, 0x8e, 0xf6, 0x5f, 0xb9, 0x10, 0x49, 0xe0, 0x06, 0xaf, + 0xd7, 0x7e, 0x98, 0x31, 0xae, 0x07, 0xe1, 0x48, 0x30, 0x99, + 0x7f, 0xd6, 0x8f, 0x26, 0xc0, 0x69, 0x11, 0xb8, 0x5e, 0xf7, + 0xec, 0x45, 0xa3, 0x0a, 0x72, 0xdb, 0x3d, 0x94, 0xcd, 0x64, + 0x82, 0x2b, 0x53, 0xfa, 0x1c, 0xb5, 0x3f, 0x96, 0x70, 0xd9, + 0xa1, 0x08, 0xee, 0x47, 0x1e, 0xb7, 0x51, 0xf8, 0x80, 0x29, + 0xcf, 0x66, 0x7d, 0xd4, 0x32, 0x9b, 0xe3, 0x4a, 0xac, 0x05, + 0x5c, 0xf5, 0x13, 0xba, 0xc2, 0x6b, 0x8d, 0x24, 0xbb, 0x12, + 0xf4, 0x5d, 0x25, 0x8c, 0x6a, 0xc3, 0x9a, 0x33, 0xd5, 0x7c, + 0x04, 0xad, 0x4b, 0xe2, 0xf9, 0x50, 0xb6, 0x1f, 0x67, 0xce, + 0x28, 0x81, 0xd8, 0x71, 0x97, 0x3e, 0x46, 0xef, 0x09, 0xa0, + 0x00, 0xaa, 0x49, 0xe3, 0x92, 0x38, 0xdb, 0x71, 0x39, 0x93, + 0x70, 0xda, 0xab, 0x01, 0xe2, 0x48, 0x72, 0xd8, 0x3b, 0x91, + 0xe0, 0x4a, 0xa9, 0x03, 0x4b, 0xe1, 0x02, 0xa8, 0xd9, 0x73, + 0x90, 0x3a, 0xe4, 0x4e, 0xad, 0x07, 0x76, 0xdc, 0x3f, 0x95, + 0xdd, 0x77, 0x94, 0x3e, 0x4f, 0xe5, 0x06, 0xac, 0x96, 0x3c, + 0xdf, 0x75, 0x04, 0xae, 0x4d, 0xe7, 0xaf, 0x05, 0xe6, 0x4c, + 0x3d, 0x97, 0x74, 0xde, 0xd5, 0x7f, 0x9c, 0x36, 0x47, 0xed, + 0x0e, 0xa4, 0xec, 0x46, 0xa5, 0x0f, 0x7e, 0xd4, 0x37, 0x9d, + 0xa7, 0x0d, 0xee, 0x44, 0x35, 0x9f, 0x7c, 0xd6, 0x9e, 0x34, + 0xd7, 0x7d, 0x0c, 0xa6, 0x45, 0xef, 0x31, 0x9b, 0x78, 0xd2, + 0xa3, 0x09, 0xea, 0x40, 0x08, 0xa2, 0x41, 0xeb, 0x9a, 0x30, + 0xd3, 0x79, 0x43, 0xe9, 0x0a, 0xa0, 0xd1, 0x7b, 0x98, 0x32, + 0x7a, 0xd0, 0x33, 0x99, 0xe8, 0x42, 0xa1, 0x0b, 0xb7, 0x1d, + 0xfe, 0x54, 0x25, 0x8f, 0x6c, 0xc6, 0x8e, 0x24, 0xc7, 0x6d, + 0x1c, 0xb6, 0x55, 0xff, 0xc5, 0x6f, 0x8c, 0x26, 0x57, 0xfd, + 0x1e, 0xb4, 0xfc, 0x56, 0xb5, 0x1f, 0x6e, 0xc4, 0x27, 0x8d, + 0x53, 0xf9, 0x1a, 0xb0, 0xc1, 0x6b, 0x88, 0x22, 0x6a, 0xc0, + 0x23, 0x89, 0xf8, 0x52, 0xb1, 0x1b, 0x21, 0x8b, 0x68, 0xc2, + 0xb3, 0x19, 0xfa, 0x50, 0x18, 0xb2, 0x51, 0xfb, 0x8a, 0x20, + 0xc3, 0x69, 0x62, 0xc8, 0x2b, 0x81, 0xf0, 0x5a, 0xb9, 0x13, + 0x5b, 0xf1, 0x12, 0xb8, 0xc9, 0x63, 0x80, 0x2a, 0x10, 0xba, + 0x59, 0xf3, 0x82, 0x28, 0xcb, 0x61, 0x29, 0x83, 0x60, 0xca, + 0xbb, 0x11, 0xf2, 0x58, 0x86, 0x2c, 0xcf, 0x65, 0x14, 0xbe, + 0x5d, 0xf7, 0xbf, 0x15, 0xf6, 0x5c, 0x2d, 0x87, 0x64, 0xce, + 0xf4, 0x5e, 0xbd, 0x17, 0x66, 0xcc, 0x2f, 0x85, 0xcd, 0x67, + 0x84, 0x2e, 0x5f, 0xf5, 0x16, 0xbc, 0x00, 0xab, 0x4b, 0xe0, + 0x96, 0x3d, 0xdd, 0x76, 0x31, 0x9a, 0x7a, 0xd1, 0xa7, 0x0c, + 0xec, 0x47, 0x62, 0xc9, 0x29, 0x82, 0xf4, 0x5f, 0xbf, 0x14, + 0x53, 0xf8, 0x18, 0xb3, 0xc5, 0x6e, 0x8e, 0x25, 0xc4, 0x6f, + 0x8f, 0x24, 0x52, 0xf9, 0x19, 0xb2, 0xf5, 0x5e, 0xbe, 0x15, + 0x63, 0xc8, 0x28, 0x83, 0xa6, 0x0d, 0xed, 0x46, 0x30, 0x9b, + 0x7b, 0xd0, 0x97, 0x3c, 0xdc, 0x77, 0x01, 0xaa, 0x4a, 0xe1, + 0x95, 0x3e, 0xde, 0x75, 0x03, 0xa8, 0x48, 0xe3, 0xa4, 0x0f, + 0xef, 0x44, 0x32, 0x99, 0x79, 0xd2, 0xf7, 0x5c, 0xbc, 0x17, + 0x61, 0xca, 0x2a, 0x81, 0xc6, 0x6d, 0x8d, 0x26, 0x50, 0xfb, + 0x1b, 0xb0, 0x51, 0xfa, 0x1a, 0xb1, 0xc7, 0x6c, 0x8c, 0x27, + 0x60, 0xcb, 0x2b, 0x80, 0xf6, 0x5d, 0xbd, 0x16, 0x33, 0x98, + 0x78, 0xd3, 0xa5, 0x0e, 0xee, 0x45, 0x02, 0xa9, 0x49, 0xe2, + 0x94, 0x3f, 0xdf, 0x74, 0x37, 0x9c, 0x7c, 0xd7, 0xa1, 0x0a, + 0xea, 0x41, 0x06, 0xad, 0x4d, 0xe6, 0x90, 0x3b, 0xdb, 0x70, + 0x55, 0xfe, 0x1e, 0xb5, 0xc3, 0x68, 0x88, 0x23, 0x64, 0xcf, + 0x2f, 0x84, 0xf2, 0x59, 0xb9, 0x12, 0xf3, 0x58, 0xb8, 0x13, + 0x65, 0xce, 0x2e, 0x85, 0xc2, 0x69, 0x89, 0x22, 0x54, 0xff, + 0x1f, 0xb4, 0x91, 0x3a, 0xda, 0x71, 0x07, 0xac, 0x4c, 0xe7, + 0xa0, 0x0b, 0xeb, 0x40, 0x36, 0x9d, 0x7d, 0xd6, 0xa2, 0x09, + 0xe9, 0x42, 0x34, 0x9f, 0x7f, 0xd4, 0x93, 0x38, 0xd8, 0x73, + 0x05, 0xae, 0x4e, 0xe5, 0xc0, 0x6b, 0x8b, 0x20, 0x56, 0xfd, + 0x1d, 0xb6, 0xf1, 0x5a, 0xba, 0x11, 0x67, 0xcc, 0x2c, 0x87, + 0x66, 0xcd, 0x2d, 0x86, 0xf0, 0x5b, 0xbb, 0x10, 0x57, 0xfc, + 0x1c, 0xb7, 0xc1, 0x6a, 0x8a, 0x21, 0x04, 0xaf, 0x4f, 0xe4, + 0x92, 0x39, 0xd9, 0x72, 0x35, 0x9e, 0x7e, 0xd5, 0xa3, 0x08, + 0xe8, 0x43, 0x00, 0xac, 0x45, 0xe9, 0x8a, 0x26, 0xcf, 0x63, + 0x09, 0xa5, 0x4c, 0xe0, 0x83, 0x2f, 0xc6, 0x6a, 0x12, 0xbe, + 0x57, 0xfb, 0x98, 0x34, 0xdd, 0x71, 0x1b, 0xb7, 0x5e, 0xf2, + 0x91, 0x3d, 0xd4, 0x78, 0x24, 0x88, 0x61, 0xcd, 0xae, 0x02, + 0xeb, 0x47, 0x2d, 0x81, 0x68, 0xc4, 0xa7, 0x0b, 0xe2, 0x4e, + 0x36, 0x9a, 0x73, 0xdf, 0xbc, 0x10, 0xf9, 0x55, 0x3f, 0x93, + 0x7a, 0xd6, 0xb5, 0x19, 0xf0, 0x5c, 0x48, 0xe4, 0x0d, 0xa1, + 0xc2, 0x6e, 0x87, 0x2b, 0x41, 0xed, 0x04, 0xa8, 0xcb, 0x67, + 0x8e, 0x22, 0x5a, 0xf6, 0x1f, 0xb3, 0xd0, 0x7c, 0x95, 0x39, + 0x53, 0xff, 0x16, 0xba, 0xd9, 0x75, 0x9c, 0x30, 0x6c, 0xc0, + 0x29, 0x85, 0xe6, 0x4a, 0xa3, 0x0f, 0x65, 0xc9, 0x20, 0x8c, + 0xef, 0x43, 0xaa, 0x06, 0x7e, 0xd2, 0x3b, 0x97, 0xf4, 0x58, + 0xb1, 0x1d, 0x77, 0xdb, 0x32, 0x9e, 0xfd, 0x51, 0xb8, 0x14, + 0x90, 0x3c, 0xd5, 0x79, 0x1a, 0xb6, 0x5f, 0xf3, 0x99, 0x35, + 0xdc, 0x70, 0x13, 0xbf, 0x56, 0xfa, 0x82, 0x2e, 0xc7, 0x6b, + 0x08, 0xa4, 0x4d, 0xe1, 0x8b, 0x27, 0xce, 0x62, 0x01, 0xad, + 0x44, 0xe8, 0xb4, 0x18, 0xf1, 0x5d, 0x3e, 0x92, 0x7b, 0xd7, + 0xbd, 0x11, 0xf8, 0x54, 0x37, 0x9b, 0x72, 0xde, 0xa6, 0x0a, + 0xe3, 0x4f, 0x2c, 0x80, 0x69, 0xc5, 0xaf, 0x03, 0xea, 0x46, + 0x25, 0x89, 0x60, 0xcc, 0xd8, 0x74, 0x9d, 0x31, 0x52, 0xfe, + 0x17, 0xbb, 0xd1, 0x7d, 0x94, 0x38, 0x5b, 0xf7, 0x1e, 0xb2, + 0xca, 0x66, 0x8f, 0x23, 0x40, 0xec, 0x05, 0xa9, 0xc3, 0x6f, + 0x86, 0x2a, 0x49, 0xe5, 0x0c, 0xa0, 0xfc, 0x50, 0xb9, 0x15, + 0x76, 0xda, 0x33, 0x9f, 0xf5, 0x59, 0xb0, 0x1c, 0x7f, 0xd3, + 0x3a, 0x96, 0xee, 0x42, 0xab, 0x07, 0x64, 0xc8, 0x21, 0x8d, + 0xe7, 0x4b, 0xa2, 0x0e, 0x6d, 0xc1, 0x28, 0x84, 0x00, 0xad, + 0x47, 0xea, 0x8e, 0x23, 0xc9, 0x64, 0x01, 0xac, 0x46, 0xeb, + 0x8f, 0x22, 0xc8, 0x65, 0x02, 0xaf, 0x45, 0xe8, 0x8c, 0x21, + 0xcb, 0x66, 0x03, 0xae, 0x44, 0xe9, 0x8d, 0x20, 0xca, 0x67, + 0x04, 0xa9, 0x43, 0xee, 0x8a, 0x27, 0xcd, 0x60, 0x05, 0xa8, + 0x42, 0xef, 0x8b, 0x26, 0xcc, 0x61, 0x06, 0xab, 0x41, 0xec, + 0x88, 0x25, 0xcf, 0x62, 0x07, 0xaa, 0x40, 0xed, 0x89, 0x24, + 0xce, 0x63, 0x08, 0xa5, 0x4f, 0xe2, 0x86, 0x2b, 0xc1, 0x6c, + 0x09, 0xa4, 0x4e, 0xe3, 0x87, 0x2a, 0xc0, 0x6d, 0x0a, 0xa7, + 0x4d, 0xe0, 0x84, 0x29, 0xc3, 0x6e, 0x0b, 0xa6, 0x4c, 0xe1, + 0x85, 0x28, 0xc2, 0x6f, 0x0c, 0xa1, 0x4b, 0xe6, 0x82, 0x2f, + 0xc5, 0x68, 0x0d, 0xa0, 0x4a, 0xe7, 0x83, 0x2e, 0xc4, 0x69, + 0x0e, 0xa3, 0x49, 0xe4, 0x80, 0x2d, 0xc7, 0x6a, 0x0f, 0xa2, + 0x48, 0xe5, 0x81, 0x2c, 0xc6, 0x6b, 0x10, 0xbd, 0x57, 0xfa, + 0x9e, 0x33, 0xd9, 0x74, 0x11, 0xbc, 0x56, 0xfb, 0x9f, 0x32, + 0xd8, 0x75, 0x12, 0xbf, 0x55, 0xf8, 0x9c, 0x31, 0xdb, 0x76, + 0x13, 0xbe, 0x54, 0xf9, 0x9d, 0x30, 0xda, 0x77, 0x14, 0xb9, + 0x53, 0xfe, 0x9a, 0x37, 0xdd, 0x70, 0x15, 0xb8, 0x52, 0xff, + 0x9b, 0x36, 0xdc, 0x71, 0x16, 0xbb, 0x51, 0xfc, 0x98, 0x35, + 0xdf, 0x72, 0x17, 0xba, 0x50, 0xfd, 0x99, 0x34, 0xde, 0x73, + 0x18, 0xb5, 0x5f, 0xf2, 0x96, 0x3b, 0xd1, 0x7c, 0x19, 0xb4, + 0x5e, 0xf3, 0x97, 0x3a, 0xd0, 0x7d, 0x1a, 0xb7, 0x5d, 0xf0, + 0x94, 0x39, 0xd3, 0x7e, 0x1b, 0xb6, 0x5c, 0xf1, 0x95, 0x38, + 0xd2, 0x7f, 0x1c, 0xb1, 0x5b, 0xf6, 0x92, 0x3f, 0xd5, 0x78, + 0x1d, 0xb0, 0x5a, 0xf7, 0x93, 0x3e, 0xd4, 0x79, 0x1e, 0xb3, + 0x59, 0xf4, 0x90, 0x3d, 0xd7, 0x7a, 0x1f, 0xb2, 0x58, 0xf5, + 0x91, 0x3c, 0xd6, 0x7b, 0x00, 0xae, 0x41, 0xef, 0x82, 0x2c, + 0xc3, 0x6d, 0x19, 0xb7, 0x58, 0xf6, 0x9b, 0x35, 0xda, 0x74, + 0x32, 0x9c, 0x73, 0xdd, 0xb0, 0x1e, 0xf1, 0x5f, 0x2b, 0x85, + 0x6a, 0xc4, 0xa9, 0x07, 0xe8, 0x46, 0x64, 0xca, 0x25, 0x8b, + 0xe6, 0x48, 0xa7, 0x09, 0x7d, 0xd3, 0x3c, 0x92, 0xff, 0x51, + 0xbe, 0x10, 0x56, 0xf8, 0x17, 0xb9, 0xd4, 0x7a, 0x95, 0x3b, + 0x4f, 0xe1, 0x0e, 0xa0, 0xcd, 0x63, 0x8c, 0x22, 0xc8, 0x66, + 0x89, 0x27, 0x4a, 0xe4, 0x0b, 0xa5, 0xd1, 0x7f, 0x90, 0x3e, + 0x53, 0xfd, 0x12, 0xbc, 0xfa, 0x54, 0xbb, 0x15, 0x78, 0xd6, + 0x39, 0x97, 0xe3, 0x4d, 0xa2, 0x0c, 0x61, 0xcf, 0x20, 0x8e, + 0xac, 0x02, 0xed, 0x43, 0x2e, 0x80, 0x6f, 0xc1, 0xb5, 0x1b, + 0xf4, 0x5a, 0x37, 0x99, 0x76, 0xd8, 0x9e, 0x30, 0xdf, 0x71, + 0x1c, 0xb2, 0x5d, 0xf3, 0x87, 0x29, 0xc6, 0x68, 0x05, 0xab, + 0x44, 0xea, 0x8d, 0x23, 0xcc, 0x62, 0x0f, 0xa1, 0x4e, 0xe0, + 0x94, 0x3a, 0xd5, 0x7b, 0x16, 0xb8, 0x57, 0xf9, 0xbf, 0x11, + 0xfe, 0x50, 0x3d, 0x93, 0x7c, 0xd2, 0xa6, 0x08, 0xe7, 0x49, + 0x24, 0x8a, 0x65, 0xcb, 0xe9, 0x47, 0xa8, 0x06, 0x6b, 0xc5, + 0x2a, 0x84, 0xf0, 0x5e, 0xb1, 0x1f, 0x72, 0xdc, 0x33, 0x9d, + 0xdb, 0x75, 0x9a, 0x34, 0x59, 0xf7, 0x18, 0xb6, 0xc2, 0x6c, + 0x83, 0x2d, 0x40, 0xee, 0x01, 0xaf, 0x45, 0xeb, 0x04, 0xaa, + 0xc7, 0x69, 0x86, 0x28, 0x5c, 0xf2, 0x1d, 0xb3, 0xde, 0x70, + 0x9f, 0x31, 0x77, 0xd9, 0x36, 0x98, 0xf5, 0x5b, 0xb4, 0x1a, + 0x6e, 0xc0, 0x2f, 0x81, 0xec, 0x42, 0xad, 0x03, 0x21, 0x8f, + 0x60, 0xce, 0xa3, 0x0d, 0xe2, 0x4c, 0x38, 0x96, 0x79, 0xd7, + 0xba, 0x14, 0xfb, 0x55, 0x13, 0xbd, 0x52, 0xfc, 0x91, 0x3f, + 0xd0, 0x7e, 0x0a, 0xa4, 0x4b, 0xe5, 0x88, 0x26, 0xc9, 0x67, + 0x00, 0xaf, 0x43, 0xec, 0x86, 0x29, 0xc5, 0x6a, 0x11, 0xbe, + 0x52, 0xfd, 0x97, 0x38, 0xd4, 0x7b, 0x22, 0x8d, 0x61, 0xce, + 0xa4, 0x0b, 0xe7, 0x48, 0x33, 0x9c, 0x70, 0xdf, 0xb5, 0x1a, + 0xf6, 0x59, 0x44, 0xeb, 0x07, 0xa8, 0xc2, 0x6d, 0x81, 0x2e, + 0x55, 0xfa, 0x16, 0xb9, 0xd3, 0x7c, 0x90, 0x3f, 0x66, 0xc9, + 0x25, 0x8a, 0xe0, 0x4f, 0xa3, 0x0c, 0x77, 0xd8, 0x34, 0x9b, + 0xf1, 0x5e, 0xb2, 0x1d, 0x88, 0x27, 0xcb, 0x64, 0x0e, 0xa1, + 0x4d, 0xe2, 0x99, 0x36, 0xda, 0x75, 0x1f, 0xb0, 0x5c, 0xf3, + 0xaa, 0x05, 0xe9, 0x46, 0x2c, 0x83, 0x6f, 0xc0, 0xbb, 0x14, + 0xf8, 0x57, 0x3d, 0x92, 0x7e, 0xd1, 0xcc, 0x63, 0x8f, 0x20, + 0x4a, 0xe5, 0x09, 0xa6, 0xdd, 0x72, 0x9e, 0x31, 0x5b, 0xf4, + 0x18, 0xb7, 0xee, 0x41, 0xad, 0x02, 0x68, 0xc7, 0x2b, 0x84, + 0xff, 0x50, 0xbc, 0x13, 0x79, 0xd6, 0x3a, 0x95, 0x0d, 0xa2, + 0x4e, 0xe1, 0x8b, 0x24, 0xc8, 0x67, 0x1c, 0xb3, 0x5f, 0xf0, + 0x9a, 0x35, 0xd9, 0x76, 0x2f, 0x80, 0x6c, 0xc3, 0xa9, 0x06, + 0xea, 0x45, 0x3e, 0x91, 0x7d, 0xd2, 0xb8, 0x17, 0xfb, 0x54, + 0x49, 0xe6, 0x0a, 0xa5, 0xcf, 0x60, 0x8c, 0x23, 0x58, 0xf7, + 0x1b, 0xb4, 0xde, 0x71, 0x9d, 0x32, 0x6b, 0xc4, 0x28, 0x87, + 0xed, 0x42, 0xae, 0x01, 0x7a, 0xd5, 0x39, 0x96, 0xfc, 0x53, + 0xbf, 0x10, 0x85, 0x2a, 0xc6, 0x69, 0x03, 0xac, 0x40, 0xef, + 0x94, 0x3b, 0xd7, 0x78, 0x12, 0xbd, 0x51, 0xfe, 0xa7, 0x08, + 0xe4, 0x4b, 0x21, 0x8e, 0x62, 0xcd, 0xb6, 0x19, 0xf5, 0x5a, + 0x30, 0x9f, 0x73, 0xdc, 0xc1, 0x6e, 0x82, 0x2d, 0x47, 0xe8, + 0x04, 0xab, 0xd0, 0x7f, 0x93, 0x3c, 0x56, 0xf9, 0x15, 0xba, + 0xe3, 0x4c, 0xa0, 0x0f, 0x65, 0xca, 0x26, 0x89, 0xf2, 0x5d, + 0xb1, 0x1e, 0x74, 0xdb, 0x37, 0x98, 0x00, 0xb0, 0x7d, 0xcd, + 0xfa, 0x4a, 0x87, 0x37, 0xe9, 0x59, 0x94, 0x24, 0x13, 0xa3, + 0x6e, 0xde, 0xcf, 0x7f, 0xb2, 0x02, 0x35, 0x85, 0x48, 0xf8, + 0x26, 0x96, 0x5b, 0xeb, 0xdc, 0x6c, 0xa1, 0x11, 0x83, 0x33, + 0xfe, 0x4e, 0x79, 0xc9, 0x04, 0xb4, 0x6a, 0xda, 0x17, 0xa7, + 0x90, 0x20, 0xed, 0x5d, 0x4c, 0xfc, 0x31, 0x81, 0xb6, 0x06, + 0xcb, 0x7b, 0xa5, 0x15, 0xd8, 0x68, 0x5f, 0xef, 0x22, 0x92, + 0x1b, 0xab, 0x66, 0xd6, 0xe1, 0x51, 0x9c, 0x2c, 0xf2, 0x42, + 0x8f, 0x3f, 0x08, 0xb8, 0x75, 0xc5, 0xd4, 0x64, 0xa9, 0x19, + 0x2e, 0x9e, 0x53, 0xe3, 0x3d, 0x8d, 0x40, 0xf0, 0xc7, 0x77, + 0xba, 0x0a, 0x98, 0x28, 0xe5, 0x55, 0x62, 0xd2, 0x1f, 0xaf, + 0x71, 0xc1, 0x0c, 0xbc, 0x8b, 0x3b, 0xf6, 0x46, 0x57, 0xe7, + 0x2a, 0x9a, 0xad, 0x1d, 0xd0, 0x60, 0xbe, 0x0e, 0xc3, 0x73, + 0x44, 0xf4, 0x39, 0x89, 0x36, 0x86, 0x4b, 0xfb, 0xcc, 0x7c, + 0xb1, 0x01, 0xdf, 0x6f, 0xa2, 0x12, 0x25, 0x95, 0x58, 0xe8, + 0xf9, 0x49, 0x84, 0x34, 0x03, 0xb3, 0x7e, 0xce, 0x10, 0xa0, + 0x6d, 0xdd, 0xea, 0x5a, 0x97, 0x27, 0xb5, 0x05, 0xc8, 0x78, + 0x4f, 0xff, 0x32, 0x82, 0x5c, 0xec, 0x21, 0x91, 0xa6, 0x16, + 0xdb, 0x6b, 0x7a, 0xca, 0x07, 0xb7, 0x80, 0x30, 0xfd, 0x4d, + 0x93, 0x23, 0xee, 0x5e, 0x69, 0xd9, 0x14, 0xa4, 0x2d, 0x9d, + 0x50, 0xe0, 0xd7, 0x67, 0xaa, 0x1a, 0xc4, 0x74, 0xb9, 0x09, + 0x3e, 0x8e, 0x43, 0xf3, 0xe2, 0x52, 0x9f, 0x2f, 0x18, 0xa8, + 0x65, 0xd5, 0x0b, 0xbb, 0x76, 0xc6, 0xf1, 0x41, 0x8c, 0x3c, + 0xae, 0x1e, 0xd3, 0x63, 0x54, 0xe4, 0x29, 0x99, 0x47, 0xf7, + 0x3a, 0x8a, 0xbd, 0x0d, 0xc0, 0x70, 0x61, 0xd1, 0x1c, 0xac, + 0x9b, 0x2b, 0xe6, 0x56, 0x88, 0x38, 0xf5, 0x45, 0x72, 0xc2, + 0x0f, 0xbf, 0x00, 0xb1, 0x7f, 0xce, 0xfe, 0x4f, 0x81, 0x30, + 0xe1, 0x50, 0x9e, 0x2f, 0x1f, 0xae, 0x60, 0xd1, 0xdf, 0x6e, + 0xa0, 0x11, 0x21, 0x90, 0x5e, 0xef, 0x3e, 0x8f, 0x41, 0xf0, + 0xc0, 0x71, 0xbf, 0x0e, 0xa3, 0x12, 0xdc, 0x6d, 0x5d, 0xec, + 0x22, 0x93, 0x42, 0xf3, 0x3d, 0x8c, 0xbc, 0x0d, 0xc3, 0x72, + 0x7c, 0xcd, 0x03, 0xb2, 0x82, 0x33, 0xfd, 0x4c, 0x9d, 0x2c, + 0xe2, 0x53, 0x63, 0xd2, 0x1c, 0xad, 0x5b, 0xea, 0x24, 0x95, + 0xa5, 0x14, 0xda, 0x6b, 0xba, 0x0b, 0xc5, 0x74, 0x44, 0xf5, + 0x3b, 0x8a, 0x84, 0x35, 0xfb, 0x4a, 0x7a, 0xcb, 0x05, 0xb4, + 0x65, 0xd4, 0x1a, 0xab, 0x9b, 0x2a, 0xe4, 0x55, 0xf8, 0x49, + 0x87, 0x36, 0x06, 0xb7, 0x79, 0xc8, 0x19, 0xa8, 0x66, 0xd7, + 0xe7, 0x56, 0x98, 0x29, 0x27, 0x96, 0x58, 0xe9, 0xd9, 0x68, + 0xa6, 0x17, 0xc6, 0x77, 0xb9, 0x08, 0x38, 0x89, 0x47, 0xf6, + 0xb6, 0x07, 0xc9, 0x78, 0x48, 0xf9, 0x37, 0x86, 0x57, 0xe6, + 0x28, 0x99, 0xa9, 0x18, 0xd6, 0x67, 0x69, 0xd8, 0x16, 0xa7, + 0x97, 0x26, 0xe8, 0x59, 0x88, 0x39, 0xf7, 0x46, 0x76, 0xc7, + 0x09, 0xb8, 0x15, 0xa4, 0x6a, 0xdb, 0xeb, 0x5a, 0x94, 0x25, + 0xf4, 0x45, 0x8b, 0x3a, 0x0a, 0xbb, 0x75, 0xc4, 0xca, 0x7b, + 0xb5, 0x04, 0x34, 0x85, 0x4b, 0xfa, 0x2b, 0x9a, 0x54, 0xe5, + 0xd5, 0x64, 0xaa, 0x1b, 0xed, 0x5c, 0x92, 0x23, 0x13, 0xa2, + 0x6c, 0xdd, 0x0c, 0xbd, 0x73, 0xc2, 0xf2, 0x43, 0x8d, 0x3c, + 0x32, 0x83, 0x4d, 0xfc, 0xcc, 0x7d, 0xb3, 0x02, 0xd3, 0x62, + 0xac, 0x1d, 0x2d, 0x9c, 0x52, 0xe3, 0x4e, 0xff, 0x31, 0x80, + 0xb0, 0x01, 0xcf, 0x7e, 0xaf, 0x1e, 0xd0, 0x61, 0x51, 0xe0, + 0x2e, 0x9f, 0x91, 0x20, 0xee, 0x5f, 0x6f, 0xde, 0x10, 0xa1, + 0x70, 0xc1, 0x0f, 0xbe, 0x8e, 0x3f, 0xf1, 0x40, 0x00, 0xb2, + 0x79, 0xcb, 0xf2, 0x40, 0x8b, 0x39, 0xf9, 0x4b, 0x80, 0x32, + 0x0b, 0xb9, 0x72, 0xc0, 0xef, 0x5d, 0x96, 0x24, 0x1d, 0xaf, + 0x64, 0xd6, 0x16, 0xa4, 0x6f, 0xdd, 0xe4, 0x56, 0x9d, 0x2f, + 0xc3, 0x71, 0xba, 0x08, 0x31, 0x83, 0x48, 0xfa, 0x3a, 0x88, + 0x43, 0xf1, 0xc8, 0x7a, 0xb1, 0x03, 0x2c, 0x9e, 0x55, 0xe7, + 0xde, 0x6c, 0xa7, 0x15, 0xd5, 0x67, 0xac, 0x1e, 0x27, 0x95, + 0x5e, 0xec, 0x9b, 0x29, 0xe2, 0x50, 0x69, 0xdb, 0x10, 0xa2, + 0x62, 0xd0, 0x1b, 0xa9, 0x90, 0x22, 0xe9, 0x5b, 0x74, 0xc6, + 0x0d, 0xbf, 0x86, 0x34, 0xff, 0x4d, 0x8d, 0x3f, 0xf4, 0x46, + 0x7f, 0xcd, 0x06, 0xb4, 0x58, 0xea, 0x21, 0x93, 0xaa, 0x18, + 0xd3, 0x61, 0xa1, 0x13, 0xd8, 0x6a, 0x53, 0xe1, 0x2a, 0x98, + 0xb7, 0x05, 0xce, 0x7c, 0x45, 0xf7, 0x3c, 0x8e, 0x4e, 0xfc, + 0x37, 0x85, 0xbc, 0x0e, 0xc5, 0x77, 0x2b, 0x99, 0x52, 0xe0, + 0xd9, 0x6b, 0xa0, 0x12, 0xd2, 0x60, 0xab, 0x19, 0x20, 0x92, + 0x59, 0xeb, 0xc4, 0x76, 0xbd, 0x0f, 0x36, 0x84, 0x4f, 0xfd, + 0x3d, 0x8f, 0x44, 0xf6, 0xcf, 0x7d, 0xb6, 0x04, 0xe8, 0x5a, + 0x91, 0x23, 0x1a, 0xa8, 0x63, 0xd1, 0x11, 0xa3, 0x68, 0xda, + 0xe3, 0x51, 0x9a, 0x28, 0x07, 0xb5, 0x7e, 0xcc, 0xf5, 0x47, + 0x8c, 0x3e, 0xfe, 0x4c, 0x87, 0x35, 0x0c, 0xbe, 0x75, 0xc7, + 0xb0, 0x02, 0xc9, 0x7b, 0x42, 0xf0, 0x3b, 0x89, 0x49, 0xfb, + 0x30, 0x82, 0xbb, 0x09, 0xc2, 0x70, 0x5f, 0xed, 0x26, 0x94, + 0xad, 0x1f, 0xd4, 0x66, 0xa6, 0x14, 0xdf, 0x6d, 0x54, 0xe6, + 0x2d, 0x9f, 0x73, 0xc1, 0x0a, 0xb8, 0x81, 0x33, 0xf8, 0x4a, + 0x8a, 0x38, 0xf3, 0x41, 0x78, 0xca, 0x01, 0xb3, 0x9c, 0x2e, + 0xe5, 0x57, 0x6e, 0xdc, 0x17, 0xa5, 0x65, 0xd7, 0x1c, 0xae, + 0x97, 0x25, 0xee, 0x5c, 0x00, 0xb3, 0x7b, 0xc8, 0xf6, 0x45, + 0x8d, 0x3e, 0xf1, 0x42, 0x8a, 0x39, 0x07, 0xb4, 0x7c, 0xcf, + 0xff, 0x4c, 0x84, 0x37, 0x09, 0xba, 0x72, 0xc1, 0x0e, 0xbd, + 0x75, 0xc6, 0xf8, 0x4b, 0x83, 0x30, 0xe3, 0x50, 0x98, 0x2b, + 0x15, 0xa6, 0x6e, 0xdd, 0x12, 0xa1, 0x69, 0xda, 0xe4, 0x57, + 0x9f, 0x2c, 0x1c, 0xaf, 0x67, 0xd4, 0xea, 0x59, 0x91, 0x22, + 0xed, 0x5e, 0x96, 0x25, 0x1b, 0xa8, 0x60, 0xd3, 0xdb, 0x68, + 0xa0, 0x13, 0x2d, 0x9e, 0x56, 0xe5, 0x2a, 0x99, 0x51, 0xe2, + 0xdc, 0x6f, 0xa7, 0x14, 0x24, 0x97, 0x5f, 0xec, 0xd2, 0x61, + 0xa9, 0x1a, 0xd5, 0x66, 0xae, 0x1d, 0x23, 0x90, 0x58, 0xeb, + 0x38, 0x8b, 0x43, 0xf0, 0xce, 0x7d, 0xb5, 0x06, 0xc9, 0x7a, + 0xb2, 0x01, 0x3f, 0x8c, 0x44, 0xf7, 0xc7, 0x74, 0xbc, 0x0f, + 0x31, 0x82, 0x4a, 0xf9, 0x36, 0x85, 0x4d, 0xfe, 0xc0, 0x73, + 0xbb, 0x08, 0xab, 0x18, 0xd0, 0x63, 0x5d, 0xee, 0x26, 0x95, + 0x5a, 0xe9, 0x21, 0x92, 0xac, 0x1f, 0xd7, 0x64, 0x54, 0xe7, + 0x2f, 0x9c, 0xa2, 0x11, 0xd9, 0x6a, 0xa5, 0x16, 0xde, 0x6d, + 0x53, 0xe0, 0x28, 0x9b, 0x48, 0xfb, 0x33, 0x80, 0xbe, 0x0d, + 0xc5, 0x76, 0xb9, 0x0a, 0xc2, 0x71, 0x4f, 0xfc, 0x34, 0x87, + 0xb7, 0x04, 0xcc, 0x7f, 0x41, 0xf2, 0x3a, 0x89, 0x46, 0xf5, + 0x3d, 0x8e, 0xb0, 0x03, 0xcb, 0x78, 0x70, 0xc3, 0x0b, 0xb8, + 0x86, 0x35, 0xfd, 0x4e, 0x81, 0x32, 0xfa, 0x49, 0x77, 0xc4, + 0x0c, 0xbf, 0x8f, 0x3c, 0xf4, 0x47, 0x79, 0xca, 0x02, 0xb1, + 0x7e, 0xcd, 0x05, 0xb6, 0x88, 0x3b, 0xf3, 0x40, 0x93, 0x20, + 0xe8, 0x5b, 0x65, 0xd6, 0x1e, 0xad, 0x62, 0xd1, 0x19, 0xaa, + 0x94, 0x27, 0xef, 0x5c, 0x6c, 0xdf, 0x17, 0xa4, 0x9a, 0x29, + 0xe1, 0x52, 0x9d, 0x2e, 0xe6, 0x55, 0x6b, 0xd8, 0x10, 0xa3, + 0x00, 0xb4, 0x75, 0xc1, 0xea, 0x5e, 0x9f, 0x2b, 0xc9, 0x7d, + 0xbc, 0x08, 0x23, 0x97, 0x56, 0xe2, 0x8f, 0x3b, 0xfa, 0x4e, + 0x65, 0xd1, 0x10, 0xa4, 0x46, 0xf2, 0x33, 0x87, 0xac, 0x18, + 0xd9, 0x6d, 0x03, 0xb7, 0x76, 0xc2, 0xe9, 0x5d, 0x9c, 0x28, + 0xca, 0x7e, 0xbf, 0x0b, 0x20, 0x94, 0x55, 0xe1, 0x8c, 0x38, + 0xf9, 0x4d, 0x66, 0xd2, 0x13, 0xa7, 0x45, 0xf1, 0x30, 0x84, + 0xaf, 0x1b, 0xda, 0x6e, 0x06, 0xb2, 0x73, 0xc7, 0xec, 0x58, + 0x99, 0x2d, 0xcf, 0x7b, 0xba, 0x0e, 0x25, 0x91, 0x50, 0xe4, + 0x89, 0x3d, 0xfc, 0x48, 0x63, 0xd7, 0x16, 0xa2, 0x40, 0xf4, + 0x35, 0x81, 0xaa, 0x1e, 0xdf, 0x6b, 0x05, 0xb1, 0x70, 0xc4, + 0xef, 0x5b, 0x9a, 0x2e, 0xcc, 0x78, 0xb9, 0x0d, 0x26, 0x92, + 0x53, 0xe7, 0x8a, 0x3e, 0xff, 0x4b, 0x60, 0xd4, 0x15, 0xa1, + 0x43, 0xf7, 0x36, 0x82, 0xa9, 0x1d, 0xdc, 0x68, 0x0c, 0xb8, + 0x79, 0xcd, 0xe6, 0x52, 0x93, 0x27, 0xc5, 0x71, 0xb0, 0x04, + 0x2f, 0x9b, 0x5a, 0xee, 0x83, 0x37, 0xf6, 0x42, 0x69, 0xdd, + 0x1c, 0xa8, 0x4a, 0xfe, 0x3f, 0x8b, 0xa0, 0x14, 0xd5, 0x61, + 0x0f, 0xbb, 0x7a, 0xce, 0xe5, 0x51, 0x90, 0x24, 0xc6, 0x72, + 0xb3, 0x07, 0x2c, 0x98, 0x59, 0xed, 0x80, 0x34, 0xf5, 0x41, + 0x6a, 0xde, 0x1f, 0xab, 0x49, 0xfd, 0x3c, 0x88, 0xa3, 0x17, + 0xd6, 0x62, 0x0a, 0xbe, 0x7f, 0xcb, 0xe0, 0x54, 0x95, 0x21, + 0xc3, 0x77, 0xb6, 0x02, 0x29, 0x9d, 0x5c, 0xe8, 0x85, 0x31, + 0xf0, 0x44, 0x6f, 0xdb, 0x1a, 0xae, 0x4c, 0xf8, 0x39, 0x8d, + 0xa6, 0x12, 0xd3, 0x67, 0x09, 0xbd, 0x7c, 0xc8, 0xe3, 0x57, + 0x96, 0x22, 0xc0, 0x74, 0xb5, 0x01, 0x2a, 0x9e, 0x5f, 0xeb, + 0x86, 0x32, 0xf3, 0x47, 0x6c, 0xd8, 0x19, 0xad, 0x4f, 0xfb, + 0x3a, 0x8e, 0xa5, 0x11, 0xd0, 0x64, 0x00, 0xb5, 0x77, 0xc2, + 0xee, 0x5b, 0x99, 0x2c, 0xc1, 0x74, 0xb6, 0x03, 0x2f, 0x9a, + 0x58, 0xed, 0x9f, 0x2a, 0xe8, 0x5d, 0x71, 0xc4, 0x06, 0xb3, + 0x5e, 0xeb, 0x29, 0x9c, 0xb0, 0x05, 0xc7, 0x72, 0x23, 0x96, + 0x54, 0xe1, 0xcd, 0x78, 0xba, 0x0f, 0xe2, 0x57, 0x95, 0x20, + 0x0c, 0xb9, 0x7b, 0xce, 0xbc, 0x09, 0xcb, 0x7e, 0x52, 0xe7, + 0x25, 0x90, 0x7d, 0xc8, 0x0a, 0xbf, 0x93, 0x26, 0xe4, 0x51, + 0x46, 0xf3, 0x31, 0x84, 0xa8, 0x1d, 0xdf, 0x6a, 0x87, 0x32, + 0xf0, 0x45, 0x69, 0xdc, 0x1e, 0xab, 0xd9, 0x6c, 0xae, 0x1b, + 0x37, 0x82, 0x40, 0xf5, 0x18, 0xad, 0x6f, 0xda, 0xf6, 0x43, + 0x81, 0x34, 0x65, 0xd0, 0x12, 0xa7, 0x8b, 0x3e, 0xfc, 0x49, + 0xa4, 0x11, 0xd3, 0x66, 0x4a, 0xff, 0x3d, 0x88, 0xfa, 0x4f, + 0x8d, 0x38, 0x14, 0xa1, 0x63, 0xd6, 0x3b, 0x8e, 0x4c, 0xf9, + 0xd5, 0x60, 0xa2, 0x17, 0x8c, 0x39, 0xfb, 0x4e, 0x62, 0xd7, + 0x15, 0xa0, 0x4d, 0xf8, 0x3a, 0x8f, 0xa3, 0x16, 0xd4, 0x61, + 0x13, 0xa6, 0x64, 0xd1, 0xfd, 0x48, 0x8a, 0x3f, 0xd2, 0x67, + 0xa5, 0x10, 0x3c, 0x89, 0x4b, 0xfe, 0xaf, 0x1a, 0xd8, 0x6d, + 0x41, 0xf4, 0x36, 0x83, 0x6e, 0xdb, 0x19, 0xac, 0x80, 0x35, + 0xf7, 0x42, 0x30, 0x85, 0x47, 0xf2, 0xde, 0x6b, 0xa9, 0x1c, + 0xf1, 0x44, 0x86, 0x33, 0x1f, 0xaa, 0x68, 0xdd, 0xca, 0x7f, + 0xbd, 0x08, 0x24, 0x91, 0x53, 0xe6, 0x0b, 0xbe, 0x7c, 0xc9, + 0xe5, 0x50, 0x92, 0x27, 0x55, 0xe0, 0x22, 0x97, 0xbb, 0x0e, + 0xcc, 0x79, 0x94, 0x21, 0xe3, 0x56, 0x7a, 0xcf, 0x0d, 0xb8, + 0xe9, 0x5c, 0x9e, 0x2b, 0x07, 0xb2, 0x70, 0xc5, 0x28, 0x9d, + 0x5f, 0xea, 0xc6, 0x73, 0xb1, 0x04, 0x76, 0xc3, 0x01, 0xb4, + 0x98, 0x2d, 0xef, 0x5a, 0xb7, 0x02, 0xc0, 0x75, 0x59, 0xec, + 0x2e, 0x9b, 0x00, 0xb6, 0x71, 0xc7, 0xe2, 0x54, 0x93, 0x25, + 0xd9, 0x6f, 0xa8, 0x1e, 0x3b, 0x8d, 0x4a, 0xfc, 0xaf, 0x19, + 0xde, 0x68, 0x4d, 0xfb, 0x3c, 0x8a, 0x76, 0xc0, 0x07, 0xb1, + 0x94, 0x22, 0xe5, 0x53, 0x43, 0xf5, 0x32, 0x84, 0xa1, 0x17, + 0xd0, 0x66, 0x9a, 0x2c, 0xeb, 0x5d, 0x78, 0xce, 0x09, 0xbf, + 0xec, 0x5a, 0x9d, 0x2b, 0x0e, 0xb8, 0x7f, 0xc9, 0x35, 0x83, + 0x44, 0xf2, 0xd7, 0x61, 0xa6, 0x10, 0x86, 0x30, 0xf7, 0x41, + 0x64, 0xd2, 0x15, 0xa3, 0x5f, 0xe9, 0x2e, 0x98, 0xbd, 0x0b, + 0xcc, 0x7a, 0x29, 0x9f, 0x58, 0xee, 0xcb, 0x7d, 0xba, 0x0c, + 0xf0, 0x46, 0x81, 0x37, 0x12, 0xa4, 0x63, 0xd5, 0xc5, 0x73, + 0xb4, 0x02, 0x27, 0x91, 0x56, 0xe0, 0x1c, 0xaa, 0x6d, 0xdb, + 0xfe, 0x48, 0x8f, 0x39, 0x6a, 0xdc, 0x1b, 0xad, 0x88, 0x3e, + 0xf9, 0x4f, 0xb3, 0x05, 0xc2, 0x74, 0x51, 0xe7, 0x20, 0x96, + 0x11, 0xa7, 0x60, 0xd6, 0xf3, 0x45, 0x82, 0x34, 0xc8, 0x7e, + 0xb9, 0x0f, 0x2a, 0x9c, 0x5b, 0xed, 0xbe, 0x08, 0xcf, 0x79, + 0x5c, 0xea, 0x2d, 0x9b, 0x67, 0xd1, 0x16, 0xa0, 0x85, 0x33, + 0xf4, 0x42, 0x52, 0xe4, 0x23, 0x95, 0xb0, 0x06, 0xc1, 0x77, + 0x8b, 0x3d, 0xfa, 0x4c, 0x69, 0xdf, 0x18, 0xae, 0xfd, 0x4b, + 0x8c, 0x3a, 0x1f, 0xa9, 0x6e, 0xd8, 0x24, 0x92, 0x55, 0xe3, + 0xc6, 0x70, 0xb7, 0x01, 0x97, 0x21, 0xe6, 0x50, 0x75, 0xc3, + 0x04, 0xb2, 0x4e, 0xf8, 0x3f, 0x89, 0xac, 0x1a, 0xdd, 0x6b, + 0x38, 0x8e, 0x49, 0xff, 0xda, 0x6c, 0xab, 0x1d, 0xe1, 0x57, + 0x90, 0x26, 0x03, 0xb5, 0x72, 0xc4, 0xd4, 0x62, 0xa5, 0x13, + 0x36, 0x80, 0x47, 0xf1, 0x0d, 0xbb, 0x7c, 0xca, 0xef, 0x59, + 0x9e, 0x28, 0x7b, 0xcd, 0x0a, 0xbc, 0x99, 0x2f, 0xe8, 0x5e, + 0xa2, 0x14, 0xd3, 0x65, 0x40, 0xf6, 0x31, 0x87, 0x00, 0xb7, + 0x73, 0xc4, 0xe6, 0x51, 0x95, 0x22, 0xd1, 0x66, 0xa2, 0x15, + 0x37, 0x80, 0x44, 0xf3, 0xbf, 0x08, 0xcc, 0x7b, 0x59, 0xee, + 0x2a, 0x9d, 0x6e, 0xd9, 0x1d, 0xaa, 0x88, 0x3f, 0xfb, 0x4c, + 0x63, 0xd4, 0x10, 0xa7, 0x85, 0x32, 0xf6, 0x41, 0xb2, 0x05, + 0xc1, 0x76, 0x54, 0xe3, 0x27, 0x90, 0xdc, 0x6b, 0xaf, 0x18, + 0x3a, 0x8d, 0x49, 0xfe, 0x0d, 0xba, 0x7e, 0xc9, 0xeb, 0x5c, + 0x98, 0x2f, 0xc6, 0x71, 0xb5, 0x02, 0x20, 0x97, 0x53, 0xe4, + 0x17, 0xa0, 0x64, 0xd3, 0xf1, 0x46, 0x82, 0x35, 0x79, 0xce, + 0x0a, 0xbd, 0x9f, 0x28, 0xec, 0x5b, 0xa8, 0x1f, 0xdb, 0x6c, + 0x4e, 0xf9, 0x3d, 0x8a, 0xa5, 0x12, 0xd6, 0x61, 0x43, 0xf4, + 0x30, 0x87, 0x74, 0xc3, 0x07, 0xb0, 0x92, 0x25, 0xe1, 0x56, + 0x1a, 0xad, 0x69, 0xde, 0xfc, 0x4b, 0x8f, 0x38, 0xcb, 0x7c, + 0xb8, 0x0f, 0x2d, 0x9a, 0x5e, 0xe9, 0x91, 0x26, 0xe2, 0x55, + 0x77, 0xc0, 0x04, 0xb3, 0x40, 0xf7, 0x33, 0x84, 0xa6, 0x11, + 0xd5, 0x62, 0x2e, 0x99, 0x5d, 0xea, 0xc8, 0x7f, 0xbb, 0x0c, + 0xff, 0x48, 0x8c, 0x3b, 0x19, 0xae, 0x6a, 0xdd, 0xf2, 0x45, + 0x81, 0x36, 0x14, 0xa3, 0x67, 0xd0, 0x23, 0x94, 0x50, 0xe7, + 0xc5, 0x72, 0xb6, 0x01, 0x4d, 0xfa, 0x3e, 0x89, 0xab, 0x1c, + 0xd8, 0x6f, 0x9c, 0x2b, 0xef, 0x58, 0x7a, 0xcd, 0x09, 0xbe, + 0x57, 0xe0, 0x24, 0x93, 0xb1, 0x06, 0xc2, 0x75, 0x86, 0x31, + 0xf5, 0x42, 0x60, 0xd7, 0x13, 0xa4, 0xe8, 0x5f, 0x9b, 0x2c, + 0x0e, 0xb9, 0x7d, 0xca, 0x39, 0x8e, 0x4a, 0xfd, 0xdf, 0x68, + 0xac, 0x1b, 0x34, 0x83, 0x47, 0xf0, 0xd2, 0x65, 0xa1, 0x16, + 0xe5, 0x52, 0x96, 0x21, 0x03, 0xb4, 0x70, 0xc7, 0x8b, 0x3c, + 0xf8, 0x4f, 0x6d, 0xda, 0x1e, 0xa9, 0x5a, 0xed, 0x29, 0x9e, + 0xbc, 0x0b, 0xcf, 0x78, 0x00, 0xb8, 0x6d, 0xd5, 0xda, 0x62, + 0xb7, 0x0f, 0xa9, 0x11, 0xc4, 0x7c, 0x73, 0xcb, 0x1e, 0xa6, + 0x4f, 0xf7, 0x22, 0x9a, 0x95, 0x2d, 0xf8, 0x40, 0xe6, 0x5e, + 0x8b, 0x33, 0x3c, 0x84, 0x51, 0xe9, 0x9e, 0x26, 0xf3, 0x4b, + 0x44, 0xfc, 0x29, 0x91, 0x37, 0x8f, 0x5a, 0xe2, 0xed, 0x55, + 0x80, 0x38, 0xd1, 0x69, 0xbc, 0x04, 0x0b, 0xb3, 0x66, 0xde, + 0x78, 0xc0, 0x15, 0xad, 0xa2, 0x1a, 0xcf, 0x77, 0x21, 0x99, + 0x4c, 0xf4, 0xfb, 0x43, 0x96, 0x2e, 0x88, 0x30, 0xe5, 0x5d, + 0x52, 0xea, 0x3f, 0x87, 0x6e, 0xd6, 0x03, 0xbb, 0xb4, 0x0c, + 0xd9, 0x61, 0xc7, 0x7f, 0xaa, 0x12, 0x1d, 0xa5, 0x70, 0xc8, + 0xbf, 0x07, 0xd2, 0x6a, 0x65, 0xdd, 0x08, 0xb0, 0x16, 0xae, + 0x7b, 0xc3, 0xcc, 0x74, 0xa1, 0x19, 0xf0, 0x48, 0x9d, 0x25, + 0x2a, 0x92, 0x47, 0xff, 0x59, 0xe1, 0x34, 0x8c, 0x83, 0x3b, + 0xee, 0x56, 0x42, 0xfa, 0x2f, 0x97, 0x98, 0x20, 0xf5, 0x4d, + 0xeb, 0x53, 0x86, 0x3e, 0x31, 0x89, 0x5c, 0xe4, 0x0d, 0xb5, + 0x60, 0xd8, 0xd7, 0x6f, 0xba, 0x02, 0xa4, 0x1c, 0xc9, 0x71, + 0x7e, 0xc6, 0x13, 0xab, 0xdc, 0x64, 0xb1, 0x09, 0x06, 0xbe, + 0x6b, 0xd3, 0x75, 0xcd, 0x18, 0xa0, 0xaf, 0x17, 0xc2, 0x7a, + 0x93, 0x2b, 0xfe, 0x46, 0x49, 0xf1, 0x24, 0x9c, 0x3a, 0x82, + 0x57, 0xef, 0xe0, 0x58, 0x8d, 0x35, 0x63, 0xdb, 0x0e, 0xb6, + 0xb9, 0x01, 0xd4, 0x6c, 0xca, 0x72, 0xa7, 0x1f, 0x10, 0xa8, + 0x7d, 0xc5, 0x2c, 0x94, 0x41, 0xf9, 0xf6, 0x4e, 0x9b, 0x23, + 0x85, 0x3d, 0xe8, 0x50, 0x5f, 0xe7, 0x32, 0x8a, 0xfd, 0x45, + 0x90, 0x28, 0x27, 0x9f, 0x4a, 0xf2, 0x54, 0xec, 0x39, 0x81, + 0x8e, 0x36, 0xe3, 0x5b, 0xb2, 0x0a, 0xdf, 0x67, 0x68, 0xd0, + 0x05, 0xbd, 0x1b, 0xa3, 0x76, 0xce, 0xc1, 0x79, 0xac, 0x14, + 0x00, 0xb9, 0x6f, 0xd6, 0xde, 0x67, 0xb1, 0x08, 0xa1, 0x18, + 0xce, 0x77, 0x7f, 0xc6, 0x10, 0xa9, 0x5f, 0xe6, 0x30, 0x89, + 0x81, 0x38, 0xee, 0x57, 0xfe, 0x47, 0x91, 0x28, 0x20, 0x99, + 0x4f, 0xf6, 0xbe, 0x07, 0xd1, 0x68, 0x60, 0xd9, 0x0f, 0xb6, + 0x1f, 0xa6, 0x70, 0xc9, 0xc1, 0x78, 0xae, 0x17, 0xe1, 0x58, + 0x8e, 0x37, 0x3f, 0x86, 0x50, 0xe9, 0x40, 0xf9, 0x2f, 0x96, + 0x9e, 0x27, 0xf1, 0x48, 0x61, 0xd8, 0x0e, 0xb7, 0xbf, 0x06, + 0xd0, 0x69, 0xc0, 0x79, 0xaf, 0x16, 0x1e, 0xa7, 0x71, 0xc8, + 0x3e, 0x87, 0x51, 0xe8, 0xe0, 0x59, 0x8f, 0x36, 0x9f, 0x26, + 0xf0, 0x49, 0x41, 0xf8, 0x2e, 0x97, 0xdf, 0x66, 0xb0, 0x09, + 0x01, 0xb8, 0x6e, 0xd7, 0x7e, 0xc7, 0x11, 0xa8, 0xa0, 0x19, + 0xcf, 0x76, 0x80, 0x39, 0xef, 0x56, 0x5e, 0xe7, 0x31, 0x88, + 0x21, 0x98, 0x4e, 0xf7, 0xff, 0x46, 0x90, 0x29, 0xc2, 0x7b, + 0xad, 0x14, 0x1c, 0xa5, 0x73, 0xca, 0x63, 0xda, 0x0c, 0xb5, + 0xbd, 0x04, 0xd2, 0x6b, 0x9d, 0x24, 0xf2, 0x4b, 0x43, 0xfa, + 0x2c, 0x95, 0x3c, 0x85, 0x53, 0xea, 0xe2, 0x5b, 0x8d, 0x34, + 0x7c, 0xc5, 0x13, 0xaa, 0xa2, 0x1b, 0xcd, 0x74, 0xdd, 0x64, + 0xb2, 0x0b, 0x03, 0xba, 0x6c, 0xd5, 0x23, 0x9a, 0x4c, 0xf5, + 0xfd, 0x44, 0x92, 0x2b, 0x82, 0x3b, 0xed, 0x54, 0x5c, 0xe5, + 0x33, 0x8a, 0xa3, 0x1a, 0xcc, 0x75, 0x7d, 0xc4, 0x12, 0xab, + 0x02, 0xbb, 0x6d, 0xd4, 0xdc, 0x65, 0xb3, 0x0a, 0xfc, 0x45, + 0x93, 0x2a, 0x22, 0x9b, 0x4d, 0xf4, 0x5d, 0xe4, 0x32, 0x8b, + 0x83, 0x3a, 0xec, 0x55, 0x1d, 0xa4, 0x72, 0xcb, 0xc3, 0x7a, + 0xac, 0x15, 0xbc, 0x05, 0xd3, 0x6a, 0x62, 0xdb, 0x0d, 0xb4, + 0x42, 0xfb, 0x2d, 0x94, 0x9c, 0x25, 0xf3, 0x4a, 0xe3, 0x5a, + 0x8c, 0x35, 0x3d, 0x84, 0x52, 0xeb, 0x00, 0xba, 0x69, 0xd3, + 0xd2, 0x68, 0xbb, 0x01, 0xb9, 0x03, 0xd0, 0x6a, 0x6b, 0xd1, + 0x02, 0xb8, 0x6f, 0xd5, 0x06, 0xbc, 0xbd, 0x07, 0xd4, 0x6e, + 0xd6, 0x6c, 0xbf, 0x05, 0x04, 0xbe, 0x6d, 0xd7, 0xde, 0x64, + 0xb7, 0x0d, 0x0c, 0xb6, 0x65, 0xdf, 0x67, 0xdd, 0x0e, 0xb4, + 0xb5, 0x0f, 0xdc, 0x66, 0xb1, 0x0b, 0xd8, 0x62, 0x63, 0xd9, + 0x0a, 0xb0, 0x08, 0xb2, 0x61, 0xdb, 0xda, 0x60, 0xb3, 0x09, + 0xa1, 0x1b, 0xc8, 0x72, 0x73, 0xc9, 0x1a, 0xa0, 0x18, 0xa2, + 0x71, 0xcb, 0xca, 0x70, 0xa3, 0x19, 0xce, 0x74, 0xa7, 0x1d, + 0x1c, 0xa6, 0x75, 0xcf, 0x77, 0xcd, 0x1e, 0xa4, 0xa5, 0x1f, + 0xcc, 0x76, 0x7f, 0xc5, 0x16, 0xac, 0xad, 0x17, 0xc4, 0x7e, + 0xc6, 0x7c, 0xaf, 0x15, 0x14, 0xae, 0x7d, 0xc7, 0x10, 0xaa, + 0x79, 0xc3, 0xc2, 0x78, 0xab, 0x11, 0xa9, 0x13, 0xc0, 0x7a, + 0x7b, 0xc1, 0x12, 0xa8, 0x5f, 0xe5, 0x36, 0x8c, 0x8d, 0x37, + 0xe4, 0x5e, 0xe6, 0x5c, 0x8f, 0x35, 0x34, 0x8e, 0x5d, 0xe7, + 0x30, 0x8a, 0x59, 0xe3, 0xe2, 0x58, 0x8b, 0x31, 0x89, 0x33, + 0xe0, 0x5a, 0x5b, 0xe1, 0x32, 0x88, 0x81, 0x3b, 0xe8, 0x52, + 0x53, 0xe9, 0x3a, 0x80, 0x38, 0x82, 0x51, 0xeb, 0xea, 0x50, + 0x83, 0x39, 0xee, 0x54, 0x87, 0x3d, 0x3c, 0x86, 0x55, 0xef, + 0x57, 0xed, 0x3e, 0x84, 0x85, 0x3f, 0xec, 0x56, 0xfe, 0x44, + 0x97, 0x2d, 0x2c, 0x96, 0x45, 0xff, 0x47, 0xfd, 0x2e, 0x94, + 0x95, 0x2f, 0xfc, 0x46, 0x91, 0x2b, 0xf8, 0x42, 0x43, 0xf9, + 0x2a, 0x90, 0x28, 0x92, 0x41, 0xfb, 0xfa, 0x40, 0x93, 0x29, + 0x20, 0x9a, 0x49, 0xf3, 0xf2, 0x48, 0x9b, 0x21, 0x99, 0x23, + 0xf0, 0x4a, 0x4b, 0xf1, 0x22, 0x98, 0x4f, 0xf5, 0x26, 0x9c, + 0x9d, 0x27, 0xf4, 0x4e, 0xf6, 0x4c, 0x9f, 0x25, 0x24, 0x9e, + 0x4d, 0xf7, 0x00, 0xbb, 0x6b, 0xd0, 0xd6, 0x6d, 0xbd, 0x06, + 0xb1, 0x0a, 0xda, 0x61, 0x67, 0xdc, 0x0c, 0xb7, 0x7f, 0xc4, + 0x14, 0xaf, 0xa9, 0x12, 0xc2, 0x79, 0xce, 0x75, 0xa5, 0x1e, + 0x18, 0xa3, 0x73, 0xc8, 0xfe, 0x45, 0x95, 0x2e, 0x28, 0x93, + 0x43, 0xf8, 0x4f, 0xf4, 0x24, 0x9f, 0x99, 0x22, 0xf2, 0x49, + 0x81, 0x3a, 0xea, 0x51, 0x57, 0xec, 0x3c, 0x87, 0x30, 0x8b, + 0x5b, 0xe0, 0xe6, 0x5d, 0x8d, 0x36, 0xe1, 0x5a, 0x8a, 0x31, + 0x37, 0x8c, 0x5c, 0xe7, 0x50, 0xeb, 0x3b, 0x80, 0x86, 0x3d, + 0xed, 0x56, 0x9e, 0x25, 0xf5, 0x4e, 0x48, 0xf3, 0x23, 0x98, + 0x2f, 0x94, 0x44, 0xff, 0xf9, 0x42, 0x92, 0x29, 0x1f, 0xa4, + 0x74, 0xcf, 0xc9, 0x72, 0xa2, 0x19, 0xae, 0x15, 0xc5, 0x7e, + 0x78, 0xc3, 0x13, 0xa8, 0x60, 0xdb, 0x0b, 0xb0, 0xb6, 0x0d, + 0xdd, 0x66, 0xd1, 0x6a, 0xba, 0x01, 0x07, 0xbc, 0x6c, 0xd7, + 0xdf, 0x64, 0xb4, 0x0f, 0x09, 0xb2, 0x62, 0xd9, 0x6e, 0xd5, + 0x05, 0xbe, 0xb8, 0x03, 0xd3, 0x68, 0xa0, 0x1b, 0xcb, 0x70, + 0x76, 0xcd, 0x1d, 0xa6, 0x11, 0xaa, 0x7a, 0xc1, 0xc7, 0x7c, + 0xac, 0x17, 0x21, 0x9a, 0x4a, 0xf1, 0xf7, 0x4c, 0x9c, 0x27, + 0x90, 0x2b, 0xfb, 0x40, 0x46, 0xfd, 0x2d, 0x96, 0x5e, 0xe5, + 0x35, 0x8e, 0x88, 0x33, 0xe3, 0x58, 0xef, 0x54, 0x84, 0x3f, + 0x39, 0x82, 0x52, 0xe9, 0x3e, 0x85, 0x55, 0xee, 0xe8, 0x53, + 0x83, 0x38, 0x8f, 0x34, 0xe4, 0x5f, 0x59, 0xe2, 0x32, 0x89, + 0x41, 0xfa, 0x2a, 0x91, 0x97, 0x2c, 0xfc, 0x47, 0xf0, 0x4b, + 0x9b, 0x20, 0x26, 0x9d, 0x4d, 0xf6, 0xc0, 0x7b, 0xab, 0x10, + 0x16, 0xad, 0x7d, 0xc6, 0x71, 0xca, 0x1a, 0xa1, 0xa7, 0x1c, + 0xcc, 0x77, 0xbf, 0x04, 0xd4, 0x6f, 0x69, 0xd2, 0x02, 0xb9, + 0x0e, 0xb5, 0x65, 0xde, 0xd8, 0x63, 0xb3, 0x08, 0x00, 0xbc, + 0x65, 0xd9, 0xca, 0x76, 0xaf, 0x13, 0x89, 0x35, 0xec, 0x50, + 0x43, 0xff, 0x26, 0x9a, 0x0f, 0xb3, 0x6a, 0xd6, 0xc5, 0x79, + 0xa0, 0x1c, 0x86, 0x3a, 0xe3, 0x5f, 0x4c, 0xf0, 0x29, 0x95, + 0x1e, 0xa2, 0x7b, 0xc7, 0xd4, 0x68, 0xb1, 0x0d, 0x97, 0x2b, + 0xf2, 0x4e, 0x5d, 0xe1, 0x38, 0x84, 0x11, 0xad, 0x74, 0xc8, + 0xdb, 0x67, 0xbe, 0x02, 0x98, 0x24, 0xfd, 0x41, 0x52, 0xee, + 0x37, 0x8b, 0x3c, 0x80, 0x59, 0xe5, 0xf6, 0x4a, 0x93, 0x2f, + 0xb5, 0x09, 0xd0, 0x6c, 0x7f, 0xc3, 0x1a, 0xa6, 0x33, 0x8f, + 0x56, 0xea, 0xf9, 0x45, 0x9c, 0x20, 0xba, 0x06, 0xdf, 0x63, + 0x70, 0xcc, 0x15, 0xa9, 0x22, 0x9e, 0x47, 0xfb, 0xe8, 0x54, + 0x8d, 0x31, 0xab, 0x17, 0xce, 0x72, 0x61, 0xdd, 0x04, 0xb8, + 0x2d, 0x91, 0x48, 0xf4, 0xe7, 0x5b, 0x82, 0x3e, 0xa4, 0x18, + 0xc1, 0x7d, 0x6e, 0xd2, 0x0b, 0xb7, 0x78, 0xc4, 0x1d, 0xa1, + 0xb2, 0x0e, 0xd7, 0x6b, 0xf1, 0x4d, 0x94, 0x28, 0x3b, 0x87, + 0x5e, 0xe2, 0x77, 0xcb, 0x12, 0xae, 0xbd, 0x01, 0xd8, 0x64, + 0xfe, 0x42, 0x9b, 0x27, 0x34, 0x88, 0x51, 0xed, 0x66, 0xda, + 0x03, 0xbf, 0xac, 0x10, 0xc9, 0x75, 0xef, 0x53, 0x8a, 0x36, + 0x25, 0x99, 0x40, 0xfc, 0x69, 0xd5, 0x0c, 0xb0, 0xa3, 0x1f, + 0xc6, 0x7a, 0xe0, 0x5c, 0x85, 0x39, 0x2a, 0x96, 0x4f, 0xf3, + 0x44, 0xf8, 0x21, 0x9d, 0x8e, 0x32, 0xeb, 0x57, 0xcd, 0x71, + 0xa8, 0x14, 0x07, 0xbb, 0x62, 0xde, 0x4b, 0xf7, 0x2e, 0x92, + 0x81, 0x3d, 0xe4, 0x58, 0xc2, 0x7e, 0xa7, 0x1b, 0x08, 0xb4, + 0x6d, 0xd1, 0x5a, 0xe6, 0x3f, 0x83, 0x90, 0x2c, 0xf5, 0x49, + 0xd3, 0x6f, 0xb6, 0x0a, 0x19, 0xa5, 0x7c, 0xc0, 0x55, 0xe9, + 0x30, 0x8c, 0x9f, 0x23, 0xfa, 0x46, 0xdc, 0x60, 0xb9, 0x05, + 0x16, 0xaa, 0x73, 0xcf, 0x00, 0xbd, 0x67, 0xda, 0xce, 0x73, + 0xa9, 0x14, 0x81, 0x3c, 0xe6, 0x5b, 0x4f, 0xf2, 0x28, 0x95, + 0x1f, 0xa2, 0x78, 0xc5, 0xd1, 0x6c, 0xb6, 0x0b, 0x9e, 0x23, + 0xf9, 0x44, 0x50, 0xed, 0x37, 0x8a, 0x3e, 0x83, 0x59, 0xe4, + 0xf0, 0x4d, 0x97, 0x2a, 0xbf, 0x02, 0xd8, 0x65, 0x71, 0xcc, + 0x16, 0xab, 0x21, 0x9c, 0x46, 0xfb, 0xef, 0x52, 0x88, 0x35, + 0xa0, 0x1d, 0xc7, 0x7a, 0x6e, 0xd3, 0x09, 0xb4, 0x7c, 0xc1, + 0x1b, 0xa6, 0xb2, 0x0f, 0xd5, 0x68, 0xfd, 0x40, 0x9a, 0x27, + 0x33, 0x8e, 0x54, 0xe9, 0x63, 0xde, 0x04, 0xb9, 0xad, 0x10, + 0xca, 0x77, 0xe2, 0x5f, 0x85, 0x38, 0x2c, 0x91, 0x4b, 0xf6, + 0x42, 0xff, 0x25, 0x98, 0x8c, 0x31, 0xeb, 0x56, 0xc3, 0x7e, + 0xa4, 0x19, 0x0d, 0xb0, 0x6a, 0xd7, 0x5d, 0xe0, 0x3a, 0x87, + 0x93, 0x2e, 0xf4, 0x49, 0xdc, 0x61, 0xbb, 0x06, 0x12, 0xaf, + 0x75, 0xc8, 0xf8, 0x45, 0x9f, 0x22, 0x36, 0x8b, 0x51, 0xec, + 0x79, 0xc4, 0x1e, 0xa3, 0xb7, 0x0a, 0xd0, 0x6d, 0xe7, 0x5a, + 0x80, 0x3d, 0x29, 0x94, 0x4e, 0xf3, 0x66, 0xdb, 0x01, 0xbc, + 0xa8, 0x15, 0xcf, 0x72, 0xc6, 0x7b, 0xa1, 0x1c, 0x08, 0xb5, + 0x6f, 0xd2, 0x47, 0xfa, 0x20, 0x9d, 0x89, 0x34, 0xee, 0x53, + 0xd9, 0x64, 0xbe, 0x03, 0x17, 0xaa, 0x70, 0xcd, 0x58, 0xe5, + 0x3f, 0x82, 0x96, 0x2b, 0xf1, 0x4c, 0x84, 0x39, 0xe3, 0x5e, + 0x4a, 0xf7, 0x2d, 0x90, 0x05, 0xb8, 0x62, 0xdf, 0xcb, 0x76, + 0xac, 0x11, 0x9b, 0x26, 0xfc, 0x41, 0x55, 0xe8, 0x32, 0x8f, + 0x1a, 0xa7, 0x7d, 0xc0, 0xd4, 0x69, 0xb3, 0x0e, 0xba, 0x07, + 0xdd, 0x60, 0x74, 0xc9, 0x13, 0xae, 0x3b, 0x86, 0x5c, 0xe1, + 0xf5, 0x48, 0x92, 0x2f, 0xa5, 0x18, 0xc2, 0x7f, 0x6b, 0xd6, + 0x0c, 0xb1, 0x24, 0x99, 0x43, 0xfe, 0xea, 0x57, 0x8d, 0x30, + 0x00, 0xbe, 0x61, 0xdf, 0xc2, 0x7c, 0xa3, 0x1d, 0x99, 0x27, + 0xf8, 0x46, 0x5b, 0xe5, 0x3a, 0x84, 0x2f, 0x91, 0x4e, 0xf0, + 0xed, 0x53, 0x8c, 0x32, 0xb6, 0x08, 0xd7, 0x69, 0x74, 0xca, + 0x15, 0xab, 0x5e, 0xe0, 0x3f, 0x81, 0x9c, 0x22, 0xfd, 0x43, + 0xc7, 0x79, 0xa6, 0x18, 0x05, 0xbb, 0x64, 0xda, 0x71, 0xcf, + 0x10, 0xae, 0xb3, 0x0d, 0xd2, 0x6c, 0xe8, 0x56, 0x89, 0x37, + 0x2a, 0x94, 0x4b, 0xf5, 0xbc, 0x02, 0xdd, 0x63, 0x7e, 0xc0, + 0x1f, 0xa1, 0x25, 0x9b, 0x44, 0xfa, 0xe7, 0x59, 0x86, 0x38, + 0x93, 0x2d, 0xf2, 0x4c, 0x51, 0xef, 0x30, 0x8e, 0x0a, 0xb4, + 0x6b, 0xd5, 0xc8, 0x76, 0xa9, 0x17, 0xe2, 0x5c, 0x83, 0x3d, + 0x20, 0x9e, 0x41, 0xff, 0x7b, 0xc5, 0x1a, 0xa4, 0xb9, 0x07, + 0xd8, 0x66, 0xcd, 0x73, 0xac, 0x12, 0x0f, 0xb1, 0x6e, 0xd0, + 0x54, 0xea, 0x35, 0x8b, 0x96, 0x28, 0xf7, 0x49, 0x65, 0xdb, + 0x04, 0xba, 0xa7, 0x19, 0xc6, 0x78, 0xfc, 0x42, 0x9d, 0x23, + 0x3e, 0x80, 0x5f, 0xe1, 0x4a, 0xf4, 0x2b, 0x95, 0x88, 0x36, + 0xe9, 0x57, 0xd3, 0x6d, 0xb2, 0x0c, 0x11, 0xaf, 0x70, 0xce, + 0x3b, 0x85, 0x5a, 0xe4, 0xf9, 0x47, 0x98, 0x26, 0xa2, 0x1c, + 0xc3, 0x7d, 0x60, 0xde, 0x01, 0xbf, 0x14, 0xaa, 0x75, 0xcb, + 0xd6, 0x68, 0xb7, 0x09, 0x8d, 0x33, 0xec, 0x52, 0x4f, 0xf1, + 0x2e, 0x90, 0xd9, 0x67, 0xb8, 0x06, 0x1b, 0xa5, 0x7a, 0xc4, + 0x40, 0xfe, 0x21, 0x9f, 0x82, 0x3c, 0xe3, 0x5d, 0xf6, 0x48, + 0x97, 0x29, 0x34, 0x8a, 0x55, 0xeb, 0x6f, 0xd1, 0x0e, 0xb0, + 0xad, 0x13, 0xcc, 0x72, 0x87, 0x39, 0xe6, 0x58, 0x45, 0xfb, + 0x24, 0x9a, 0x1e, 0xa0, 0x7f, 0xc1, 0xdc, 0x62, 0xbd, 0x03, + 0xa8, 0x16, 0xc9, 0x77, 0x6a, 0xd4, 0x0b, 0xb5, 0x31, 0x8f, + 0x50, 0xee, 0xf3, 0x4d, 0x92, 0x2c, 0x00, 0xbf, 0x63, 0xdc, + 0xc6, 0x79, 0xa5, 0x1a, 0x91, 0x2e, 0xf2, 0x4d, 0x57, 0xe8, + 0x34, 0x8b, 0x3f, 0x80, 0x5c, 0xe3, 0xf9, 0x46, 0x9a, 0x25, + 0xae, 0x11, 0xcd, 0x72, 0x68, 0xd7, 0x0b, 0xb4, 0x7e, 0xc1, + 0x1d, 0xa2, 0xb8, 0x07, 0xdb, 0x64, 0xef, 0x50, 0x8c, 0x33, + 0x29, 0x96, 0x4a, 0xf5, 0x41, 0xfe, 0x22, 0x9d, 0x87, 0x38, + 0xe4, 0x5b, 0xd0, 0x6f, 0xb3, 0x0c, 0x16, 0xa9, 0x75, 0xca, + 0xfc, 0x43, 0x9f, 0x20, 0x3a, 0x85, 0x59, 0xe6, 0x6d, 0xd2, + 0x0e, 0xb1, 0xab, 0x14, 0xc8, 0x77, 0xc3, 0x7c, 0xa0, 0x1f, + 0x05, 0xba, 0x66, 0xd9, 0x52, 0xed, 0x31, 0x8e, 0x94, 0x2b, + 0xf7, 0x48, 0x82, 0x3d, 0xe1, 0x5e, 0x44, 0xfb, 0x27, 0x98, + 0x13, 0xac, 0x70, 0xcf, 0xd5, 0x6a, 0xb6, 0x09, 0xbd, 0x02, + 0xde, 0x61, 0x7b, 0xc4, 0x18, 0xa7, 0x2c, 0x93, 0x4f, 0xf0, + 0xea, 0x55, 0x89, 0x36, 0xe5, 0x5a, 0x86, 0x39, 0x23, 0x9c, + 0x40, 0xff, 0x74, 0xcb, 0x17, 0xa8, 0xb2, 0x0d, 0xd1, 0x6e, + 0xda, 0x65, 0xb9, 0x06, 0x1c, 0xa3, 0x7f, 0xc0, 0x4b, 0xf4, + 0x28, 0x97, 0x8d, 0x32, 0xee, 0x51, 0x9b, 0x24, 0xf8, 0x47, + 0x5d, 0xe2, 0x3e, 0x81, 0x0a, 0xb5, 0x69, 0xd6, 0xcc, 0x73, + 0xaf, 0x10, 0xa4, 0x1b, 0xc7, 0x78, 0x62, 0xdd, 0x01, 0xbe, + 0x35, 0x8a, 0x56, 0xe9, 0xf3, 0x4c, 0x90, 0x2f, 0x19, 0xa6, + 0x7a, 0xc5, 0xdf, 0x60, 0xbc, 0x03, 0x88, 0x37, 0xeb, 0x54, + 0x4e, 0xf1, 0x2d, 0x92, 0x26, 0x99, 0x45, 0xfa, 0xe0, 0x5f, + 0x83, 0x3c, 0xb7, 0x08, 0xd4, 0x6b, 0x71, 0xce, 0x12, 0xad, + 0x67, 0xd8, 0x04, 0xbb, 0xa1, 0x1e, 0xc2, 0x7d, 0xf6, 0x49, + 0x95, 0x2a, 0x30, 0x8f, 0x53, 0xec, 0x58, 0xe7, 0x3b, 0x84, + 0x9e, 0x21, 0xfd, 0x42, 0xc9, 0x76, 0xaa, 0x15, 0x0f, 0xb0, + 0x6c, 0xd3, 0x00, 0xc0, 0x9d, 0x5d, 0x27, 0xe7, 0xba, 0x7a, + 0x4e, 0x8e, 0xd3, 0x13, 0x69, 0xa9, 0xf4, 0x34, 0x9c, 0x5c, + 0x01, 0xc1, 0xbb, 0x7b, 0x26, 0xe6, 0xd2, 0x12, 0x4f, 0x8f, + 0xf5, 0x35, 0x68, 0xa8, 0x25, 0xe5, 0xb8, 0x78, 0x02, 0xc2, + 0x9f, 0x5f, 0x6b, 0xab, 0xf6, 0x36, 0x4c, 0x8c, 0xd1, 0x11, + 0xb9, 0x79, 0x24, 0xe4, 0x9e, 0x5e, 0x03, 0xc3, 0xf7, 0x37, + 0x6a, 0xaa, 0xd0, 0x10, 0x4d, 0x8d, 0x4a, 0x8a, 0xd7, 0x17, + 0x6d, 0xad, 0xf0, 0x30, 0x04, 0xc4, 0x99, 0x59, 0x23, 0xe3, + 0xbe, 0x7e, 0xd6, 0x16, 0x4b, 0x8b, 0xf1, 0x31, 0x6c, 0xac, + 0x98, 0x58, 0x05, 0xc5, 0xbf, 0x7f, 0x22, 0xe2, 0x6f, 0xaf, + 0xf2, 0x32, 0x48, 0x88, 0xd5, 0x15, 0x21, 0xe1, 0xbc, 0x7c, + 0x06, 0xc6, 0x9b, 0x5b, 0xf3, 0x33, 0x6e, 0xae, 0xd4, 0x14, + 0x49, 0x89, 0xbd, 0x7d, 0x20, 0xe0, 0x9a, 0x5a, 0x07, 0xc7, + 0x94, 0x54, 0x09, 0xc9, 0xb3, 0x73, 0x2e, 0xee, 0xda, 0x1a, + 0x47, 0x87, 0xfd, 0x3d, 0x60, 0xa0, 0x08, 0xc8, 0x95, 0x55, + 0x2f, 0xef, 0xb2, 0x72, 0x46, 0x86, 0xdb, 0x1b, 0x61, 0xa1, + 0xfc, 0x3c, 0xb1, 0x71, 0x2c, 0xec, 0x96, 0x56, 0x0b, 0xcb, + 0xff, 0x3f, 0x62, 0xa2, 0xd8, 0x18, 0x45, 0x85, 0x2d, 0xed, + 0xb0, 0x70, 0x0a, 0xca, 0x97, 0x57, 0x63, 0xa3, 0xfe, 0x3e, + 0x44, 0x84, 0xd9, 0x19, 0xde, 0x1e, 0x43, 0x83, 0xf9, 0x39, + 0x64, 0xa4, 0x90, 0x50, 0x0d, 0xcd, 0xb7, 0x77, 0x2a, 0xea, + 0x42, 0x82, 0xdf, 0x1f, 0x65, 0xa5, 0xf8, 0x38, 0x0c, 0xcc, + 0x91, 0x51, 0x2b, 0xeb, 0xb6, 0x76, 0xfb, 0x3b, 0x66, 0xa6, + 0xdc, 0x1c, 0x41, 0x81, 0xb5, 0x75, 0x28, 0xe8, 0x92, 0x52, + 0x0f, 0xcf, 0x67, 0xa7, 0xfa, 0x3a, 0x40, 0x80, 0xdd, 0x1d, + 0x29, 0xe9, 0xb4, 0x74, 0x0e, 0xce, 0x93, 0x53, 0x00, 0xc1, + 0x9f, 0x5e, 0x23, 0xe2, 0xbc, 0x7d, 0x46, 0x87, 0xd9, 0x18, + 0x65, 0xa4, 0xfa, 0x3b, 0x8c, 0x4d, 0x13, 0xd2, 0xaf, 0x6e, + 0x30, 0xf1, 0xca, 0x0b, 0x55, 0x94, 0xe9, 0x28, 0x76, 0xb7, + 0x05, 0xc4, 0x9a, 0x5b, 0x26, 0xe7, 0xb9, 0x78, 0x43, 0x82, + 0xdc, 0x1d, 0x60, 0xa1, 0xff, 0x3e, 0x89, 0x48, 0x16, 0xd7, + 0xaa, 0x6b, 0x35, 0xf4, 0xcf, 0x0e, 0x50, 0x91, 0xec, 0x2d, + 0x73, 0xb2, 0x0a, 0xcb, 0x95, 0x54, 0x29, 0xe8, 0xb6, 0x77, + 0x4c, 0x8d, 0xd3, 0x12, 0x6f, 0xae, 0xf0, 0x31, 0x86, 0x47, + 0x19, 0xd8, 0xa5, 0x64, 0x3a, 0xfb, 0xc0, 0x01, 0x5f, 0x9e, + 0xe3, 0x22, 0x7c, 0xbd, 0x0f, 0xce, 0x90, 0x51, 0x2c, 0xed, + 0xb3, 0x72, 0x49, 0x88, 0xd6, 0x17, 0x6a, 0xab, 0xf5, 0x34, + 0x83, 0x42, 0x1c, 0xdd, 0xa0, 0x61, 0x3f, 0xfe, 0xc5, 0x04, + 0x5a, 0x9b, 0xe6, 0x27, 0x79, 0xb8, 0x14, 0xd5, 0x8b, 0x4a, + 0x37, 0xf6, 0xa8, 0x69, 0x52, 0x93, 0xcd, 0x0c, 0x71, 0xb0, + 0xee, 0x2f, 0x98, 0x59, 0x07, 0xc6, 0xbb, 0x7a, 0x24, 0xe5, + 0xde, 0x1f, 0x41, 0x80, 0xfd, 0x3c, 0x62, 0xa3, 0x11, 0xd0, + 0x8e, 0x4f, 0x32, 0xf3, 0xad, 0x6c, 0x57, 0x96, 0xc8, 0x09, + 0x74, 0xb5, 0xeb, 0x2a, 0x9d, 0x5c, 0x02, 0xc3, 0xbe, 0x7f, + 0x21, 0xe0, 0xdb, 0x1a, 0x44, 0x85, 0xf8, 0x39, 0x67, 0xa6, + 0x1e, 0xdf, 0x81, 0x40, 0x3d, 0xfc, 0xa2, 0x63, 0x58, 0x99, + 0xc7, 0x06, 0x7b, 0xba, 0xe4, 0x25, 0x92, 0x53, 0x0d, 0xcc, + 0xb1, 0x70, 0x2e, 0xef, 0xd4, 0x15, 0x4b, 0x8a, 0xf7, 0x36, + 0x68, 0xa9, 0x1b, 0xda, 0x84, 0x45, 0x38, 0xf9, 0xa7, 0x66, + 0x5d, 0x9c, 0xc2, 0x03, 0x7e, 0xbf, 0xe1, 0x20, 0x97, 0x56, + 0x08, 0xc9, 0xb4, 0x75, 0x2b, 0xea, 0xd1, 0x10, 0x4e, 0x8f, + 0xf2, 0x33, 0x6d, 0xac, 0x00, 0xc2, 0x99, 0x5b, 0x2f, 0xed, + 0xb6, 0x74, 0x5e, 0x9c, 0xc7, 0x05, 0x71, 0xb3, 0xe8, 0x2a, + 0xbc, 0x7e, 0x25, 0xe7, 0x93, 0x51, 0x0a, 0xc8, 0xe2, 0x20, + 0x7b, 0xb9, 0xcd, 0x0f, 0x54, 0x96, 0x65, 0xa7, 0xfc, 0x3e, + 0x4a, 0x88, 0xd3, 0x11, 0x3b, 0xf9, 0xa2, 0x60, 0x14, 0xd6, + 0x8d, 0x4f, 0xd9, 0x1b, 0x40, 0x82, 0xf6, 0x34, 0x6f, 0xad, + 0x87, 0x45, 0x1e, 0xdc, 0xa8, 0x6a, 0x31, 0xf3, 0xca, 0x08, + 0x53, 0x91, 0xe5, 0x27, 0x7c, 0xbe, 0x94, 0x56, 0x0d, 0xcf, + 0xbb, 0x79, 0x22, 0xe0, 0x76, 0xb4, 0xef, 0x2d, 0x59, 0x9b, + 0xc0, 0x02, 0x28, 0xea, 0xb1, 0x73, 0x07, 0xc5, 0x9e, 0x5c, + 0xaf, 0x6d, 0x36, 0xf4, 0x80, 0x42, 0x19, 0xdb, 0xf1, 0x33, + 0x68, 0xaa, 0xde, 0x1c, 0x47, 0x85, 0x13, 0xd1, 0x8a, 0x48, + 0x3c, 0xfe, 0xa5, 0x67, 0x4d, 0x8f, 0xd4, 0x16, 0x62, 0xa0, + 0xfb, 0x39, 0x89, 0x4b, 0x10, 0xd2, 0xa6, 0x64, 0x3f, 0xfd, + 0xd7, 0x15, 0x4e, 0x8c, 0xf8, 0x3a, 0x61, 0xa3, 0x35, 0xf7, + 0xac, 0x6e, 0x1a, 0xd8, 0x83, 0x41, 0x6b, 0xa9, 0xf2, 0x30, + 0x44, 0x86, 0xdd, 0x1f, 0xec, 0x2e, 0x75, 0xb7, 0xc3, 0x01, + 0x5a, 0x98, 0xb2, 0x70, 0x2b, 0xe9, 0x9d, 0x5f, 0x04, 0xc6, + 0x50, 0x92, 0xc9, 0x0b, 0x7f, 0xbd, 0xe6, 0x24, 0x0e, 0xcc, + 0x97, 0x55, 0x21, 0xe3, 0xb8, 0x7a, 0x43, 0x81, 0xda, 0x18, + 0x6c, 0xae, 0xf5, 0x37, 0x1d, 0xdf, 0x84, 0x46, 0x32, 0xf0, + 0xab, 0x69, 0xff, 0x3d, 0x66, 0xa4, 0xd0, 0x12, 0x49, 0x8b, + 0xa1, 0x63, 0x38, 0xfa, 0x8e, 0x4c, 0x17, 0xd5, 0x26, 0xe4, + 0xbf, 0x7d, 0x09, 0xcb, 0x90, 0x52, 0x78, 0xba, 0xe1, 0x23, + 0x57, 0x95, 0xce, 0x0c, 0x9a, 0x58, 0x03, 0xc1, 0xb5, 0x77, + 0x2c, 0xee, 0xc4, 0x06, 0x5d, 0x9f, 0xeb, 0x29, 0x72, 0xb0, + 0x00, 0xc3, 0x9b, 0x58, 0x2b, 0xe8, 0xb0, 0x73, 0x56, 0x95, + 0xcd, 0x0e, 0x7d, 0xbe, 0xe6, 0x25, 0xac, 0x6f, 0x37, 0xf4, + 0x87, 0x44, 0x1c, 0xdf, 0xfa, 0x39, 0x61, 0xa2, 0xd1, 0x12, + 0x4a, 0x89, 0x45, 0x86, 0xde, 0x1d, 0x6e, 0xad, 0xf5, 0x36, + 0x13, 0xd0, 0x88, 0x4b, 0x38, 0xfb, 0xa3, 0x60, 0xe9, 0x2a, + 0x72, 0xb1, 0xc2, 0x01, 0x59, 0x9a, 0xbf, 0x7c, 0x24, 0xe7, + 0x94, 0x57, 0x0f, 0xcc, 0x8a, 0x49, 0x11, 0xd2, 0xa1, 0x62, + 0x3a, 0xf9, 0xdc, 0x1f, 0x47, 0x84, 0xf7, 0x34, 0x6c, 0xaf, + 0x26, 0xe5, 0xbd, 0x7e, 0x0d, 0xce, 0x96, 0x55, 0x70, 0xb3, + 0xeb, 0x28, 0x5b, 0x98, 0xc0, 0x03, 0xcf, 0x0c, 0x54, 0x97, + 0xe4, 0x27, 0x7f, 0xbc, 0x99, 0x5a, 0x02, 0xc1, 0xb2, 0x71, + 0x29, 0xea, 0x63, 0xa0, 0xf8, 0x3b, 0x48, 0x8b, 0xd3, 0x10, + 0x35, 0xf6, 0xae, 0x6d, 0x1e, 0xdd, 0x85, 0x46, 0x09, 0xca, + 0x92, 0x51, 0x22, 0xe1, 0xb9, 0x7a, 0x5f, 0x9c, 0xc4, 0x07, + 0x74, 0xb7, 0xef, 0x2c, 0xa5, 0x66, 0x3e, 0xfd, 0x8e, 0x4d, + 0x15, 0xd6, 0xf3, 0x30, 0x68, 0xab, 0xd8, 0x1b, 0x43, 0x80, + 0x4c, 0x8f, 0xd7, 0x14, 0x67, 0xa4, 0xfc, 0x3f, 0x1a, 0xd9, + 0x81, 0x42, 0x31, 0xf2, 0xaa, 0x69, 0xe0, 0x23, 0x7b, 0xb8, + 0xcb, 0x08, 0x50, 0x93, 0xb6, 0x75, 0x2d, 0xee, 0x9d, 0x5e, + 0x06, 0xc5, 0x83, 0x40, 0x18, 0xdb, 0xa8, 0x6b, 0x33, 0xf0, + 0xd5, 0x16, 0x4e, 0x8d, 0xfe, 0x3d, 0x65, 0xa6, 0x2f, 0xec, + 0xb4, 0x77, 0x04, 0xc7, 0x9f, 0x5c, 0x79, 0xba, 0xe2, 0x21, + 0x52, 0x91, 0xc9, 0x0a, 0xc6, 0x05, 0x5d, 0x9e, 0xed, 0x2e, + 0x76, 0xb5, 0x90, 0x53, 0x0b, 0xc8, 0xbb, 0x78, 0x20, 0xe3, + 0x6a, 0xa9, 0xf1, 0x32, 0x41, 0x82, 0xda, 0x19, 0x3c, 0xff, + 0xa7, 0x64, 0x17, 0xd4, 0x8c, 0x4f, 0x00, 0xc4, 0x95, 0x51, + 0x37, 0xf3, 0xa2, 0x66, 0x6e, 0xaa, 0xfb, 0x3f, 0x59, 0x9d, + 0xcc, 0x08, 0xdc, 0x18, 0x49, 0x8d, 0xeb, 0x2f, 0x7e, 0xba, + 0xb2, 0x76, 0x27, 0xe3, 0x85, 0x41, 0x10, 0xd4, 0xa5, 0x61, + 0x30, 0xf4, 0x92, 0x56, 0x07, 0xc3, 0xcb, 0x0f, 0x5e, 0x9a, + 0xfc, 0x38, 0x69, 0xad, 0x79, 0xbd, 0xec, 0x28, 0x4e, 0x8a, + 0xdb, 0x1f, 0x17, 0xd3, 0x82, 0x46, 0x20, 0xe4, 0xb5, 0x71, + 0x57, 0x93, 0xc2, 0x06, 0x60, 0xa4, 0xf5, 0x31, 0x39, 0xfd, + 0xac, 0x68, 0x0e, 0xca, 0x9b, 0x5f, 0x8b, 0x4f, 0x1e, 0xda, + 0xbc, 0x78, 0x29, 0xed, 0xe5, 0x21, 0x70, 0xb4, 0xd2, 0x16, + 0x47, 0x83, 0xf2, 0x36, 0x67, 0xa3, 0xc5, 0x01, 0x50, 0x94, + 0x9c, 0x58, 0x09, 0xcd, 0xab, 0x6f, 0x3e, 0xfa, 0x2e, 0xea, + 0xbb, 0x7f, 0x19, 0xdd, 0x8c, 0x48, 0x40, 0x84, 0xd5, 0x11, + 0x77, 0xb3, 0xe2, 0x26, 0xae, 0x6a, 0x3b, 0xff, 0x99, 0x5d, + 0x0c, 0xc8, 0xc0, 0x04, 0x55, 0x91, 0xf7, 0x33, 0x62, 0xa6, + 0x72, 0xb6, 0xe7, 0x23, 0x45, 0x81, 0xd0, 0x14, 0x1c, 0xd8, + 0x89, 0x4d, 0x2b, 0xef, 0xbe, 0x7a, 0x0b, 0xcf, 0x9e, 0x5a, + 0x3c, 0xf8, 0xa9, 0x6d, 0x65, 0xa1, 0xf0, 0x34, 0x52, 0x96, + 0xc7, 0x03, 0xd7, 0x13, 0x42, 0x86, 0xe0, 0x24, 0x75, 0xb1, + 0xb9, 0x7d, 0x2c, 0xe8, 0x8e, 0x4a, 0x1b, 0xdf, 0xf9, 0x3d, + 0x6c, 0xa8, 0xce, 0x0a, 0x5b, 0x9f, 0x97, 0x53, 0x02, 0xc6, + 0xa0, 0x64, 0x35, 0xf1, 0x25, 0xe1, 0xb0, 0x74, 0x12, 0xd6, + 0x87, 0x43, 0x4b, 0x8f, 0xde, 0x1a, 0x7c, 0xb8, 0xe9, 0x2d, + 0x5c, 0x98, 0xc9, 0x0d, 0x6b, 0xaf, 0xfe, 0x3a, 0x32, 0xf6, + 0xa7, 0x63, 0x05, 0xc1, 0x90, 0x54, 0x80, 0x44, 0x15, 0xd1, + 0xb7, 0x73, 0x22, 0xe6, 0xee, 0x2a, 0x7b, 0xbf, 0xd9, 0x1d, + 0x4c, 0x88, 0x00, 0xc5, 0x97, 0x52, 0x33, 0xf6, 0xa4, 0x61, + 0x66, 0xa3, 0xf1, 0x34, 0x55, 0x90, 0xc2, 0x07, 0xcc, 0x09, + 0x5b, 0x9e, 0xff, 0x3a, 0x68, 0xad, 0xaa, 0x6f, 0x3d, 0xf8, + 0x99, 0x5c, 0x0e, 0xcb, 0x85, 0x40, 0x12, 0xd7, 0xb6, 0x73, + 0x21, 0xe4, 0xe3, 0x26, 0x74, 0xb1, 0xd0, 0x15, 0x47, 0x82, + 0x49, 0x8c, 0xde, 0x1b, 0x7a, 0xbf, 0xed, 0x28, 0x2f, 0xea, + 0xb8, 0x7d, 0x1c, 0xd9, 0x8b, 0x4e, 0x17, 0xd2, 0x80, 0x45, + 0x24, 0xe1, 0xb3, 0x76, 0x71, 0xb4, 0xe6, 0x23, 0x42, 0x87, + 0xd5, 0x10, 0xdb, 0x1e, 0x4c, 0x89, 0xe8, 0x2d, 0x7f, 0xba, + 0xbd, 0x78, 0x2a, 0xef, 0x8e, 0x4b, 0x19, 0xdc, 0x92, 0x57, + 0x05, 0xc0, 0xa1, 0x64, 0x36, 0xf3, 0xf4, 0x31, 0x63, 0xa6, + 0xc7, 0x02, 0x50, 0x95, 0x5e, 0x9b, 0xc9, 0x0c, 0x6d, 0xa8, + 0xfa, 0x3f, 0x38, 0xfd, 0xaf, 0x6a, 0x0b, 0xce, 0x9c, 0x59, + 0x2e, 0xeb, 0xb9, 0x7c, 0x1d, 0xd8, 0x8a, 0x4f, 0x48, 0x8d, + 0xdf, 0x1a, 0x7b, 0xbe, 0xec, 0x29, 0xe2, 0x27, 0x75, 0xb0, + 0xd1, 0x14, 0x46, 0x83, 0x84, 0x41, 0x13, 0xd6, 0xb7, 0x72, + 0x20, 0xe5, 0xab, 0x6e, 0x3c, 0xf9, 0x98, 0x5d, 0x0f, 0xca, + 0xcd, 0x08, 0x5a, 0x9f, 0xfe, 0x3b, 0x69, 0xac, 0x67, 0xa2, + 0xf0, 0x35, 0x54, 0x91, 0xc3, 0x06, 0x01, 0xc4, 0x96, 0x53, + 0x32, 0xf7, 0xa5, 0x60, 0x39, 0xfc, 0xae, 0x6b, 0x0a, 0xcf, + 0x9d, 0x58, 0x5f, 0x9a, 0xc8, 0x0d, 0x6c, 0xa9, 0xfb, 0x3e, + 0xf5, 0x30, 0x62, 0xa7, 0xc6, 0x03, 0x51, 0x94, 0x93, 0x56, + 0x04, 0xc1, 0xa0, 0x65, 0x37, 0xf2, 0xbc, 0x79, 0x2b, 0xee, + 0x8f, 0x4a, 0x18, 0xdd, 0xda, 0x1f, 0x4d, 0x88, 0xe9, 0x2c, + 0x7e, 0xbb, 0x70, 0xb5, 0xe7, 0x22, 0x43, 0x86, 0xd4, 0x11, + 0x16, 0xd3, 0x81, 0x44, 0x25, 0xe0, 0xb2, 0x77, 0x00, 0xc6, + 0x91, 0x57, 0x3f, 0xf9, 0xae, 0x68, 0x7e, 0xb8, 0xef, 0x29, + 0x41, 0x87, 0xd0, 0x16, 0xfc, 0x3a, 0x6d, 0xab, 0xc3, 0x05, + 0x52, 0x94, 0x82, 0x44, 0x13, 0xd5, 0xbd, 0x7b, 0x2c, 0xea, + 0xe5, 0x23, 0x74, 0xb2, 0xda, 0x1c, 0x4b, 0x8d, 0x9b, 0x5d, + 0x0a, 0xcc, 0xa4, 0x62, 0x35, 0xf3, 0x19, 0xdf, 0x88, 0x4e, + 0x26, 0xe0, 0xb7, 0x71, 0x67, 0xa1, 0xf6, 0x30, 0x58, 0x9e, + 0xc9, 0x0f, 0xd7, 0x11, 0x46, 0x80, 0xe8, 0x2e, 0x79, 0xbf, + 0xa9, 0x6f, 0x38, 0xfe, 0x96, 0x50, 0x07, 0xc1, 0x2b, 0xed, + 0xba, 0x7c, 0x14, 0xd2, 0x85, 0x43, 0x55, 0x93, 0xc4, 0x02, + 0x6a, 0xac, 0xfb, 0x3d, 0x32, 0xf4, 0xa3, 0x65, 0x0d, 0xcb, + 0x9c, 0x5a, 0x4c, 0x8a, 0xdd, 0x1b, 0x73, 0xb5, 0xe2, 0x24, + 0xce, 0x08, 0x5f, 0x99, 0xf1, 0x37, 0x60, 0xa6, 0xb0, 0x76, + 0x21, 0xe7, 0x8f, 0x49, 0x1e, 0xd8, 0xb3, 0x75, 0x22, 0xe4, + 0x8c, 0x4a, 0x1d, 0xdb, 0xcd, 0x0b, 0x5c, 0x9a, 0xf2, 0x34, + 0x63, 0xa5, 0x4f, 0x89, 0xde, 0x18, 0x70, 0xb6, 0xe1, 0x27, + 0x31, 0xf7, 0xa0, 0x66, 0x0e, 0xc8, 0x9f, 0x59, 0x56, 0x90, + 0xc7, 0x01, 0x69, 0xaf, 0xf8, 0x3e, 0x28, 0xee, 0xb9, 0x7f, + 0x17, 0xd1, 0x86, 0x40, 0xaa, 0x6c, 0x3b, 0xfd, 0x95, 0x53, + 0x04, 0xc2, 0xd4, 0x12, 0x45, 0x83, 0xeb, 0x2d, 0x7a, 0xbc, + 0x64, 0xa2, 0xf5, 0x33, 0x5b, 0x9d, 0xca, 0x0c, 0x1a, 0xdc, + 0x8b, 0x4d, 0x25, 0xe3, 0xb4, 0x72, 0x98, 0x5e, 0x09, 0xcf, + 0xa7, 0x61, 0x36, 0xf0, 0xe6, 0x20, 0x77, 0xb1, 0xd9, 0x1f, + 0x48, 0x8e, 0x81, 0x47, 0x10, 0xd6, 0xbe, 0x78, 0x2f, 0xe9, + 0xff, 0x39, 0x6e, 0xa8, 0xc0, 0x06, 0x51, 0x97, 0x7d, 0xbb, + 0xec, 0x2a, 0x42, 0x84, 0xd3, 0x15, 0x03, 0xc5, 0x92, 0x54, + 0x3c, 0xfa, 0xad, 0x6b, 0x00, 0xc7, 0x93, 0x54, 0x3b, 0xfc, + 0xa8, 0x6f, 0x76, 0xb1, 0xe5, 0x22, 0x4d, 0x8a, 0xde, 0x19, + 0xec, 0x2b, 0x7f, 0xb8, 0xd7, 0x10, 0x44, 0x83, 0x9a, 0x5d, + 0x09, 0xce, 0xa1, 0x66, 0x32, 0xf5, 0xc5, 0x02, 0x56, 0x91, + 0xfe, 0x39, 0x6d, 0xaa, 0xb3, 0x74, 0x20, 0xe7, 0x88, 0x4f, + 0x1b, 0xdc, 0x29, 0xee, 0xba, 0x7d, 0x12, 0xd5, 0x81, 0x46, + 0x5f, 0x98, 0xcc, 0x0b, 0x64, 0xa3, 0xf7, 0x30, 0x97, 0x50, + 0x04, 0xc3, 0xac, 0x6b, 0x3f, 0xf8, 0xe1, 0x26, 0x72, 0xb5, + 0xda, 0x1d, 0x49, 0x8e, 0x7b, 0xbc, 0xe8, 0x2f, 0x40, 0x87, + 0xd3, 0x14, 0x0d, 0xca, 0x9e, 0x59, 0x36, 0xf1, 0xa5, 0x62, + 0x52, 0x95, 0xc1, 0x06, 0x69, 0xae, 0xfa, 0x3d, 0x24, 0xe3, + 0xb7, 0x70, 0x1f, 0xd8, 0x8c, 0x4b, 0xbe, 0x79, 0x2d, 0xea, + 0x85, 0x42, 0x16, 0xd1, 0xc8, 0x0f, 0x5b, 0x9c, 0xf3, 0x34, + 0x60, 0xa7, 0x33, 0xf4, 0xa0, 0x67, 0x08, 0xcf, 0x9b, 0x5c, + 0x45, 0x82, 0xd6, 0x11, 0x7e, 0xb9, 0xed, 0x2a, 0xdf, 0x18, + 0x4c, 0x8b, 0xe4, 0x23, 0x77, 0xb0, 0xa9, 0x6e, 0x3a, 0xfd, + 0x92, 0x55, 0x01, 0xc6, 0xf6, 0x31, 0x65, 0xa2, 0xcd, 0x0a, + 0x5e, 0x99, 0x80, 0x47, 0x13, 0xd4, 0xbb, 0x7c, 0x28, 0xef, + 0x1a, 0xdd, 0x89, 0x4e, 0x21, 0xe6, 0xb2, 0x75, 0x6c, 0xab, + 0xff, 0x38, 0x57, 0x90, 0xc4, 0x03, 0xa4, 0x63, 0x37, 0xf0, + 0x9f, 0x58, 0x0c, 0xcb, 0xd2, 0x15, 0x41, 0x86, 0xe9, 0x2e, + 0x7a, 0xbd, 0x48, 0x8f, 0xdb, 0x1c, 0x73, 0xb4, 0xe0, 0x27, + 0x3e, 0xf9, 0xad, 0x6a, 0x05, 0xc2, 0x96, 0x51, 0x61, 0xa6, + 0xf2, 0x35, 0x5a, 0x9d, 0xc9, 0x0e, 0x17, 0xd0, 0x84, 0x43, + 0x2c, 0xeb, 0xbf, 0x78, 0x8d, 0x4a, 0x1e, 0xd9, 0xb6, 0x71, + 0x25, 0xe2, 0xfb, 0x3c, 0x68, 0xaf, 0xc0, 0x07, 0x53, 0x94, + 0x00, 0xc8, 0x8d, 0x45, 0x07, 0xcf, 0x8a, 0x42, 0x0e, 0xc6, + 0x83, 0x4b, 0x09, 0xc1, 0x84, 0x4c, 0x1c, 0xd4, 0x91, 0x59, + 0x1b, 0xd3, 0x96, 0x5e, 0x12, 0xda, 0x9f, 0x57, 0x15, 0xdd, + 0x98, 0x50, 0x38, 0xf0, 0xb5, 0x7d, 0x3f, 0xf7, 0xb2, 0x7a, + 0x36, 0xfe, 0xbb, 0x73, 0x31, 0xf9, 0xbc, 0x74, 0x24, 0xec, + 0xa9, 0x61, 0x23, 0xeb, 0xae, 0x66, 0x2a, 0xe2, 0xa7, 0x6f, + 0x2d, 0xe5, 0xa0, 0x68, 0x70, 0xb8, 0xfd, 0x35, 0x77, 0xbf, + 0xfa, 0x32, 0x7e, 0xb6, 0xf3, 0x3b, 0x79, 0xb1, 0xf4, 0x3c, + 0x6c, 0xa4, 0xe1, 0x29, 0x6b, 0xa3, 0xe6, 0x2e, 0x62, 0xaa, + 0xef, 0x27, 0x65, 0xad, 0xe8, 0x20, 0x48, 0x80, 0xc5, 0x0d, + 0x4f, 0x87, 0xc2, 0x0a, 0x46, 0x8e, 0xcb, 0x03, 0x41, 0x89, + 0xcc, 0x04, 0x54, 0x9c, 0xd9, 0x11, 0x53, 0x9b, 0xde, 0x16, + 0x5a, 0x92, 0xd7, 0x1f, 0x5d, 0x95, 0xd0, 0x18, 0xe0, 0x28, + 0x6d, 0xa5, 0xe7, 0x2f, 0x6a, 0xa2, 0xee, 0x26, 0x63, 0xab, + 0xe9, 0x21, 0x64, 0xac, 0xfc, 0x34, 0x71, 0xb9, 0xfb, 0x33, + 0x76, 0xbe, 0xf2, 0x3a, 0x7f, 0xb7, 0xf5, 0x3d, 0x78, 0xb0, + 0xd8, 0x10, 0x55, 0x9d, 0xdf, 0x17, 0x52, 0x9a, 0xd6, 0x1e, + 0x5b, 0x93, 0xd1, 0x19, 0x5c, 0x94, 0xc4, 0x0c, 0x49, 0x81, + 0xc3, 0x0b, 0x4e, 0x86, 0xca, 0x02, 0x47, 0x8f, 0xcd, 0x05, + 0x40, 0x88, 0x90, 0x58, 0x1d, 0xd5, 0x97, 0x5f, 0x1a, 0xd2, + 0x9e, 0x56, 0x13, 0xdb, 0x99, 0x51, 0x14, 0xdc, 0x8c, 0x44, + 0x01, 0xc9, 0x8b, 0x43, 0x06, 0xce, 0x82, 0x4a, 0x0f, 0xc7, + 0x85, 0x4d, 0x08, 0xc0, 0xa8, 0x60, 0x25, 0xed, 0xaf, 0x67, + 0x22, 0xea, 0xa6, 0x6e, 0x2b, 0xe3, 0xa1, 0x69, 0x2c, 0xe4, + 0xb4, 0x7c, 0x39, 0xf1, 0xb3, 0x7b, 0x3e, 0xf6, 0xba, 0x72, + 0x37, 0xff, 0xbd, 0x75, 0x30, 0xf8, 0x00, 0xc9, 0x8f, 0x46, + 0x03, 0xca, 0x8c, 0x45, 0x06, 0xcf, 0x89, 0x40, 0x05, 0xcc, + 0x8a, 0x43, 0x0c, 0xc5, 0x83, 0x4a, 0x0f, 0xc6, 0x80, 0x49, + 0x0a, 0xc3, 0x85, 0x4c, 0x09, 0xc0, 0x86, 0x4f, 0x18, 0xd1, + 0x97, 0x5e, 0x1b, 0xd2, 0x94, 0x5d, 0x1e, 0xd7, 0x91, 0x58, + 0x1d, 0xd4, 0x92, 0x5b, 0x14, 0xdd, 0x9b, 0x52, 0x17, 0xde, + 0x98, 0x51, 0x12, 0xdb, 0x9d, 0x54, 0x11, 0xd8, 0x9e, 0x57, + 0x30, 0xf9, 0xbf, 0x76, 0x33, 0xfa, 0xbc, 0x75, 0x36, 0xff, + 0xb9, 0x70, 0x35, 0xfc, 0xba, 0x73, 0x3c, 0xf5, 0xb3, 0x7a, + 0x3f, 0xf6, 0xb0, 0x79, 0x3a, 0xf3, 0xb5, 0x7c, 0x39, 0xf0, + 0xb6, 0x7f, 0x28, 0xe1, 0xa7, 0x6e, 0x2b, 0xe2, 0xa4, 0x6d, + 0x2e, 0xe7, 0xa1, 0x68, 0x2d, 0xe4, 0xa2, 0x6b, 0x24, 0xed, + 0xab, 0x62, 0x27, 0xee, 0xa8, 0x61, 0x22, 0xeb, 0xad, 0x64, + 0x21, 0xe8, 0xae, 0x67, 0x60, 0xa9, 0xef, 0x26, 0x63, 0xaa, + 0xec, 0x25, 0x66, 0xaf, 0xe9, 0x20, 0x65, 0xac, 0xea, 0x23, + 0x6c, 0xa5, 0xe3, 0x2a, 0x6f, 0xa6, 0xe0, 0x29, 0x6a, 0xa3, + 0xe5, 0x2c, 0x69, 0xa0, 0xe6, 0x2f, 0x78, 0xb1, 0xf7, 0x3e, + 0x7b, 0xb2, 0xf4, 0x3d, 0x7e, 0xb7, 0xf1, 0x38, 0x7d, 0xb4, + 0xf2, 0x3b, 0x74, 0xbd, 0xfb, 0x32, 0x77, 0xbe, 0xf8, 0x31, + 0x72, 0xbb, 0xfd, 0x34, 0x71, 0xb8, 0xfe, 0x37, 0x50, 0x99, + 0xdf, 0x16, 0x53, 0x9a, 0xdc, 0x15, 0x56, 0x9f, 0xd9, 0x10, + 0x55, 0x9c, 0xda, 0x13, 0x5c, 0x95, 0xd3, 0x1a, 0x5f, 0x96, + 0xd0, 0x19, 0x5a, 0x93, 0xd5, 0x1c, 0x59, 0x90, 0xd6, 0x1f, + 0x48, 0x81, 0xc7, 0x0e, 0x4b, 0x82, 0xc4, 0x0d, 0x4e, 0x87, + 0xc1, 0x08, 0x4d, 0x84, 0xc2, 0x0b, 0x44, 0x8d, 0xcb, 0x02, + 0x47, 0x8e, 0xc8, 0x01, 0x42, 0x8b, 0xcd, 0x04, 0x41, 0x88, + 0xce, 0x07, 0x00, 0xca, 0x89, 0x43, 0x0f, 0xc5, 0x86, 0x4c, + 0x1e, 0xd4, 0x97, 0x5d, 0x11, 0xdb, 0x98, 0x52, 0x3c, 0xf6, + 0xb5, 0x7f, 0x33, 0xf9, 0xba, 0x70, 0x22, 0xe8, 0xab, 0x61, + 0x2d, 0xe7, 0xa4, 0x6e, 0x78, 0xb2, 0xf1, 0x3b, 0x77, 0xbd, + 0xfe, 0x34, 0x66, 0xac, 0xef, 0x25, 0x69, 0xa3, 0xe0, 0x2a, + 0x44, 0x8e, 0xcd, 0x07, 0x4b, 0x81, 0xc2, 0x08, 0x5a, 0x90, + 0xd3, 0x19, 0x55, 0x9f, 0xdc, 0x16, 0xf0, 0x3a, 0x79, 0xb3, + 0xff, 0x35, 0x76, 0xbc, 0xee, 0x24, 0x67, 0xad, 0xe1, 0x2b, + 0x68, 0xa2, 0xcc, 0x06, 0x45, 0x8f, 0xc3, 0x09, 0x4a, 0x80, + 0xd2, 0x18, 0x5b, 0x91, 0xdd, 0x17, 0x54, 0x9e, 0x88, 0x42, + 0x01, 0xcb, 0x87, 0x4d, 0x0e, 0xc4, 0x96, 0x5c, 0x1f, 0xd5, + 0x99, 0x53, 0x10, 0xda, 0xb4, 0x7e, 0x3d, 0xf7, 0xbb, 0x71, + 0x32, 0xf8, 0xaa, 0x60, 0x23, 0xe9, 0xa5, 0x6f, 0x2c, 0xe6, + 0xfd, 0x37, 0x74, 0xbe, 0xf2, 0x38, 0x7b, 0xb1, 0xe3, 0x29, + 0x6a, 0xa0, 0xec, 0x26, 0x65, 0xaf, 0xc1, 0x0b, 0x48, 0x82, + 0xce, 0x04, 0x47, 0x8d, 0xdf, 0x15, 0x56, 0x9c, 0xd0, 0x1a, + 0x59, 0x93, 0x85, 0x4f, 0x0c, 0xc6, 0x8a, 0x40, 0x03, 0xc9, + 0x9b, 0x51, 0x12, 0xd8, 0x94, 0x5e, 0x1d, 0xd7, 0xb9, 0x73, + 0x30, 0xfa, 0xb6, 0x7c, 0x3f, 0xf5, 0xa7, 0x6d, 0x2e, 0xe4, + 0xa8, 0x62, 0x21, 0xeb, 0x0d, 0xc7, 0x84, 0x4e, 0x02, 0xc8, + 0x8b, 0x41, 0x13, 0xd9, 0x9a, 0x50, 0x1c, 0xd6, 0x95, 0x5f, + 0x31, 0xfb, 0xb8, 0x72, 0x3e, 0xf4, 0xb7, 0x7d, 0x2f, 0xe5, + 0xa6, 0x6c, 0x20, 0xea, 0xa9, 0x63, 0x75, 0xbf, 0xfc, 0x36, + 0x7a, 0xb0, 0xf3, 0x39, 0x6b, 0xa1, 0xe2, 0x28, 0x64, 0xae, + 0xed, 0x27, 0x49, 0x83, 0xc0, 0x0a, 0x46, 0x8c, 0xcf, 0x05, + 0x57, 0x9d, 0xde, 0x14, 0x58, 0x92, 0xd1, 0x1b, 0x00, 0xcb, + 0x8b, 0x40, 0x0b, 0xc0, 0x80, 0x4b, 0x16, 0xdd, 0x9d, 0x56, + 0x1d, 0xd6, 0x96, 0x5d, 0x2c, 0xe7, 0xa7, 0x6c, 0x27, 0xec, + 0xac, 0x67, 0x3a, 0xf1, 0xb1, 0x7a, 0x31, 0xfa, 0xba, 0x71, + 0x58, 0x93, 0xd3, 0x18, 0x53, 0x98, 0xd8, 0x13, 0x4e, 0x85, + 0xc5, 0x0e, 0x45, 0x8e, 0xce, 0x05, 0x74, 0xbf, 0xff, 0x34, + 0x7f, 0xb4, 0xf4, 0x3f, 0x62, 0xa9, 0xe9, 0x22, 0x69, 0xa2, + 0xe2, 0x29, 0xb0, 0x7b, 0x3b, 0xf0, 0xbb, 0x70, 0x30, 0xfb, + 0xa6, 0x6d, 0x2d, 0xe6, 0xad, 0x66, 0x26, 0xed, 0x9c, 0x57, + 0x17, 0xdc, 0x97, 0x5c, 0x1c, 0xd7, 0x8a, 0x41, 0x01, 0xca, + 0x81, 0x4a, 0x0a, 0xc1, 0xe8, 0x23, 0x63, 0xa8, 0xe3, 0x28, + 0x68, 0xa3, 0xfe, 0x35, 0x75, 0xbe, 0xf5, 0x3e, 0x7e, 0xb5, + 0xc4, 0x0f, 0x4f, 0x84, 0xcf, 0x04, 0x44, 0x8f, 0xd2, 0x19, + 0x59, 0x92, 0xd9, 0x12, 0x52, 0x99, 0x7d, 0xb6, 0xf6, 0x3d, + 0x76, 0xbd, 0xfd, 0x36, 0x6b, 0xa0, 0xe0, 0x2b, 0x60, 0xab, + 0xeb, 0x20, 0x51, 0x9a, 0xda, 0x11, 0x5a, 0x91, 0xd1, 0x1a, + 0x47, 0x8c, 0xcc, 0x07, 0x4c, 0x87, 0xc7, 0x0c, 0x25, 0xee, + 0xae, 0x65, 0x2e, 0xe5, 0xa5, 0x6e, 0x33, 0xf8, 0xb8, 0x73, + 0x38, 0xf3, 0xb3, 0x78, 0x09, 0xc2, 0x82, 0x49, 0x02, 0xc9, + 0x89, 0x42, 0x1f, 0xd4, 0x94, 0x5f, 0x14, 0xdf, 0x9f, 0x54, + 0xcd, 0x06, 0x46, 0x8d, 0xc6, 0x0d, 0x4d, 0x86, 0xdb, 0x10, + 0x50, 0x9b, 0xd0, 0x1b, 0x5b, 0x90, 0xe1, 0x2a, 0x6a, 0xa1, + 0xea, 0x21, 0x61, 0xaa, 0xf7, 0x3c, 0x7c, 0xb7, 0xfc, 0x37, + 0x77, 0xbc, 0x95, 0x5e, 0x1e, 0xd5, 0x9e, 0x55, 0x15, 0xde, + 0x83, 0x48, 0x08, 0xc3, 0x88, 0x43, 0x03, 0xc8, 0xb9, 0x72, + 0x32, 0xf9, 0xb2, 0x79, 0x39, 0xf2, 0xaf, 0x64, 0x24, 0xef, + 0xa4, 0x6f, 0x2f, 0xe4, 0x00, 0xcc, 0x85, 0x49, 0x17, 0xdb, + 0x92, 0x5e, 0x2e, 0xe2, 0xab, 0x67, 0x39, 0xf5, 0xbc, 0x70, + 0x5c, 0x90, 0xd9, 0x15, 0x4b, 0x87, 0xce, 0x02, 0x72, 0xbe, + 0xf7, 0x3b, 0x65, 0xa9, 0xe0, 0x2c, 0xb8, 0x74, 0x3d, 0xf1, + 0xaf, 0x63, 0x2a, 0xe6, 0x96, 0x5a, 0x13, 0xdf, 0x81, 0x4d, + 0x04, 0xc8, 0xe4, 0x28, 0x61, 0xad, 0xf3, 0x3f, 0x76, 0xba, + 0xca, 0x06, 0x4f, 0x83, 0xdd, 0x11, 0x58, 0x94, 0x6d, 0xa1, + 0xe8, 0x24, 0x7a, 0xb6, 0xff, 0x33, 0x43, 0x8f, 0xc6, 0x0a, + 0x54, 0x98, 0xd1, 0x1d, 0x31, 0xfd, 0xb4, 0x78, 0x26, 0xea, + 0xa3, 0x6f, 0x1f, 0xd3, 0x9a, 0x56, 0x08, 0xc4, 0x8d, 0x41, + 0xd5, 0x19, 0x50, 0x9c, 0xc2, 0x0e, 0x47, 0x8b, 0xfb, 0x37, + 0x7e, 0xb2, 0xec, 0x20, 0x69, 0xa5, 0x89, 0x45, 0x0c, 0xc0, + 0x9e, 0x52, 0x1b, 0xd7, 0xa7, 0x6b, 0x22, 0xee, 0xb0, 0x7c, + 0x35, 0xf9, 0xda, 0x16, 0x5f, 0x93, 0xcd, 0x01, 0x48, 0x84, + 0xf4, 0x38, 0x71, 0xbd, 0xe3, 0x2f, 0x66, 0xaa, 0x86, 0x4a, + 0x03, 0xcf, 0x91, 0x5d, 0x14, 0xd8, 0xa8, 0x64, 0x2d, 0xe1, + 0xbf, 0x73, 0x3a, 0xf6, 0x62, 0xae, 0xe7, 0x2b, 0x75, 0xb9, + 0xf0, 0x3c, 0x4c, 0x80, 0xc9, 0x05, 0x5b, 0x97, 0xde, 0x12, + 0x3e, 0xf2, 0xbb, 0x77, 0x29, 0xe5, 0xac, 0x60, 0x10, 0xdc, + 0x95, 0x59, 0x07, 0xcb, 0x82, 0x4e, 0xb7, 0x7b, 0x32, 0xfe, + 0xa0, 0x6c, 0x25, 0xe9, 0x99, 0x55, 0x1c, 0xd0, 0x8e, 0x42, + 0x0b, 0xc7, 0xeb, 0x27, 0x6e, 0xa2, 0xfc, 0x30, 0x79, 0xb5, + 0xc5, 0x09, 0x40, 0x8c, 0xd2, 0x1e, 0x57, 0x9b, 0x0f, 0xc3, + 0x8a, 0x46, 0x18, 0xd4, 0x9d, 0x51, 0x21, 0xed, 0xa4, 0x68, + 0x36, 0xfa, 0xb3, 0x7f, 0x53, 0x9f, 0xd6, 0x1a, 0x44, 0x88, + 0xc1, 0x0d, 0x7d, 0xb1, 0xf8, 0x34, 0x6a, 0xa6, 0xef, 0x23, + 0x00, 0xcd, 0x87, 0x4a, 0x13, 0xde, 0x94, 0x59, 0x26, 0xeb, + 0xa1, 0x6c, 0x35, 0xf8, 0xb2, 0x7f, 0x4c, 0x81, 0xcb, 0x06, + 0x5f, 0x92, 0xd8, 0x15, 0x6a, 0xa7, 0xed, 0x20, 0x79, 0xb4, + 0xfe, 0x33, 0x98, 0x55, 0x1f, 0xd2, 0x8b, 0x46, 0x0c, 0xc1, + 0xbe, 0x73, 0x39, 0xf4, 0xad, 0x60, 0x2a, 0xe7, 0xd4, 0x19, + 0x53, 0x9e, 0xc7, 0x0a, 0x40, 0x8d, 0xf2, 0x3f, 0x75, 0xb8, + 0xe1, 0x2c, 0x66, 0xab, 0x2d, 0xe0, 0xaa, 0x67, 0x3e, 0xf3, + 0xb9, 0x74, 0x0b, 0xc6, 0x8c, 0x41, 0x18, 0xd5, 0x9f, 0x52, + 0x61, 0xac, 0xe6, 0x2b, 0x72, 0xbf, 0xf5, 0x38, 0x47, 0x8a, + 0xc0, 0x0d, 0x54, 0x99, 0xd3, 0x1e, 0xb5, 0x78, 0x32, 0xff, + 0xa6, 0x6b, 0x21, 0xec, 0x93, 0x5e, 0x14, 0xd9, 0x80, 0x4d, + 0x07, 0xca, 0xf9, 0x34, 0x7e, 0xb3, 0xea, 0x27, 0x6d, 0xa0, + 0xdf, 0x12, 0x58, 0x95, 0xcc, 0x01, 0x4b, 0x86, 0x5a, 0x97, + 0xdd, 0x10, 0x49, 0x84, 0xce, 0x03, 0x7c, 0xb1, 0xfb, 0x36, + 0x6f, 0xa2, 0xe8, 0x25, 0x16, 0xdb, 0x91, 0x5c, 0x05, 0xc8, + 0x82, 0x4f, 0x30, 0xfd, 0xb7, 0x7a, 0x23, 0xee, 0xa4, 0x69, + 0xc2, 0x0f, 0x45, 0x88, 0xd1, 0x1c, 0x56, 0x9b, 0xe4, 0x29, + 0x63, 0xae, 0xf7, 0x3a, 0x70, 0xbd, 0x8e, 0x43, 0x09, 0xc4, + 0x9d, 0x50, 0x1a, 0xd7, 0xa8, 0x65, 0x2f, 0xe2, 0xbb, 0x76, + 0x3c, 0xf1, 0x77, 0xba, 0xf0, 0x3d, 0x64, 0xa9, 0xe3, 0x2e, + 0x51, 0x9c, 0xd6, 0x1b, 0x42, 0x8f, 0xc5, 0x08, 0x3b, 0xf6, + 0xbc, 0x71, 0x28, 0xe5, 0xaf, 0x62, 0x1d, 0xd0, 0x9a, 0x57, + 0x0e, 0xc3, 0x89, 0x44, 0xef, 0x22, 0x68, 0xa5, 0xfc, 0x31, + 0x7b, 0xb6, 0xc9, 0x04, 0x4e, 0x83, 0xda, 0x17, 0x5d, 0x90, + 0xa3, 0x6e, 0x24, 0xe9, 0xb0, 0x7d, 0x37, 0xfa, 0x85, 0x48, + 0x02, 0xcf, 0x96, 0x5b, 0x11, 0xdc, 0x00, 0xce, 0x81, 0x4f, + 0x1f, 0xd1, 0x9e, 0x50, 0x3e, 0xf0, 0xbf, 0x71, 0x21, 0xef, + 0xa0, 0x6e, 0x7c, 0xb2, 0xfd, 0x33, 0x63, 0xad, 0xe2, 0x2c, + 0x42, 0x8c, 0xc3, 0x0d, 0x5d, 0x93, 0xdc, 0x12, 0xf8, 0x36, + 0x79, 0xb7, 0xe7, 0x29, 0x66, 0xa8, 0xc6, 0x08, 0x47, 0x89, + 0xd9, 0x17, 0x58, 0x96, 0x84, 0x4a, 0x05, 0xcb, 0x9b, 0x55, + 0x1a, 0xd4, 0xba, 0x74, 0x3b, 0xf5, 0xa5, 0x6b, 0x24, 0xea, + 0xed, 0x23, 0x6c, 0xa2, 0xf2, 0x3c, 0x73, 0xbd, 0xd3, 0x1d, + 0x52, 0x9c, 0xcc, 0x02, 0x4d, 0x83, 0x91, 0x5f, 0x10, 0xde, + 0x8e, 0x40, 0x0f, 0xc1, 0xaf, 0x61, 0x2e, 0xe0, 0xb0, 0x7e, + 0x31, 0xff, 0x15, 0xdb, 0x94, 0x5a, 0x0a, 0xc4, 0x8b, 0x45, + 0x2b, 0xe5, 0xaa, 0x64, 0x34, 0xfa, 0xb5, 0x7b, 0x69, 0xa7, + 0xe8, 0x26, 0x76, 0xb8, 0xf7, 0x39, 0x57, 0x99, 0xd6, 0x18, + 0x48, 0x86, 0xc9, 0x07, 0xc7, 0x09, 0x46, 0x88, 0xd8, 0x16, + 0x59, 0x97, 0xf9, 0x37, 0x78, 0xb6, 0xe6, 0x28, 0x67, 0xa9, + 0xbb, 0x75, 0x3a, 0xf4, 0xa4, 0x6a, 0x25, 0xeb, 0x85, 0x4b, + 0x04, 0xca, 0x9a, 0x54, 0x1b, 0xd5, 0x3f, 0xf1, 0xbe, 0x70, + 0x20, 0xee, 0xa1, 0x6f, 0x01, 0xcf, 0x80, 0x4e, 0x1e, 0xd0, + 0x9f, 0x51, 0x43, 0x8d, 0xc2, 0x0c, 0x5c, 0x92, 0xdd, 0x13, + 0x7d, 0xb3, 0xfc, 0x32, 0x62, 0xac, 0xe3, 0x2d, 0x2a, 0xe4, + 0xab, 0x65, 0x35, 0xfb, 0xb4, 0x7a, 0x14, 0xda, 0x95, 0x5b, + 0x0b, 0xc5, 0x8a, 0x44, 0x56, 0x98, 0xd7, 0x19, 0x49, 0x87, + 0xc8, 0x06, 0x68, 0xa6, 0xe9, 0x27, 0x77, 0xb9, 0xf6, 0x38, + 0xd2, 0x1c, 0x53, 0x9d, 0xcd, 0x03, 0x4c, 0x82, 0xec, 0x22, + 0x6d, 0xa3, 0xf3, 0x3d, 0x72, 0xbc, 0xae, 0x60, 0x2f, 0xe1, + 0xb1, 0x7f, 0x30, 0xfe, 0x90, 0x5e, 0x11, 0xdf, 0x8f, 0x41, + 0x0e, 0xc0, 0x00, 0xcf, 0x83, 0x4c, 0x1b, 0xd4, 0x98, 0x57, + 0x36, 0xf9, 0xb5, 0x7a, 0x2d, 0xe2, 0xae, 0x61, 0x6c, 0xa3, + 0xef, 0x20, 0x77, 0xb8, 0xf4, 0x3b, 0x5a, 0x95, 0xd9, 0x16, + 0x41, 0x8e, 0xc2, 0x0d, 0xd8, 0x17, 0x5b, 0x94, 0xc3, 0x0c, + 0x40, 0x8f, 0xee, 0x21, 0x6d, 0xa2, 0xf5, 0x3a, 0x76, 0xb9, + 0xb4, 0x7b, 0x37, 0xf8, 0xaf, 0x60, 0x2c, 0xe3, 0x82, 0x4d, + 0x01, 0xce, 0x99, 0x56, 0x1a, 0xd5, 0xad, 0x62, 0x2e, 0xe1, + 0xb6, 0x79, 0x35, 0xfa, 0x9b, 0x54, 0x18, 0xd7, 0x80, 0x4f, + 0x03, 0xcc, 0xc1, 0x0e, 0x42, 0x8d, 0xda, 0x15, 0x59, 0x96, + 0xf7, 0x38, 0x74, 0xbb, 0xec, 0x23, 0x6f, 0xa0, 0x75, 0xba, + 0xf6, 0x39, 0x6e, 0xa1, 0xed, 0x22, 0x43, 0x8c, 0xc0, 0x0f, + 0x58, 0x97, 0xdb, 0x14, 0x19, 0xd6, 0x9a, 0x55, 0x02, 0xcd, + 0x81, 0x4e, 0x2f, 0xe0, 0xac, 0x63, 0x34, 0xfb, 0xb7, 0x78, + 0x47, 0x88, 0xc4, 0x0b, 0x5c, 0x93, 0xdf, 0x10, 0x71, 0xbe, + 0xf2, 0x3d, 0x6a, 0xa5, 0xe9, 0x26, 0x2b, 0xe4, 0xa8, 0x67, + 0x30, 0xff, 0xb3, 0x7c, 0x1d, 0xd2, 0x9e, 0x51, 0x06, 0xc9, + 0x85, 0x4a, 0x9f, 0x50, 0x1c, 0xd3, 0x84, 0x4b, 0x07, 0xc8, + 0xa9, 0x66, 0x2a, 0xe5, 0xb2, 0x7d, 0x31, 0xfe, 0xf3, 0x3c, + 0x70, 0xbf, 0xe8, 0x27, 0x6b, 0xa4, 0xc5, 0x0a, 0x46, 0x89, + 0xde, 0x11, 0x5d, 0x92, 0xea, 0x25, 0x69, 0xa6, 0xf1, 0x3e, + 0x72, 0xbd, 0xdc, 0x13, 0x5f, 0x90, 0xc7, 0x08, 0x44, 0x8b, + 0x86, 0x49, 0x05, 0xca, 0x9d, 0x52, 0x1e, 0xd1, 0xb0, 0x7f, + 0x33, 0xfc, 0xab, 0x64, 0x28, 0xe7, 0x32, 0xfd, 0xb1, 0x7e, + 0x29, 0xe6, 0xaa, 0x65, 0x04, 0xcb, 0x87, 0x48, 0x1f, 0xd0, + 0x9c, 0x53, 0x5e, 0x91, 0xdd, 0x12, 0x45, 0x8a, 0xc6, 0x09, + 0x68, 0xa7, 0xeb, 0x24, 0x73, 0xbc, 0xf0, 0x3f, 0x00, 0xd0, + 0xbd, 0x6d, 0x67, 0xb7, 0xda, 0x0a, 0xce, 0x1e, 0x73, 0xa3, + 0xa9, 0x79, 0x14, 0xc4, 0x81, 0x51, 0x3c, 0xec, 0xe6, 0x36, + 0x5b, 0x8b, 0x4f, 0x9f, 0xf2, 0x22, 0x28, 0xf8, 0x95, 0x45, + 0x1f, 0xcf, 0xa2, 0x72, 0x78, 0xa8, 0xc5, 0x15, 0xd1, 0x01, + 0x6c, 0xbc, 0xb6, 0x66, 0x0b, 0xdb, 0x9e, 0x4e, 0x23, 0xf3, + 0xf9, 0x29, 0x44, 0x94, 0x50, 0x80, 0xed, 0x3d, 0x37, 0xe7, + 0x8a, 0x5a, 0x3e, 0xee, 0x83, 0x53, 0x59, 0x89, 0xe4, 0x34, + 0xf0, 0x20, 0x4d, 0x9d, 0x97, 0x47, 0x2a, 0xfa, 0xbf, 0x6f, + 0x02, 0xd2, 0xd8, 0x08, 0x65, 0xb5, 0x71, 0xa1, 0xcc, 0x1c, + 0x16, 0xc6, 0xab, 0x7b, 0x21, 0xf1, 0x9c, 0x4c, 0x46, 0x96, + 0xfb, 0x2b, 0xef, 0x3f, 0x52, 0x82, 0x88, 0x58, 0x35, 0xe5, + 0xa0, 0x70, 0x1d, 0xcd, 0xc7, 0x17, 0x7a, 0xaa, 0x6e, 0xbe, + 0xd3, 0x03, 0x09, 0xd9, 0xb4, 0x64, 0x7c, 0xac, 0xc1, 0x11, + 0x1b, 0xcb, 0xa6, 0x76, 0xb2, 0x62, 0x0f, 0xdf, 0xd5, 0x05, + 0x68, 0xb8, 0xfd, 0x2d, 0x40, 0x90, 0x9a, 0x4a, 0x27, 0xf7, + 0x33, 0xe3, 0x8e, 0x5e, 0x54, 0x84, 0xe9, 0x39, 0x63, 0xb3, + 0xde, 0x0e, 0x04, 0xd4, 0xb9, 0x69, 0xad, 0x7d, 0x10, 0xc0, + 0xca, 0x1a, 0x77, 0xa7, 0xe2, 0x32, 0x5f, 0x8f, 0x85, 0x55, + 0x38, 0xe8, 0x2c, 0xfc, 0x91, 0x41, 0x4b, 0x9b, 0xf6, 0x26, + 0x42, 0x92, 0xff, 0x2f, 0x25, 0xf5, 0x98, 0x48, 0x8c, 0x5c, + 0x31, 0xe1, 0xeb, 0x3b, 0x56, 0x86, 0xc3, 0x13, 0x7e, 0xae, + 0xa4, 0x74, 0x19, 0xc9, 0x0d, 0xdd, 0xb0, 0x60, 0x6a, 0xba, + 0xd7, 0x07, 0x5d, 0x8d, 0xe0, 0x30, 0x3a, 0xea, 0x87, 0x57, + 0x93, 0x43, 0x2e, 0xfe, 0xf4, 0x24, 0x49, 0x99, 0xdc, 0x0c, + 0x61, 0xb1, 0xbb, 0x6b, 0x06, 0xd6, 0x12, 0xc2, 0xaf, 0x7f, + 0x75, 0xa5, 0xc8, 0x18, 0x00, 0xd1, 0xbf, 0x6e, 0x63, 0xb2, + 0xdc, 0x0d, 0xc6, 0x17, 0x79, 0xa8, 0xa5, 0x74, 0x1a, 0xcb, + 0x91, 0x40, 0x2e, 0xff, 0xf2, 0x23, 0x4d, 0x9c, 0x57, 0x86, + 0xe8, 0x39, 0x34, 0xe5, 0x8b, 0x5a, 0x3f, 0xee, 0x80, 0x51, + 0x5c, 0x8d, 0xe3, 0x32, 0xf9, 0x28, 0x46, 0x97, 0x9a, 0x4b, + 0x25, 0xf4, 0xae, 0x7f, 0x11, 0xc0, 0xcd, 0x1c, 0x72, 0xa3, + 0x68, 0xb9, 0xd7, 0x06, 0x0b, 0xda, 0xb4, 0x65, 0x7e, 0xaf, + 0xc1, 0x10, 0x1d, 0xcc, 0xa2, 0x73, 0xb8, 0x69, 0x07, 0xd6, + 0xdb, 0x0a, 0x64, 0xb5, 0xef, 0x3e, 0x50, 0x81, 0x8c, 0x5d, + 0x33, 0xe2, 0x29, 0xf8, 0x96, 0x47, 0x4a, 0x9b, 0xf5, 0x24, + 0x41, 0x90, 0xfe, 0x2f, 0x22, 0xf3, 0x9d, 0x4c, 0x87, 0x56, + 0x38, 0xe9, 0xe4, 0x35, 0x5b, 0x8a, 0xd0, 0x01, 0x6f, 0xbe, + 0xb3, 0x62, 0x0c, 0xdd, 0x16, 0xc7, 0xa9, 0x78, 0x75, 0xa4, + 0xca, 0x1b, 0xfc, 0x2d, 0x43, 0x92, 0x9f, 0x4e, 0x20, 0xf1, + 0x3a, 0xeb, 0x85, 0x54, 0x59, 0x88, 0xe6, 0x37, 0x6d, 0xbc, + 0xd2, 0x03, 0x0e, 0xdf, 0xb1, 0x60, 0xab, 0x7a, 0x14, 0xc5, + 0xc8, 0x19, 0x77, 0xa6, 0xc3, 0x12, 0x7c, 0xad, 0xa0, 0x71, + 0x1f, 0xce, 0x05, 0xd4, 0xba, 0x6b, 0x66, 0xb7, 0xd9, 0x08, + 0x52, 0x83, 0xed, 0x3c, 0x31, 0xe0, 0x8e, 0x5f, 0x94, 0x45, + 0x2b, 0xfa, 0xf7, 0x26, 0x48, 0x99, 0x82, 0x53, 0x3d, 0xec, + 0xe1, 0x30, 0x5e, 0x8f, 0x44, 0x95, 0xfb, 0x2a, 0x27, 0xf6, + 0x98, 0x49, 0x13, 0xc2, 0xac, 0x7d, 0x70, 0xa1, 0xcf, 0x1e, + 0xd5, 0x04, 0x6a, 0xbb, 0xb6, 0x67, 0x09, 0xd8, 0xbd, 0x6c, + 0x02, 0xd3, 0xde, 0x0f, 0x61, 0xb0, 0x7b, 0xaa, 0xc4, 0x15, + 0x18, 0xc9, 0xa7, 0x76, 0x2c, 0xfd, 0x93, 0x42, 0x4f, 0x9e, + 0xf0, 0x21, 0xea, 0x3b, 0x55, 0x84, 0x89, 0x58, 0x36, 0xe7, + 0x00, 0xd2, 0xb9, 0x6b, 0x6f, 0xbd, 0xd6, 0x04, 0xde, 0x0c, + 0x67, 0xb5, 0xb1, 0x63, 0x08, 0xda, 0xa1, 0x73, 0x18, 0xca, + 0xce, 0x1c, 0x77, 0xa5, 0x7f, 0xad, 0xc6, 0x14, 0x10, 0xc2, + 0xa9, 0x7b, 0x5f, 0x8d, 0xe6, 0x34, 0x30, 0xe2, 0x89, 0x5b, + 0x81, 0x53, 0x38, 0xea, 0xee, 0x3c, 0x57, 0x85, 0xfe, 0x2c, + 0x47, 0x95, 0x91, 0x43, 0x28, 0xfa, 0x20, 0xf2, 0x99, 0x4b, + 0x4f, 0x9d, 0xf6, 0x24, 0xbe, 0x6c, 0x07, 0xd5, 0xd1, 0x03, + 0x68, 0xba, 0x60, 0xb2, 0xd9, 0x0b, 0x0f, 0xdd, 0xb6, 0x64, + 0x1f, 0xcd, 0xa6, 0x74, 0x70, 0xa2, 0xc9, 0x1b, 0xc1, 0x13, + 0x78, 0xaa, 0xae, 0x7c, 0x17, 0xc5, 0xe1, 0x33, 0x58, 0x8a, + 0x8e, 0x5c, 0x37, 0xe5, 0x3f, 0xed, 0x86, 0x54, 0x50, 0x82, + 0xe9, 0x3b, 0x40, 0x92, 0xf9, 0x2b, 0x2f, 0xfd, 0x96, 0x44, + 0x9e, 0x4c, 0x27, 0xf5, 0xf1, 0x23, 0x48, 0x9a, 0x61, 0xb3, + 0xd8, 0x0a, 0x0e, 0xdc, 0xb7, 0x65, 0xbf, 0x6d, 0x06, 0xd4, + 0xd0, 0x02, 0x69, 0xbb, 0xc0, 0x12, 0x79, 0xab, 0xaf, 0x7d, + 0x16, 0xc4, 0x1e, 0xcc, 0xa7, 0x75, 0x71, 0xa3, 0xc8, 0x1a, + 0x3e, 0xec, 0x87, 0x55, 0x51, 0x83, 0xe8, 0x3a, 0xe0, 0x32, + 0x59, 0x8b, 0x8f, 0x5d, 0x36, 0xe4, 0x9f, 0x4d, 0x26, 0xf4, + 0xf0, 0x22, 0x49, 0x9b, 0x41, 0x93, 0xf8, 0x2a, 0x2e, 0xfc, + 0x97, 0x45, 0xdf, 0x0d, 0x66, 0xb4, 0xb0, 0x62, 0x09, 0xdb, + 0x01, 0xd3, 0xb8, 0x6a, 0x6e, 0xbc, 0xd7, 0x05, 0x7e, 0xac, + 0xc7, 0x15, 0x11, 0xc3, 0xa8, 0x7a, 0xa0, 0x72, 0x19, 0xcb, + 0xcf, 0x1d, 0x76, 0xa4, 0x80, 0x52, 0x39, 0xeb, 0xef, 0x3d, + 0x56, 0x84, 0x5e, 0x8c, 0xe7, 0x35, 0x31, 0xe3, 0x88, 0x5a, + 0x21, 0xf3, 0x98, 0x4a, 0x4e, 0x9c, 0xf7, 0x25, 0xff, 0x2d, + 0x46, 0x94, 0x90, 0x42, 0x29, 0xfb, 0x00, 0xd3, 0xbb, 0x68, + 0x6b, 0xb8, 0xd0, 0x03, 0xd6, 0x05, 0x6d, 0xbe, 0xbd, 0x6e, + 0x06, 0xd5, 0xb1, 0x62, 0x0a, 0xd9, 0xda, 0x09, 0x61, 0xb2, + 0x67, 0xb4, 0xdc, 0x0f, 0x0c, 0xdf, 0xb7, 0x64, 0x7f, 0xac, + 0xc4, 0x17, 0x14, 0xc7, 0xaf, 0x7c, 0xa9, 0x7a, 0x12, 0xc1, + 0xc2, 0x11, 0x79, 0xaa, 0xce, 0x1d, 0x75, 0xa6, 0xa5, 0x76, + 0x1e, 0xcd, 0x18, 0xcb, 0xa3, 0x70, 0x73, 0xa0, 0xc8, 0x1b, + 0xfe, 0x2d, 0x45, 0x96, 0x95, 0x46, 0x2e, 0xfd, 0x28, 0xfb, + 0x93, 0x40, 0x43, 0x90, 0xf8, 0x2b, 0x4f, 0x9c, 0xf4, 0x27, + 0x24, 0xf7, 0x9f, 0x4c, 0x99, 0x4a, 0x22, 0xf1, 0xf2, 0x21, + 0x49, 0x9a, 0x81, 0x52, 0x3a, 0xe9, 0xea, 0x39, 0x51, 0x82, + 0x57, 0x84, 0xec, 0x3f, 0x3c, 0xef, 0x87, 0x54, 0x30, 0xe3, + 0x8b, 0x58, 0x5b, 0x88, 0xe0, 0x33, 0xe6, 0x35, 0x5d, 0x8e, + 0x8d, 0x5e, 0x36, 0xe5, 0xe1, 0x32, 0x5a, 0x89, 0x8a, 0x59, + 0x31, 0xe2, 0x37, 0xe4, 0x8c, 0x5f, 0x5c, 0x8f, 0xe7, 0x34, + 0x50, 0x83, 0xeb, 0x38, 0x3b, 0xe8, 0x80, 0x53, 0x86, 0x55, + 0x3d, 0xee, 0xed, 0x3e, 0x56, 0x85, 0x9e, 0x4d, 0x25, 0xf6, + 0xf5, 0x26, 0x4e, 0x9d, 0x48, 0x9b, 0xf3, 0x20, 0x23, 0xf0, + 0x98, 0x4b, 0x2f, 0xfc, 0x94, 0x47, 0x44, 0x97, 0xff, 0x2c, + 0xf9, 0x2a, 0x42, 0x91, 0x92, 0x41, 0x29, 0xfa, 0x1f, 0xcc, + 0xa4, 0x77, 0x74, 0xa7, 0xcf, 0x1c, 0xc9, 0x1a, 0x72, 0xa1, + 0xa2, 0x71, 0x19, 0xca, 0xae, 0x7d, 0x15, 0xc6, 0xc5, 0x16, + 0x7e, 0xad, 0x78, 0xab, 0xc3, 0x10, 0x13, 0xc0, 0xa8, 0x7b, + 0x60, 0xb3, 0xdb, 0x08, 0x0b, 0xd8, 0xb0, 0x63, 0xb6, 0x65, + 0x0d, 0xde, 0xdd, 0x0e, 0x66, 0xb5, 0xd1, 0x02, 0x6a, 0xb9, + 0xba, 0x69, 0x01, 0xd2, 0x07, 0xd4, 0xbc, 0x6f, 0x6c, 0xbf, + 0xd7, 0x04, 0x00, 0xd4, 0xb5, 0x61, 0x77, 0xa3, 0xc2, 0x16, + 0xee, 0x3a, 0x5b, 0x8f, 0x99, 0x4d, 0x2c, 0xf8, 0xc1, 0x15, + 0x74, 0xa0, 0xb6, 0x62, 0x03, 0xd7, 0x2f, 0xfb, 0x9a, 0x4e, + 0x58, 0x8c, 0xed, 0x39, 0x9f, 0x4b, 0x2a, 0xfe, 0xe8, 0x3c, + 0x5d, 0x89, 0x71, 0xa5, 0xc4, 0x10, 0x06, 0xd2, 0xb3, 0x67, + 0x5e, 0x8a, 0xeb, 0x3f, 0x29, 0xfd, 0x9c, 0x48, 0xb0, 0x64, + 0x05, 0xd1, 0xc7, 0x13, 0x72, 0xa6, 0x23, 0xf7, 0x96, 0x42, + 0x54, 0x80, 0xe1, 0x35, 0xcd, 0x19, 0x78, 0xac, 0xba, 0x6e, + 0x0f, 0xdb, 0xe2, 0x36, 0x57, 0x83, 0x95, 0x41, 0x20, 0xf4, + 0x0c, 0xd8, 0xb9, 0x6d, 0x7b, 0xaf, 0xce, 0x1a, 0xbc, 0x68, + 0x09, 0xdd, 0xcb, 0x1f, 0x7e, 0xaa, 0x52, 0x86, 0xe7, 0x33, + 0x25, 0xf1, 0x90, 0x44, 0x7d, 0xa9, 0xc8, 0x1c, 0x0a, 0xde, + 0xbf, 0x6b, 0x93, 0x47, 0x26, 0xf2, 0xe4, 0x30, 0x51, 0x85, + 0x46, 0x92, 0xf3, 0x27, 0x31, 0xe5, 0x84, 0x50, 0xa8, 0x7c, + 0x1d, 0xc9, 0xdf, 0x0b, 0x6a, 0xbe, 0x87, 0x53, 0x32, 0xe6, + 0xf0, 0x24, 0x45, 0x91, 0x69, 0xbd, 0xdc, 0x08, 0x1e, 0xca, + 0xab, 0x7f, 0xd9, 0x0d, 0x6c, 0xb8, 0xae, 0x7a, 0x1b, 0xcf, + 0x37, 0xe3, 0x82, 0x56, 0x40, 0x94, 0xf5, 0x21, 0x18, 0xcc, + 0xad, 0x79, 0x6f, 0xbb, 0xda, 0x0e, 0xf6, 0x22, 0x43, 0x97, + 0x81, 0x55, 0x34, 0xe0, 0x65, 0xb1, 0xd0, 0x04, 0x12, 0xc6, + 0xa7, 0x73, 0x8b, 0x5f, 0x3e, 0xea, 0xfc, 0x28, 0x49, 0x9d, + 0xa4, 0x70, 0x11, 0xc5, 0xd3, 0x07, 0x66, 0xb2, 0x4a, 0x9e, + 0xff, 0x2b, 0x3d, 0xe9, 0x88, 0x5c, 0xfa, 0x2e, 0x4f, 0x9b, + 0x8d, 0x59, 0x38, 0xec, 0x14, 0xc0, 0xa1, 0x75, 0x63, 0xb7, + 0xd6, 0x02, 0x3b, 0xef, 0x8e, 0x5a, 0x4c, 0x98, 0xf9, 0x2d, + 0xd5, 0x01, 0x60, 0xb4, 0xa2, 0x76, 0x17, 0xc3, 0x00, 0xd5, + 0xb7, 0x62, 0x73, 0xa6, 0xc4, 0x11, 0xe6, 0x33, 0x51, 0x84, + 0x95, 0x40, 0x22, 0xf7, 0xd1, 0x04, 0x66, 0xb3, 0xa2, 0x77, + 0x15, 0xc0, 0x37, 0xe2, 0x80, 0x55, 0x44, 0x91, 0xf3, 0x26, + 0xbf, 0x6a, 0x08, 0xdd, 0xcc, 0x19, 0x7b, 0xae, 0x59, 0x8c, + 0xee, 0x3b, 0x2a, 0xff, 0x9d, 0x48, 0x6e, 0xbb, 0xd9, 0x0c, + 0x1d, 0xc8, 0xaa, 0x7f, 0x88, 0x5d, 0x3f, 0xea, 0xfb, 0x2e, + 0x4c, 0x99, 0x63, 0xb6, 0xd4, 0x01, 0x10, 0xc5, 0xa7, 0x72, + 0x85, 0x50, 0x32, 0xe7, 0xf6, 0x23, 0x41, 0x94, 0xb2, 0x67, + 0x05, 0xd0, 0xc1, 0x14, 0x76, 0xa3, 0x54, 0x81, 0xe3, 0x36, + 0x27, 0xf2, 0x90, 0x45, 0xdc, 0x09, 0x6b, 0xbe, 0xaf, 0x7a, + 0x18, 0xcd, 0x3a, 0xef, 0x8d, 0x58, 0x49, 0x9c, 0xfe, 0x2b, + 0x0d, 0xd8, 0xba, 0x6f, 0x7e, 0xab, 0xc9, 0x1c, 0xeb, 0x3e, + 0x5c, 0x89, 0x98, 0x4d, 0x2f, 0xfa, 0xc6, 0x13, 0x71, 0xa4, + 0xb5, 0x60, 0x02, 0xd7, 0x20, 0xf5, 0x97, 0x42, 0x53, 0x86, + 0xe4, 0x31, 0x17, 0xc2, 0xa0, 0x75, 0x64, 0xb1, 0xd3, 0x06, + 0xf1, 0x24, 0x46, 0x93, 0x82, 0x57, 0x35, 0xe0, 0x79, 0xac, + 0xce, 0x1b, 0x0a, 0xdf, 0xbd, 0x68, 0x9f, 0x4a, 0x28, 0xfd, + 0xec, 0x39, 0x5b, 0x8e, 0xa8, 0x7d, 0x1f, 0xca, 0xdb, 0x0e, + 0x6c, 0xb9, 0x4e, 0x9b, 0xf9, 0x2c, 0x3d, 0xe8, 0x8a, 0x5f, + 0xa5, 0x70, 0x12, 0xc7, 0xd6, 0x03, 0x61, 0xb4, 0x43, 0x96, + 0xf4, 0x21, 0x30, 0xe5, 0x87, 0x52, 0x74, 0xa1, 0xc3, 0x16, + 0x07, 0xd2, 0xb0, 0x65, 0x92, 0x47, 0x25, 0xf0, 0xe1, 0x34, + 0x56, 0x83, 0x1a, 0xcf, 0xad, 0x78, 0x69, 0xbc, 0xde, 0x0b, + 0xfc, 0x29, 0x4b, 0x9e, 0x8f, 0x5a, 0x38, 0xed, 0xcb, 0x1e, + 0x7c, 0xa9, 0xb8, 0x6d, 0x0f, 0xda, 0x2d, 0xf8, 0x9a, 0x4f, + 0x5e, 0x8b, 0xe9, 0x3c, 0x00, 0xd6, 0xb1, 0x67, 0x7f, 0xa9, + 0xce, 0x18, 0xfe, 0x28, 0x4f, 0x99, 0x81, 0x57, 0x30, 0xe6, + 0xe1, 0x37, 0x50, 0x86, 0x9e, 0x48, 0x2f, 0xf9, 0x1f, 0xc9, + 0xae, 0x78, 0x60, 0xb6, 0xd1, 0x07, 0xdf, 0x09, 0x6e, 0xb8, + 0xa0, 0x76, 0x11, 0xc7, 0x21, 0xf7, 0x90, 0x46, 0x5e, 0x88, + 0xef, 0x39, 0x3e, 0xe8, 0x8f, 0x59, 0x41, 0x97, 0xf0, 0x26, + 0xc0, 0x16, 0x71, 0xa7, 0xbf, 0x69, 0x0e, 0xd8, 0xa3, 0x75, + 0x12, 0xc4, 0xdc, 0x0a, 0x6d, 0xbb, 0x5d, 0x8b, 0xec, 0x3a, + 0x22, 0xf4, 0x93, 0x45, 0x42, 0x94, 0xf3, 0x25, 0x3d, 0xeb, + 0x8c, 0x5a, 0xbc, 0x6a, 0x0d, 0xdb, 0xc3, 0x15, 0x72, 0xa4, + 0x7c, 0xaa, 0xcd, 0x1b, 0x03, 0xd5, 0xb2, 0x64, 0x82, 0x54, + 0x33, 0xe5, 0xfd, 0x2b, 0x4c, 0x9a, 0x9d, 0x4b, 0x2c, 0xfa, + 0xe2, 0x34, 0x53, 0x85, 0x63, 0xb5, 0xd2, 0x04, 0x1c, 0xca, + 0xad, 0x7b, 0x5b, 0x8d, 0xea, 0x3c, 0x24, 0xf2, 0x95, 0x43, + 0xa5, 0x73, 0x14, 0xc2, 0xda, 0x0c, 0x6b, 0xbd, 0xba, 0x6c, + 0x0b, 0xdd, 0xc5, 0x13, 0x74, 0xa2, 0x44, 0x92, 0xf5, 0x23, + 0x3b, 0xed, 0x8a, 0x5c, 0x84, 0x52, 0x35, 0xe3, 0xfb, 0x2d, + 0x4a, 0x9c, 0x7a, 0xac, 0xcb, 0x1d, 0x05, 0xd3, 0xb4, 0x62, + 0x65, 0xb3, 0xd4, 0x02, 0x1a, 0xcc, 0xab, 0x7d, 0x9b, 0x4d, + 0x2a, 0xfc, 0xe4, 0x32, 0x55, 0x83, 0xf8, 0x2e, 0x49, 0x9f, + 0x87, 0x51, 0x36, 0xe0, 0x06, 0xd0, 0xb7, 0x61, 0x79, 0xaf, + 0xc8, 0x1e, 0x19, 0xcf, 0xa8, 0x7e, 0x66, 0xb0, 0xd7, 0x01, + 0xe7, 0x31, 0x56, 0x80, 0x98, 0x4e, 0x29, 0xff, 0x27, 0xf1, + 0x96, 0x40, 0x58, 0x8e, 0xe9, 0x3f, 0xd9, 0x0f, 0x68, 0xbe, + 0xa6, 0x70, 0x17, 0xc1, 0xc6, 0x10, 0x77, 0xa1, 0xb9, 0x6f, + 0x08, 0xde, 0x38, 0xee, 0x89, 0x5f, 0x47, 0x91, 0xf6, 0x20, + 0x00, 0xd7, 0xb3, 0x64, 0x7b, 0xac, 0xc8, 0x1f, 0xf6, 0x21, + 0x45, 0x92, 0x8d, 0x5a, 0x3e, 0xe9, 0xf1, 0x26, 0x42, 0x95, + 0x8a, 0x5d, 0x39, 0xee, 0x07, 0xd0, 0xb4, 0x63, 0x7c, 0xab, + 0xcf, 0x18, 0xff, 0x28, 0x4c, 0x9b, 0x84, 0x53, 0x37, 0xe0, + 0x09, 0xde, 0xba, 0x6d, 0x72, 0xa5, 0xc1, 0x16, 0x0e, 0xd9, + 0xbd, 0x6a, 0x75, 0xa2, 0xc6, 0x11, 0xf8, 0x2f, 0x4b, 0x9c, + 0x83, 0x54, 0x30, 0xe7, 0xe3, 0x34, 0x50, 0x87, 0x98, 0x4f, + 0x2b, 0xfc, 0x15, 0xc2, 0xa6, 0x71, 0x6e, 0xb9, 0xdd, 0x0a, + 0x12, 0xc5, 0xa1, 0x76, 0x69, 0xbe, 0xda, 0x0d, 0xe4, 0x33, + 0x57, 0x80, 0x9f, 0x48, 0x2c, 0xfb, 0x1c, 0xcb, 0xaf, 0x78, + 0x67, 0xb0, 0xd4, 0x03, 0xea, 0x3d, 0x59, 0x8e, 0x91, 0x46, + 0x22, 0xf5, 0xed, 0x3a, 0x5e, 0x89, 0x96, 0x41, 0x25, 0xf2, + 0x1b, 0xcc, 0xa8, 0x7f, 0x60, 0xb7, 0xd3, 0x04, 0xdb, 0x0c, + 0x68, 0xbf, 0xa0, 0x77, 0x13, 0xc4, 0x2d, 0xfa, 0x9e, 0x49, + 0x56, 0x81, 0xe5, 0x32, 0x2a, 0xfd, 0x99, 0x4e, 0x51, 0x86, + 0xe2, 0x35, 0xdc, 0x0b, 0x6f, 0xb8, 0xa7, 0x70, 0x14, 0xc3, + 0x24, 0xf3, 0x97, 0x40, 0x5f, 0x88, 0xec, 0x3b, 0xd2, 0x05, + 0x61, 0xb6, 0xa9, 0x7e, 0x1a, 0xcd, 0xd5, 0x02, 0x66, 0xb1, + 0xae, 0x79, 0x1d, 0xca, 0x23, 0xf4, 0x90, 0x47, 0x58, 0x8f, + 0xeb, 0x3c, 0x38, 0xef, 0x8b, 0x5c, 0x43, 0x94, 0xf0, 0x27, + 0xce, 0x19, 0x7d, 0xaa, 0xb5, 0x62, 0x06, 0xd1, 0xc9, 0x1e, + 0x7a, 0xad, 0xb2, 0x65, 0x01, 0xd6, 0x3f, 0xe8, 0x8c, 0x5b, + 0x44, 0x93, 0xf7, 0x20, 0xc7, 0x10, 0x74, 0xa3, 0xbc, 0x6b, + 0x0f, 0xd8, 0x31, 0xe6, 0x82, 0x55, 0x4a, 0x9d, 0xf9, 0x2e, + 0x36, 0xe1, 0x85, 0x52, 0x4d, 0x9a, 0xfe, 0x29, 0xc0, 0x17, + 0x73, 0xa4, 0xbb, 0x6c, 0x08, 0xdf, 0x00, 0xd8, 0xad, 0x75, + 0x47, 0x9f, 0xea, 0x32, 0x8e, 0x56, 0x23, 0xfb, 0xc9, 0x11, + 0x64, 0xbc, 0x01, 0xd9, 0xac, 0x74, 0x46, 0x9e, 0xeb, 0x33, + 0x8f, 0x57, 0x22, 0xfa, 0xc8, 0x10, 0x65, 0xbd, 0x02, 0xda, + 0xaf, 0x77, 0x45, 0x9d, 0xe8, 0x30, 0x8c, 0x54, 0x21, 0xf9, + 0xcb, 0x13, 0x66, 0xbe, 0x03, 0xdb, 0xae, 0x76, 0x44, 0x9c, + 0xe9, 0x31, 0x8d, 0x55, 0x20, 0xf8, 0xca, 0x12, 0x67, 0xbf, + 0x04, 0xdc, 0xa9, 0x71, 0x43, 0x9b, 0xee, 0x36, 0x8a, 0x52, + 0x27, 0xff, 0xcd, 0x15, 0x60, 0xb8, 0x05, 0xdd, 0xa8, 0x70, + 0x42, 0x9a, 0xef, 0x37, 0x8b, 0x53, 0x26, 0xfe, 0xcc, 0x14, + 0x61, 0xb9, 0x06, 0xde, 0xab, 0x73, 0x41, 0x99, 0xec, 0x34, + 0x88, 0x50, 0x25, 0xfd, 0xcf, 0x17, 0x62, 0xba, 0x07, 0xdf, + 0xaa, 0x72, 0x40, 0x98, 0xed, 0x35, 0x89, 0x51, 0x24, 0xfc, + 0xce, 0x16, 0x63, 0xbb, 0x08, 0xd0, 0xa5, 0x7d, 0x4f, 0x97, + 0xe2, 0x3a, 0x86, 0x5e, 0x2b, 0xf3, 0xc1, 0x19, 0x6c, 0xb4, + 0x09, 0xd1, 0xa4, 0x7c, 0x4e, 0x96, 0xe3, 0x3b, 0x87, 0x5f, + 0x2a, 0xf2, 0xc0, 0x18, 0x6d, 0xb5, 0x0a, 0xd2, 0xa7, 0x7f, + 0x4d, 0x95, 0xe0, 0x38, 0x84, 0x5c, 0x29, 0xf1, 0xc3, 0x1b, + 0x6e, 0xb6, 0x0b, 0xd3, 0xa6, 0x7e, 0x4c, 0x94, 0xe1, 0x39, + 0x85, 0x5d, 0x28, 0xf0, 0xc2, 0x1a, 0x6f, 0xb7, 0x0c, 0xd4, + 0xa1, 0x79, 0x4b, 0x93, 0xe6, 0x3e, 0x82, 0x5a, 0x2f, 0xf7, + 0xc5, 0x1d, 0x68, 0xb0, 0x0d, 0xd5, 0xa0, 0x78, 0x4a, 0x92, + 0xe7, 0x3f, 0x83, 0x5b, 0x2e, 0xf6, 0xc4, 0x1c, 0x69, 0xb1, + 0x0e, 0xd6, 0xa3, 0x7b, 0x49, 0x91, 0xe4, 0x3c, 0x80, 0x58, + 0x2d, 0xf5, 0xc7, 0x1f, 0x6a, 0xb2, 0x0f, 0xd7, 0xa2, 0x7a, + 0x48, 0x90, 0xe5, 0x3d, 0x81, 0x59, 0x2c, 0xf4, 0xc6, 0x1e, + 0x6b, 0xb3, 0x00, 0xd9, 0xaf, 0x76, 0x43, 0x9a, 0xec, 0x35, + 0x86, 0x5f, 0x29, 0xf0, 0xc5, 0x1c, 0x6a, 0xb3, 0x11, 0xc8, + 0xbe, 0x67, 0x52, 0x8b, 0xfd, 0x24, 0x97, 0x4e, 0x38, 0xe1, + 0xd4, 0x0d, 0x7b, 0xa2, 0x22, 0xfb, 0x8d, 0x54, 0x61, 0xb8, + 0xce, 0x17, 0xa4, 0x7d, 0x0b, 0xd2, 0xe7, 0x3e, 0x48, 0x91, + 0x33, 0xea, 0x9c, 0x45, 0x70, 0xa9, 0xdf, 0x06, 0xb5, 0x6c, + 0x1a, 0xc3, 0xf6, 0x2f, 0x59, 0x80, 0x44, 0x9d, 0xeb, 0x32, + 0x07, 0xde, 0xa8, 0x71, 0xc2, 0x1b, 0x6d, 0xb4, 0x81, 0x58, + 0x2e, 0xf7, 0x55, 0x8c, 0xfa, 0x23, 0x16, 0xcf, 0xb9, 0x60, + 0xd3, 0x0a, 0x7c, 0xa5, 0x90, 0x49, 0x3f, 0xe6, 0x66, 0xbf, + 0xc9, 0x10, 0x25, 0xfc, 0x8a, 0x53, 0xe0, 0x39, 0x4f, 0x96, + 0xa3, 0x7a, 0x0c, 0xd5, 0x77, 0xae, 0xd8, 0x01, 0x34, 0xed, + 0x9b, 0x42, 0xf1, 0x28, 0x5e, 0x87, 0xb2, 0x6b, 0x1d, 0xc4, + 0x88, 0x51, 0x27, 0xfe, 0xcb, 0x12, 0x64, 0xbd, 0x0e, 0xd7, + 0xa1, 0x78, 0x4d, 0x94, 0xe2, 0x3b, 0x99, 0x40, 0x36, 0xef, + 0xda, 0x03, 0x75, 0xac, 0x1f, 0xc6, 0xb0, 0x69, 0x5c, 0x85, + 0xf3, 0x2a, 0xaa, 0x73, 0x05, 0xdc, 0xe9, 0x30, 0x46, 0x9f, + 0x2c, 0xf5, 0x83, 0x5a, 0x6f, 0xb6, 0xc0, 0x19, 0xbb, 0x62, + 0x14, 0xcd, 0xf8, 0x21, 0x57, 0x8e, 0x3d, 0xe4, 0x92, 0x4b, + 0x7e, 0xa7, 0xd1, 0x08, 0xcc, 0x15, 0x63, 0xba, 0x8f, 0x56, + 0x20, 0xf9, 0x4a, 0x93, 0xe5, 0x3c, 0x09, 0xd0, 0xa6, 0x7f, + 0xdd, 0x04, 0x72, 0xab, 0x9e, 0x47, 0x31, 0xe8, 0x5b, 0x82, + 0xf4, 0x2d, 0x18, 0xc1, 0xb7, 0x6e, 0xee, 0x37, 0x41, 0x98, + 0xad, 0x74, 0x02, 0xdb, 0x68, 0xb1, 0xc7, 0x1e, 0x2b, 0xf2, + 0x84, 0x5d, 0xff, 0x26, 0x50, 0x89, 0xbc, 0x65, 0x13, 0xca, + 0x79, 0xa0, 0xd6, 0x0f, 0x3a, 0xe3, 0x95, 0x4c, 0x00, 0xda, + 0xa9, 0x73, 0x4f, 0x95, 0xe6, 0x3c, 0x9e, 0x44, 0x37, 0xed, + 0xd1, 0x0b, 0x78, 0xa2, 0x21, 0xfb, 0x88, 0x52, 0x6e, 0xb4, + 0xc7, 0x1d, 0xbf, 0x65, 0x16, 0xcc, 0xf0, 0x2a, 0x59, 0x83, + 0x42, 0x98, 0xeb, 0x31, 0x0d, 0xd7, 0xa4, 0x7e, 0xdc, 0x06, + 0x75, 0xaf, 0x93, 0x49, 0x3a, 0xe0, 0x63, 0xb9, 0xca, 0x10, + 0x2c, 0xf6, 0x85, 0x5f, 0xfd, 0x27, 0x54, 0x8e, 0xb2, 0x68, + 0x1b, 0xc1, 0x84, 0x5e, 0x2d, 0xf7, 0xcb, 0x11, 0x62, 0xb8, + 0x1a, 0xc0, 0xb3, 0x69, 0x55, 0x8f, 0xfc, 0x26, 0xa5, 0x7f, + 0x0c, 0xd6, 0xea, 0x30, 0x43, 0x99, 0x3b, 0xe1, 0x92, 0x48, + 0x74, 0xae, 0xdd, 0x07, 0xc6, 0x1c, 0x6f, 0xb5, 0x89, 0x53, + 0x20, 0xfa, 0x58, 0x82, 0xf1, 0x2b, 0x17, 0xcd, 0xbe, 0x64, + 0xe7, 0x3d, 0x4e, 0x94, 0xa8, 0x72, 0x01, 0xdb, 0x79, 0xa3, + 0xd0, 0x0a, 0x36, 0xec, 0x9f, 0x45, 0x15, 0xcf, 0xbc, 0x66, + 0x5a, 0x80, 0xf3, 0x29, 0x8b, 0x51, 0x22, 0xf8, 0xc4, 0x1e, + 0x6d, 0xb7, 0x34, 0xee, 0x9d, 0x47, 0x7b, 0xa1, 0xd2, 0x08, + 0xaa, 0x70, 0x03, 0xd9, 0xe5, 0x3f, 0x4c, 0x96, 0x57, 0x8d, + 0xfe, 0x24, 0x18, 0xc2, 0xb1, 0x6b, 0xc9, 0x13, 0x60, 0xba, + 0x86, 0x5c, 0x2f, 0xf5, 0x76, 0xac, 0xdf, 0x05, 0x39, 0xe3, + 0x90, 0x4a, 0xe8, 0x32, 0x41, 0x9b, 0xa7, 0x7d, 0x0e, 0xd4, + 0x91, 0x4b, 0x38, 0xe2, 0xde, 0x04, 0x77, 0xad, 0x0f, 0xd5, + 0xa6, 0x7c, 0x40, 0x9a, 0xe9, 0x33, 0xb0, 0x6a, 0x19, 0xc3, + 0xff, 0x25, 0x56, 0x8c, 0x2e, 0xf4, 0x87, 0x5d, 0x61, 0xbb, + 0xc8, 0x12, 0xd3, 0x09, 0x7a, 0xa0, 0x9c, 0x46, 0x35, 0xef, + 0x4d, 0x97, 0xe4, 0x3e, 0x02, 0xd8, 0xab, 0x71, 0xf2, 0x28, + 0x5b, 0x81, 0xbd, 0x67, 0x14, 0xce, 0x6c, 0xb6, 0xc5, 0x1f, + 0x23, 0xf9, 0x8a, 0x50, 0x00, 0xdb, 0xab, 0x70, 0x4b, 0x90, + 0xe0, 0x3b, 0x96, 0x4d, 0x3d, 0xe6, 0xdd, 0x06, 0x76, 0xad, + 0x31, 0xea, 0x9a, 0x41, 0x7a, 0xa1, 0xd1, 0x0a, 0xa7, 0x7c, + 0x0c, 0xd7, 0xec, 0x37, 0x47, 0x9c, 0x62, 0xb9, 0xc9, 0x12, + 0x29, 0xf2, 0x82, 0x59, 0xf4, 0x2f, 0x5f, 0x84, 0xbf, 0x64, + 0x14, 0xcf, 0x53, 0x88, 0xf8, 0x23, 0x18, 0xc3, 0xb3, 0x68, + 0xc5, 0x1e, 0x6e, 0xb5, 0x8e, 0x55, 0x25, 0xfe, 0xc4, 0x1f, + 0x6f, 0xb4, 0x8f, 0x54, 0x24, 0xff, 0x52, 0x89, 0xf9, 0x22, + 0x19, 0xc2, 0xb2, 0x69, 0xf5, 0x2e, 0x5e, 0x85, 0xbe, 0x65, + 0x15, 0xce, 0x63, 0xb8, 0xc8, 0x13, 0x28, 0xf3, 0x83, 0x58, + 0xa6, 0x7d, 0x0d, 0xd6, 0xed, 0x36, 0x46, 0x9d, 0x30, 0xeb, + 0x9b, 0x40, 0x7b, 0xa0, 0xd0, 0x0b, 0x97, 0x4c, 0x3c, 0xe7, + 0xdc, 0x07, 0x77, 0xac, 0x01, 0xda, 0xaa, 0x71, 0x4a, 0x91, + 0xe1, 0x3a, 0x95, 0x4e, 0x3e, 0xe5, 0xde, 0x05, 0x75, 0xae, + 0x03, 0xd8, 0xa8, 0x73, 0x48, 0x93, 0xe3, 0x38, 0xa4, 0x7f, + 0x0f, 0xd4, 0xef, 0x34, 0x44, 0x9f, 0x32, 0xe9, 0x99, 0x42, + 0x79, 0xa2, 0xd2, 0x09, 0xf7, 0x2c, 0x5c, 0x87, 0xbc, 0x67, + 0x17, 0xcc, 0x61, 0xba, 0xca, 0x11, 0x2a, 0xf1, 0x81, 0x5a, + 0xc6, 0x1d, 0x6d, 0xb6, 0x8d, 0x56, 0x26, 0xfd, 0x50, 0x8b, + 0xfb, 0x20, 0x1b, 0xc0, 0xb0, 0x6b, 0x51, 0x8a, 0xfa, 0x21, + 0x1a, 0xc1, 0xb1, 0x6a, 0xc7, 0x1c, 0x6c, 0xb7, 0x8c, 0x57, + 0x27, 0xfc, 0x60, 0xbb, 0xcb, 0x10, 0x2b, 0xf0, 0x80, 0x5b, + 0xf6, 0x2d, 0x5d, 0x86, 0xbd, 0x66, 0x16, 0xcd, 0x33, 0xe8, + 0x98, 0x43, 0x78, 0xa3, 0xd3, 0x08, 0xa5, 0x7e, 0x0e, 0xd5, + 0xee, 0x35, 0x45, 0x9e, 0x02, 0xd9, 0xa9, 0x72, 0x49, 0x92, + 0xe2, 0x39, 0x94, 0x4f, 0x3f, 0xe4, 0xdf, 0x04, 0x74, 0xaf, + 0x00, 0xdc, 0xa5, 0x79, 0x57, 0x8b, 0xf2, 0x2e, 0xae, 0x72, + 0x0b, 0xd7, 0xf9, 0x25, 0x5c, 0x80, 0x41, 0x9d, 0xe4, 0x38, + 0x16, 0xca, 0xb3, 0x6f, 0xef, 0x33, 0x4a, 0x96, 0xb8, 0x64, + 0x1d, 0xc1, 0x82, 0x5e, 0x27, 0xfb, 0xd5, 0x09, 0x70, 0xac, + 0x2c, 0xf0, 0x89, 0x55, 0x7b, 0xa7, 0xde, 0x02, 0xc3, 0x1f, + 0x66, 0xba, 0x94, 0x48, 0x31, 0xed, 0x6d, 0xb1, 0xc8, 0x14, + 0x3a, 0xe6, 0x9f, 0x43, 0x19, 0xc5, 0xbc, 0x60, 0x4e, 0x92, + 0xeb, 0x37, 0xb7, 0x6b, 0x12, 0xce, 0xe0, 0x3c, 0x45, 0x99, + 0x58, 0x84, 0xfd, 0x21, 0x0f, 0xd3, 0xaa, 0x76, 0xf6, 0x2a, + 0x53, 0x8f, 0xa1, 0x7d, 0x04, 0xd8, 0x9b, 0x47, 0x3e, 0xe2, + 0xcc, 0x10, 0x69, 0xb5, 0x35, 0xe9, 0x90, 0x4c, 0x62, 0xbe, + 0xc7, 0x1b, 0xda, 0x06, 0x7f, 0xa3, 0x8d, 0x51, 0x28, 0xf4, + 0x74, 0xa8, 0xd1, 0x0d, 0x23, 0xff, 0x86, 0x5a, 0x32, 0xee, + 0x97, 0x4b, 0x65, 0xb9, 0xc0, 0x1c, 0x9c, 0x40, 0x39, 0xe5, + 0xcb, 0x17, 0x6e, 0xb2, 0x73, 0xaf, 0xd6, 0x0a, 0x24, 0xf8, + 0x81, 0x5d, 0xdd, 0x01, 0x78, 0xa4, 0x8a, 0x56, 0x2f, 0xf3, + 0xb0, 0x6c, 0x15, 0xc9, 0xe7, 0x3b, 0x42, 0x9e, 0x1e, 0xc2, + 0xbb, 0x67, 0x49, 0x95, 0xec, 0x30, 0xf1, 0x2d, 0x54, 0x88, + 0xa6, 0x7a, 0x03, 0xdf, 0x5f, 0x83, 0xfa, 0x26, 0x08, 0xd4, + 0xad, 0x71, 0x2b, 0xf7, 0x8e, 0x52, 0x7c, 0xa0, 0xd9, 0x05, + 0x85, 0x59, 0x20, 0xfc, 0xd2, 0x0e, 0x77, 0xab, 0x6a, 0xb6, + 0xcf, 0x13, 0x3d, 0xe1, 0x98, 0x44, 0xc4, 0x18, 0x61, 0xbd, + 0x93, 0x4f, 0x36, 0xea, 0xa9, 0x75, 0x0c, 0xd0, 0xfe, 0x22, + 0x5b, 0x87, 0x07, 0xdb, 0xa2, 0x7e, 0x50, 0x8c, 0xf5, 0x29, + 0xe8, 0x34, 0x4d, 0x91, 0xbf, 0x63, 0x1a, 0xc6, 0x46, 0x9a, + 0xe3, 0x3f, 0x11, 0xcd, 0xb4, 0x68, 0x00, 0xdd, 0xa7, 0x7a, + 0x53, 0x8e, 0xf4, 0x29, 0xa6, 0x7b, 0x01, 0xdc, 0xf5, 0x28, + 0x52, 0x8f, 0x51, 0x8c, 0xf6, 0x2b, 0x02, 0xdf, 0xa5, 0x78, + 0xf7, 0x2a, 0x50, 0x8d, 0xa4, 0x79, 0x03, 0xde, 0xa2, 0x7f, + 0x05, 0xd8, 0xf1, 0x2c, 0x56, 0x8b, 0x04, 0xd9, 0xa3, 0x7e, + 0x57, 0x8a, 0xf0, 0x2d, 0xf3, 0x2e, 0x54, 0x89, 0xa0, 0x7d, + 0x07, 0xda, 0x55, 0x88, 0xf2, 0x2f, 0x06, 0xdb, 0xa1, 0x7c, + 0x59, 0x84, 0xfe, 0x23, 0x0a, 0xd7, 0xad, 0x70, 0xff, 0x22, + 0x58, 0x85, 0xac, 0x71, 0x0b, 0xd6, 0x08, 0xd5, 0xaf, 0x72, + 0x5b, 0x86, 0xfc, 0x21, 0xae, 0x73, 0x09, 0xd4, 0xfd, 0x20, + 0x5a, 0x87, 0xfb, 0x26, 0x5c, 0x81, 0xa8, 0x75, 0x0f, 0xd2, + 0x5d, 0x80, 0xfa, 0x27, 0x0e, 0xd3, 0xa9, 0x74, 0xaa, 0x77, + 0x0d, 0xd0, 0xf9, 0x24, 0x5e, 0x83, 0x0c, 0xd1, 0xab, 0x76, + 0x5f, 0x82, 0xf8, 0x25, 0xb2, 0x6f, 0x15, 0xc8, 0xe1, 0x3c, + 0x46, 0x9b, 0x14, 0xc9, 0xb3, 0x6e, 0x47, 0x9a, 0xe0, 0x3d, + 0xe3, 0x3e, 0x44, 0x99, 0xb0, 0x6d, 0x17, 0xca, 0x45, 0x98, + 0xe2, 0x3f, 0x16, 0xcb, 0xb1, 0x6c, 0x10, 0xcd, 0xb7, 0x6a, + 0x43, 0x9e, 0xe4, 0x39, 0xb6, 0x6b, 0x11, 0xcc, 0xe5, 0x38, + 0x42, 0x9f, 0x41, 0x9c, 0xe6, 0x3b, 0x12, 0xcf, 0xb5, 0x68, + 0xe7, 0x3a, 0x40, 0x9d, 0xb4, 0x69, 0x13, 0xce, 0xeb, 0x36, + 0x4c, 0x91, 0xb8, 0x65, 0x1f, 0xc2, 0x4d, 0x90, 0xea, 0x37, + 0x1e, 0xc3, 0xb9, 0x64, 0xba, 0x67, 0x1d, 0xc0, 0xe9, 0x34, + 0x4e, 0x93, 0x1c, 0xc1, 0xbb, 0x66, 0x4f, 0x92, 0xe8, 0x35, + 0x49, 0x94, 0xee, 0x33, 0x1a, 0xc7, 0xbd, 0x60, 0xef, 0x32, + 0x48, 0x95, 0xbc, 0x61, 0x1b, 0xc6, 0x18, 0xc5, 0xbf, 0x62, + 0x4b, 0x96, 0xec, 0x31, 0xbe, 0x63, 0x19, 0xc4, 0xed, 0x30, + 0x4a, 0x97, 0x00, 0xde, 0xa1, 0x7f, 0x5f, 0x81, 0xfe, 0x20, + 0xbe, 0x60, 0x1f, 0xc1, 0xe1, 0x3f, 0x40, 0x9e, 0x61, 0xbf, + 0xc0, 0x1e, 0x3e, 0xe0, 0x9f, 0x41, 0xdf, 0x01, 0x7e, 0xa0, + 0x80, 0x5e, 0x21, 0xff, 0xc2, 0x1c, 0x63, 0xbd, 0x9d, 0x43, + 0x3c, 0xe2, 0x7c, 0xa2, 0xdd, 0x03, 0x23, 0xfd, 0x82, 0x5c, + 0xa3, 0x7d, 0x02, 0xdc, 0xfc, 0x22, 0x5d, 0x83, 0x1d, 0xc3, + 0xbc, 0x62, 0x42, 0x9c, 0xe3, 0x3d, 0x99, 0x47, 0x38, 0xe6, + 0xc6, 0x18, 0x67, 0xb9, 0x27, 0xf9, 0x86, 0x58, 0x78, 0xa6, + 0xd9, 0x07, 0xf8, 0x26, 0x59, 0x87, 0xa7, 0x79, 0x06, 0xd8, + 0x46, 0x98, 0xe7, 0x39, 0x19, 0xc7, 0xb8, 0x66, 0x5b, 0x85, + 0xfa, 0x24, 0x04, 0xda, 0xa5, 0x7b, 0xe5, 0x3b, 0x44, 0x9a, + 0xba, 0x64, 0x1b, 0xc5, 0x3a, 0xe4, 0x9b, 0x45, 0x65, 0xbb, + 0xc4, 0x1a, 0x84, 0x5a, 0x25, 0xfb, 0xdb, 0x05, 0x7a, 0xa4, + 0x2f, 0xf1, 0x8e, 0x50, 0x70, 0xae, 0xd1, 0x0f, 0x91, 0x4f, + 0x30, 0xee, 0xce, 0x10, 0x6f, 0xb1, 0x4e, 0x90, 0xef, 0x31, + 0x11, 0xcf, 0xb0, 0x6e, 0xf0, 0x2e, 0x51, 0x8f, 0xaf, 0x71, + 0x0e, 0xd0, 0xed, 0x33, 0x4c, 0x92, 0xb2, 0x6c, 0x13, 0xcd, + 0x53, 0x8d, 0xf2, 0x2c, 0x0c, 0xd2, 0xad, 0x73, 0x8c, 0x52, + 0x2d, 0xf3, 0xd3, 0x0d, 0x72, 0xac, 0x32, 0xec, 0x93, 0x4d, + 0x6d, 0xb3, 0xcc, 0x12, 0xb6, 0x68, 0x17, 0xc9, 0xe9, 0x37, + 0x48, 0x96, 0x08, 0xd6, 0xa9, 0x77, 0x57, 0x89, 0xf6, 0x28, + 0xd7, 0x09, 0x76, 0xa8, 0x88, 0x56, 0x29, 0xf7, 0x69, 0xb7, + 0xc8, 0x16, 0x36, 0xe8, 0x97, 0x49, 0x74, 0xaa, 0xd5, 0x0b, + 0x2b, 0xf5, 0x8a, 0x54, 0xca, 0x14, 0x6b, 0xb5, 0x95, 0x4b, + 0x34, 0xea, 0x15, 0xcb, 0xb4, 0x6a, 0x4a, 0x94, 0xeb, 0x35, + 0xab, 0x75, 0x0a, 0xd4, 0xf4, 0x2a, 0x55, 0x8b, 0x00, 0xdf, + 0xa3, 0x7c, 0x5b, 0x84, 0xf8, 0x27, 0xb6, 0x69, 0x15, 0xca, + 0xed, 0x32, 0x4e, 0x91, 0x71, 0xae, 0xd2, 0x0d, 0x2a, 0xf5, + 0x89, 0x56, 0xc7, 0x18, 0x64, 0xbb, 0x9c, 0x43, 0x3f, 0xe0, + 0xe2, 0x3d, 0x41, 0x9e, 0xb9, 0x66, 0x1a, 0xc5, 0x54, 0x8b, + 0xf7, 0x28, 0x0f, 0xd0, 0xac, 0x73, 0x93, 0x4c, 0x30, 0xef, + 0xc8, 0x17, 0x6b, 0xb4, 0x25, 0xfa, 0x86, 0x59, 0x7e, 0xa1, + 0xdd, 0x02, 0xd9, 0x06, 0x7a, 0xa5, 0x82, 0x5d, 0x21, 0xfe, + 0x6f, 0xb0, 0xcc, 0x13, 0x34, 0xeb, 0x97, 0x48, 0xa8, 0x77, + 0x0b, 0xd4, 0xf3, 0x2c, 0x50, 0x8f, 0x1e, 0xc1, 0xbd, 0x62, + 0x45, 0x9a, 0xe6, 0x39, 0x3b, 0xe4, 0x98, 0x47, 0x60, 0xbf, + 0xc3, 0x1c, 0x8d, 0x52, 0x2e, 0xf1, 0xd6, 0x09, 0x75, 0xaa, + 0x4a, 0x95, 0xe9, 0x36, 0x11, 0xce, 0xb2, 0x6d, 0xfc, 0x23, + 0x5f, 0x80, 0xa7, 0x78, 0x04, 0xdb, 0xaf, 0x70, 0x0c, 0xd3, + 0xf4, 0x2b, 0x57, 0x88, 0x19, 0xc6, 0xba, 0x65, 0x42, 0x9d, + 0xe1, 0x3e, 0xde, 0x01, 0x7d, 0xa2, 0x85, 0x5a, 0x26, 0xf9, + 0x68, 0xb7, 0xcb, 0x14, 0x33, 0xec, 0x90, 0x4f, 0x4d, 0x92, + 0xee, 0x31, 0x16, 0xc9, 0xb5, 0x6a, 0xfb, 0x24, 0x58, 0x87, + 0xa0, 0x7f, 0x03, 0xdc, 0x3c, 0xe3, 0x9f, 0x40, 0x67, 0xb8, + 0xc4, 0x1b, 0x8a, 0x55, 0x29, 0xf6, 0xd1, 0x0e, 0x72, 0xad, + 0x76, 0xa9, 0xd5, 0x0a, 0x2d, 0xf2, 0x8e, 0x51, 0xc0, 0x1f, + 0x63, 0xbc, 0x9b, 0x44, 0x38, 0xe7, 0x07, 0xd8, 0xa4, 0x7b, + 0x5c, 0x83, 0xff, 0x20, 0xb1, 0x6e, 0x12, 0xcd, 0xea, 0x35, + 0x49, 0x96, 0x94, 0x4b, 0x37, 0xe8, 0xcf, 0x10, 0x6c, 0xb3, + 0x22, 0xfd, 0x81, 0x5e, 0x79, 0xa6, 0xda, 0x05, 0xe5, 0x3a, + 0x46, 0x99, 0xbe, 0x61, 0x1d, 0xc2, 0x53, 0x8c, 0xf0, 0x2f, + 0x08, 0xd7, 0xab, 0x74, 0x00, 0xe0, 0xdd, 0x3d, 0xa7, 0x47, + 0x7a, 0x9a, 0x53, 0xb3, 0x8e, 0x6e, 0xf4, 0x14, 0x29, 0xc9, + 0xa6, 0x46, 0x7b, 0x9b, 0x01, 0xe1, 0xdc, 0x3c, 0xf5, 0x15, + 0x28, 0xc8, 0x52, 0xb2, 0x8f, 0x6f, 0x51, 0xb1, 0x8c, 0x6c, + 0xf6, 0x16, 0x2b, 0xcb, 0x02, 0xe2, 0xdf, 0x3f, 0xa5, 0x45, + 0x78, 0x98, 0xf7, 0x17, 0x2a, 0xca, 0x50, 0xb0, 0x8d, 0x6d, + 0xa4, 0x44, 0x79, 0x99, 0x03, 0xe3, 0xde, 0x3e, 0xa2, 0x42, + 0x7f, 0x9f, 0x05, 0xe5, 0xd8, 0x38, 0xf1, 0x11, 0x2c, 0xcc, + 0x56, 0xb6, 0x8b, 0x6b, 0x04, 0xe4, 0xd9, 0x39, 0xa3, 0x43, + 0x7e, 0x9e, 0x57, 0xb7, 0x8a, 0x6a, 0xf0, 0x10, 0x2d, 0xcd, + 0xf3, 0x13, 0x2e, 0xce, 0x54, 0xb4, 0x89, 0x69, 0xa0, 0x40, + 0x7d, 0x9d, 0x07, 0xe7, 0xda, 0x3a, 0x55, 0xb5, 0x88, 0x68, + 0xf2, 0x12, 0x2f, 0xcf, 0x06, 0xe6, 0xdb, 0x3b, 0xa1, 0x41, + 0x7c, 0x9c, 0x59, 0xb9, 0x84, 0x64, 0xfe, 0x1e, 0x23, 0xc3, + 0x0a, 0xea, 0xd7, 0x37, 0xad, 0x4d, 0x70, 0x90, 0xff, 0x1f, + 0x22, 0xc2, 0x58, 0xb8, 0x85, 0x65, 0xac, 0x4c, 0x71, 0x91, + 0x0b, 0xeb, 0xd6, 0x36, 0x08, 0xe8, 0xd5, 0x35, 0xaf, 0x4f, + 0x72, 0x92, 0x5b, 0xbb, 0x86, 0x66, 0xfc, 0x1c, 0x21, 0xc1, + 0xae, 0x4e, 0x73, 0x93, 0x09, 0xe9, 0xd4, 0x34, 0xfd, 0x1d, + 0x20, 0xc0, 0x5a, 0xba, 0x87, 0x67, 0xfb, 0x1b, 0x26, 0xc6, + 0x5c, 0xbc, 0x81, 0x61, 0xa8, 0x48, 0x75, 0x95, 0x0f, 0xef, + 0xd2, 0x32, 0x5d, 0xbd, 0x80, 0x60, 0xfa, 0x1a, 0x27, 0xc7, + 0x0e, 0xee, 0xd3, 0x33, 0xa9, 0x49, 0x74, 0x94, 0xaa, 0x4a, + 0x77, 0x97, 0x0d, 0xed, 0xd0, 0x30, 0xf9, 0x19, 0x24, 0xc4, + 0x5e, 0xbe, 0x83, 0x63, 0x0c, 0xec, 0xd1, 0x31, 0xab, 0x4b, + 0x76, 0x96, 0x5f, 0xbf, 0x82, 0x62, 0xf8, 0x18, 0x25, 0xc5, + 0x00, 0xe1, 0xdf, 0x3e, 0xa3, 0x42, 0x7c, 0x9d, 0x5b, 0xba, + 0x84, 0x65, 0xf8, 0x19, 0x27, 0xc6, 0xb6, 0x57, 0x69, 0x88, + 0x15, 0xf4, 0xca, 0x2b, 0xed, 0x0c, 0x32, 0xd3, 0x4e, 0xaf, + 0x91, 0x70, 0x71, 0x90, 0xae, 0x4f, 0xd2, 0x33, 0x0d, 0xec, + 0x2a, 0xcb, 0xf5, 0x14, 0x89, 0x68, 0x56, 0xb7, 0xc7, 0x26, + 0x18, 0xf9, 0x64, 0x85, 0xbb, 0x5a, 0x9c, 0x7d, 0x43, 0xa2, + 0x3f, 0xde, 0xe0, 0x01, 0xe2, 0x03, 0x3d, 0xdc, 0x41, 0xa0, + 0x9e, 0x7f, 0xb9, 0x58, 0x66, 0x87, 0x1a, 0xfb, 0xc5, 0x24, + 0x54, 0xb5, 0x8b, 0x6a, 0xf7, 0x16, 0x28, 0xc9, 0x0f, 0xee, + 0xd0, 0x31, 0xac, 0x4d, 0x73, 0x92, 0x93, 0x72, 0x4c, 0xad, + 0x30, 0xd1, 0xef, 0x0e, 0xc8, 0x29, 0x17, 0xf6, 0x6b, 0x8a, + 0xb4, 0x55, 0x25, 0xc4, 0xfa, 0x1b, 0x86, 0x67, 0x59, 0xb8, + 0x7e, 0x9f, 0xa1, 0x40, 0xdd, 0x3c, 0x02, 0xe3, 0xd9, 0x38, + 0x06, 0xe7, 0x7a, 0x9b, 0xa5, 0x44, 0x82, 0x63, 0x5d, 0xbc, + 0x21, 0xc0, 0xfe, 0x1f, 0x6f, 0x8e, 0xb0, 0x51, 0xcc, 0x2d, + 0x13, 0xf2, 0x34, 0xd5, 0xeb, 0x0a, 0x97, 0x76, 0x48, 0xa9, + 0xa8, 0x49, 0x77, 0x96, 0x0b, 0xea, 0xd4, 0x35, 0xf3, 0x12, + 0x2c, 0xcd, 0x50, 0xb1, 0x8f, 0x6e, 0x1e, 0xff, 0xc1, 0x20, + 0xbd, 0x5c, 0x62, 0x83, 0x45, 0xa4, 0x9a, 0x7b, 0xe6, 0x07, + 0x39, 0xd8, 0x3b, 0xda, 0xe4, 0x05, 0x98, 0x79, 0x47, 0xa6, + 0x60, 0x81, 0xbf, 0x5e, 0xc3, 0x22, 0x1c, 0xfd, 0x8d, 0x6c, + 0x52, 0xb3, 0x2e, 0xcf, 0xf1, 0x10, 0xd6, 0x37, 0x09, 0xe8, + 0x75, 0x94, 0xaa, 0x4b, 0x4a, 0xab, 0x95, 0x74, 0xe9, 0x08, + 0x36, 0xd7, 0x11, 0xf0, 0xce, 0x2f, 0xb2, 0x53, 0x6d, 0x8c, + 0xfc, 0x1d, 0x23, 0xc2, 0x5f, 0xbe, 0x80, 0x61, 0xa7, 0x46, + 0x78, 0x99, 0x04, 0xe5, 0xdb, 0x3a, 0x00, 0xe2, 0xd9, 0x3b, + 0xaf, 0x4d, 0x76, 0x94, 0x43, 0xa1, 0x9a, 0x78, 0xec, 0x0e, + 0x35, 0xd7, 0x86, 0x64, 0x5f, 0xbd, 0x29, 0xcb, 0xf0, 0x12, + 0xc5, 0x27, 0x1c, 0xfe, 0x6a, 0x88, 0xb3, 0x51, 0x11, 0xf3, + 0xc8, 0x2a, 0xbe, 0x5c, 0x67, 0x85, 0x52, 0xb0, 0x8b, 0x69, + 0xfd, 0x1f, 0x24, 0xc6, 0x97, 0x75, 0x4e, 0xac, 0x38, 0xda, + 0xe1, 0x03, 0xd4, 0x36, 0x0d, 0xef, 0x7b, 0x99, 0xa2, 0x40, + 0x22, 0xc0, 0xfb, 0x19, 0x8d, 0x6f, 0x54, 0xb6, 0x61, 0x83, + 0xb8, 0x5a, 0xce, 0x2c, 0x17, 0xf5, 0xa4, 0x46, 0x7d, 0x9f, + 0x0b, 0xe9, 0xd2, 0x30, 0xe7, 0x05, 0x3e, 0xdc, 0x48, 0xaa, + 0x91, 0x73, 0x33, 0xd1, 0xea, 0x08, 0x9c, 0x7e, 0x45, 0xa7, + 0x70, 0x92, 0xa9, 0x4b, 0xdf, 0x3d, 0x06, 0xe4, 0xb5, 0x57, + 0x6c, 0x8e, 0x1a, 0xf8, 0xc3, 0x21, 0xf6, 0x14, 0x2f, 0xcd, + 0x59, 0xbb, 0x80, 0x62, 0x44, 0xa6, 0x9d, 0x7f, 0xeb, 0x09, + 0x32, 0xd0, 0x07, 0xe5, 0xde, 0x3c, 0xa8, 0x4a, 0x71, 0x93, + 0xc2, 0x20, 0x1b, 0xf9, 0x6d, 0x8f, 0xb4, 0x56, 0x81, 0x63, + 0x58, 0xba, 0x2e, 0xcc, 0xf7, 0x15, 0x55, 0xb7, 0x8c, 0x6e, + 0xfa, 0x18, 0x23, 0xc1, 0x16, 0xf4, 0xcf, 0x2d, 0xb9, 0x5b, + 0x60, 0x82, 0xd3, 0x31, 0x0a, 0xe8, 0x7c, 0x9e, 0xa5, 0x47, + 0x90, 0x72, 0x49, 0xab, 0x3f, 0xdd, 0xe6, 0x04, 0x66, 0x84, + 0xbf, 0x5d, 0xc9, 0x2b, 0x10, 0xf2, 0x25, 0xc7, 0xfc, 0x1e, + 0x8a, 0x68, 0x53, 0xb1, 0xe0, 0x02, 0x39, 0xdb, 0x4f, 0xad, + 0x96, 0x74, 0xa3, 0x41, 0x7a, 0x98, 0x0c, 0xee, 0xd5, 0x37, + 0x77, 0x95, 0xae, 0x4c, 0xd8, 0x3a, 0x01, 0xe3, 0x34, 0xd6, + 0xed, 0x0f, 0x9b, 0x79, 0x42, 0xa0, 0xf1, 0x13, 0x28, 0xca, + 0x5e, 0xbc, 0x87, 0x65, 0xb2, 0x50, 0x6b, 0x89, 0x1d, 0xff, + 0xc4, 0x26, 0x00, 0xe3, 0xdb, 0x38, 0xab, 0x48, 0x70, 0x93, + 0x4b, 0xa8, 0x90, 0x73, 0xe0, 0x03, 0x3b, 0xd8, 0x96, 0x75, + 0x4d, 0xae, 0x3d, 0xde, 0xe6, 0x05, 0xdd, 0x3e, 0x06, 0xe5, + 0x76, 0x95, 0xad, 0x4e, 0x31, 0xd2, 0xea, 0x09, 0x9a, 0x79, + 0x41, 0xa2, 0x7a, 0x99, 0xa1, 0x42, 0xd1, 0x32, 0x0a, 0xe9, + 0xa7, 0x44, 0x7c, 0x9f, 0x0c, 0xef, 0xd7, 0x34, 0xec, 0x0f, + 0x37, 0xd4, 0x47, 0xa4, 0x9c, 0x7f, 0x62, 0x81, 0xb9, 0x5a, + 0xc9, 0x2a, 0x12, 0xf1, 0x29, 0xca, 0xf2, 0x11, 0x82, 0x61, + 0x59, 0xba, 0xf4, 0x17, 0x2f, 0xcc, 0x5f, 0xbc, 0x84, 0x67, + 0xbf, 0x5c, 0x64, 0x87, 0x14, 0xf7, 0xcf, 0x2c, 0x53, 0xb0, + 0x88, 0x6b, 0xf8, 0x1b, 0x23, 0xc0, 0x18, 0xfb, 0xc3, 0x20, + 0xb3, 0x50, 0x68, 0x8b, 0xc5, 0x26, 0x1e, 0xfd, 0x6e, 0x8d, + 0xb5, 0x56, 0x8e, 0x6d, 0x55, 0xb6, 0x25, 0xc6, 0xfe, 0x1d, + 0xc4, 0x27, 0x1f, 0xfc, 0x6f, 0x8c, 0xb4, 0x57, 0x8f, 0x6c, + 0x54, 0xb7, 0x24, 0xc7, 0xff, 0x1c, 0x52, 0xb1, 0x89, 0x6a, + 0xf9, 0x1a, 0x22, 0xc1, 0x19, 0xfa, 0xc2, 0x21, 0xb2, 0x51, + 0x69, 0x8a, 0xf5, 0x16, 0x2e, 0xcd, 0x5e, 0xbd, 0x85, 0x66, + 0xbe, 0x5d, 0x65, 0x86, 0x15, 0xf6, 0xce, 0x2d, 0x63, 0x80, + 0xb8, 0x5b, 0xc8, 0x2b, 0x13, 0xf0, 0x28, 0xcb, 0xf3, 0x10, + 0x83, 0x60, 0x58, 0xbb, 0xa6, 0x45, 0x7d, 0x9e, 0x0d, 0xee, + 0xd6, 0x35, 0xed, 0x0e, 0x36, 0xd5, 0x46, 0xa5, 0x9d, 0x7e, + 0x30, 0xd3, 0xeb, 0x08, 0x9b, 0x78, 0x40, 0xa3, 0x7b, 0x98, + 0xa0, 0x43, 0xd0, 0x33, 0x0b, 0xe8, 0x97, 0x74, 0x4c, 0xaf, + 0x3c, 0xdf, 0xe7, 0x04, 0xdc, 0x3f, 0x07, 0xe4, 0x77, 0x94, + 0xac, 0x4f, 0x01, 0xe2, 0xda, 0x39, 0xaa, 0x49, 0x71, 0x92, + 0x4a, 0xa9, 0x91, 0x72, 0xe1, 0x02, 0x3a, 0xd9, 0x00, 0xe4, + 0xd5, 0x31, 0xb7, 0x53, 0x62, 0x86, 0x73, 0x97, 0xa6, 0x42, + 0xc4, 0x20, 0x11, 0xf5, 0xe6, 0x02, 0x33, 0xd7, 0x51, 0xb5, + 0x84, 0x60, 0x95, 0x71, 0x40, 0xa4, 0x22, 0xc6, 0xf7, 0x13, + 0xd1, 0x35, 0x04, 0xe0, 0x66, 0x82, 0xb3, 0x57, 0xa2, 0x46, + 0x77, 0x93, 0x15, 0xf1, 0xc0, 0x24, 0x37, 0xd3, 0xe2, 0x06, + 0x80, 0x64, 0x55, 0xb1, 0x44, 0xa0, 0x91, 0x75, 0xf3, 0x17, + 0x26, 0xc2, 0xbf, 0x5b, 0x6a, 0x8e, 0x08, 0xec, 0xdd, 0x39, + 0xcc, 0x28, 0x19, 0xfd, 0x7b, 0x9f, 0xae, 0x4a, 0x59, 0xbd, + 0x8c, 0x68, 0xee, 0x0a, 0x3b, 0xdf, 0x2a, 0xce, 0xff, 0x1b, + 0x9d, 0x79, 0x48, 0xac, 0x6e, 0x8a, 0xbb, 0x5f, 0xd9, 0x3d, + 0x0c, 0xe8, 0x1d, 0xf9, 0xc8, 0x2c, 0xaa, 0x4e, 0x7f, 0x9b, + 0x88, 0x6c, 0x5d, 0xb9, 0x3f, 0xdb, 0xea, 0x0e, 0xfb, 0x1f, + 0x2e, 0xca, 0x4c, 0xa8, 0x99, 0x7d, 0x63, 0x87, 0xb6, 0x52, + 0xd4, 0x30, 0x01, 0xe5, 0x10, 0xf4, 0xc5, 0x21, 0xa7, 0x43, + 0x72, 0x96, 0x85, 0x61, 0x50, 0xb4, 0x32, 0xd6, 0xe7, 0x03, + 0xf6, 0x12, 0x23, 0xc7, 0x41, 0xa5, 0x94, 0x70, 0xb2, 0x56, + 0x67, 0x83, 0x05, 0xe1, 0xd0, 0x34, 0xc1, 0x25, 0x14, 0xf0, + 0x76, 0x92, 0xa3, 0x47, 0x54, 0xb0, 0x81, 0x65, 0xe3, 0x07, + 0x36, 0xd2, 0x27, 0xc3, 0xf2, 0x16, 0x90, 0x74, 0x45, 0xa1, + 0xdc, 0x38, 0x09, 0xed, 0x6b, 0x8f, 0xbe, 0x5a, 0xaf, 0x4b, + 0x7a, 0x9e, 0x18, 0xfc, 0xcd, 0x29, 0x3a, 0xde, 0xef, 0x0b, + 0x8d, 0x69, 0x58, 0xbc, 0x49, 0xad, 0x9c, 0x78, 0xfe, 0x1a, + 0x2b, 0xcf, 0x0d, 0xe9, 0xd8, 0x3c, 0xba, 0x5e, 0x6f, 0x8b, + 0x7e, 0x9a, 0xab, 0x4f, 0xc9, 0x2d, 0x1c, 0xf8, 0xeb, 0x0f, + 0x3e, 0xda, 0x5c, 0xb8, 0x89, 0x6d, 0x98, 0x7c, 0x4d, 0xa9, + 0x2f, 0xcb, 0xfa, 0x1e, 0x00, 0xe5, 0xd7, 0x32, 0xb3, 0x56, + 0x64, 0x81, 0x7b, 0x9e, 0xac, 0x49, 0xc8, 0x2d, 0x1f, 0xfa, + 0xf6, 0x13, 0x21, 0xc4, 0x45, 0xa0, 0x92, 0x77, 0x8d, 0x68, + 0x5a, 0xbf, 0x3e, 0xdb, 0xe9, 0x0c, 0xf1, 0x14, 0x26, 0xc3, + 0x42, 0xa7, 0x95, 0x70, 0x8a, 0x6f, 0x5d, 0xb8, 0x39, 0xdc, + 0xee, 0x0b, 0x07, 0xe2, 0xd0, 0x35, 0xb4, 0x51, 0x63, 0x86, + 0x7c, 0x99, 0xab, 0x4e, 0xcf, 0x2a, 0x18, 0xfd, 0xff, 0x1a, + 0x28, 0xcd, 0x4c, 0xa9, 0x9b, 0x7e, 0x84, 0x61, 0x53, 0xb6, + 0x37, 0xd2, 0xe0, 0x05, 0x09, 0xec, 0xde, 0x3b, 0xba, 0x5f, + 0x6d, 0x88, 0x72, 0x97, 0xa5, 0x40, 0xc1, 0x24, 0x16, 0xf3, + 0x0e, 0xeb, 0xd9, 0x3c, 0xbd, 0x58, 0x6a, 0x8f, 0x75, 0x90, + 0xa2, 0x47, 0xc6, 0x23, 0x11, 0xf4, 0xf8, 0x1d, 0x2f, 0xca, + 0x4b, 0xae, 0x9c, 0x79, 0x83, 0x66, 0x54, 0xb1, 0x30, 0xd5, + 0xe7, 0x02, 0xe3, 0x06, 0x34, 0xd1, 0x50, 0xb5, 0x87, 0x62, + 0x98, 0x7d, 0x4f, 0xaa, 0x2b, 0xce, 0xfc, 0x19, 0x15, 0xf0, + 0xc2, 0x27, 0xa6, 0x43, 0x71, 0x94, 0x6e, 0x8b, 0xb9, 0x5c, + 0xdd, 0x38, 0x0a, 0xef, 0x12, 0xf7, 0xc5, 0x20, 0xa1, 0x44, + 0x76, 0x93, 0x69, 0x8c, 0xbe, 0x5b, 0xda, 0x3f, 0x0d, 0xe8, + 0xe4, 0x01, 0x33, 0xd6, 0x57, 0xb2, 0x80, 0x65, 0x9f, 0x7a, + 0x48, 0xad, 0x2c, 0xc9, 0xfb, 0x1e, 0x1c, 0xf9, 0xcb, 0x2e, + 0xaf, 0x4a, 0x78, 0x9d, 0x67, 0x82, 0xb0, 0x55, 0xd4, 0x31, + 0x03, 0xe6, 0xea, 0x0f, 0x3d, 0xd8, 0x59, 0xbc, 0x8e, 0x6b, + 0x91, 0x74, 0x46, 0xa3, 0x22, 0xc7, 0xf5, 0x10, 0xed, 0x08, + 0x3a, 0xdf, 0x5e, 0xbb, 0x89, 0x6c, 0x96, 0x73, 0x41, 0xa4, + 0x25, 0xc0, 0xf2, 0x17, 0x1b, 0xfe, 0xcc, 0x29, 0xa8, 0x4d, + 0x7f, 0x9a, 0x60, 0x85, 0xb7, 0x52, 0xd3, 0x36, 0x04, 0xe1, + 0x00, 0xe6, 0xd1, 0x37, 0xbf, 0x59, 0x6e, 0x88, 0x63, 0x85, + 0xb2, 0x54, 0xdc, 0x3a, 0x0d, 0xeb, 0xc6, 0x20, 0x17, 0xf1, + 0x79, 0x9f, 0xa8, 0x4e, 0xa5, 0x43, 0x74, 0x92, 0x1a, 0xfc, + 0xcb, 0x2d, 0x91, 0x77, 0x40, 0xa6, 0x2e, 0xc8, 0xff, 0x19, + 0xf2, 0x14, 0x23, 0xc5, 0x4d, 0xab, 0x9c, 0x7a, 0x57, 0xb1, + 0x86, 0x60, 0xe8, 0x0e, 0x39, 0xdf, 0x34, 0xd2, 0xe5, 0x03, + 0x8b, 0x6d, 0x5a, 0xbc, 0x3f, 0xd9, 0xee, 0x08, 0x80, 0x66, + 0x51, 0xb7, 0x5c, 0xba, 0x8d, 0x6b, 0xe3, 0x05, 0x32, 0xd4, + 0xf9, 0x1f, 0x28, 0xce, 0x46, 0xa0, 0x97, 0x71, 0x9a, 0x7c, + 0x4b, 0xad, 0x25, 0xc3, 0xf4, 0x12, 0xae, 0x48, 0x7f, 0x99, + 0x11, 0xf7, 0xc0, 0x26, 0xcd, 0x2b, 0x1c, 0xfa, 0x72, 0x94, + 0xa3, 0x45, 0x68, 0x8e, 0xb9, 0x5f, 0xd7, 0x31, 0x06, 0xe0, + 0x0b, 0xed, 0xda, 0x3c, 0xb4, 0x52, 0x65, 0x83, 0x7e, 0x98, + 0xaf, 0x49, 0xc1, 0x27, 0x10, 0xf6, 0x1d, 0xfb, 0xcc, 0x2a, + 0xa2, 0x44, 0x73, 0x95, 0xb8, 0x5e, 0x69, 0x8f, 0x07, 0xe1, + 0xd6, 0x30, 0xdb, 0x3d, 0x0a, 0xec, 0x64, 0x82, 0xb5, 0x53, + 0xef, 0x09, 0x3e, 0xd8, 0x50, 0xb6, 0x81, 0x67, 0x8c, 0x6a, + 0x5d, 0xbb, 0x33, 0xd5, 0xe2, 0x04, 0x29, 0xcf, 0xf8, 0x1e, + 0x96, 0x70, 0x47, 0xa1, 0x4a, 0xac, 0x9b, 0x7d, 0xf5, 0x13, + 0x24, 0xc2, 0x41, 0xa7, 0x90, 0x76, 0xfe, 0x18, 0x2f, 0xc9, + 0x22, 0xc4, 0xf3, 0x15, 0x9d, 0x7b, 0x4c, 0xaa, 0x87, 0x61, + 0x56, 0xb0, 0x38, 0xde, 0xe9, 0x0f, 0xe4, 0x02, 0x35, 0xd3, + 0x5b, 0xbd, 0x8a, 0x6c, 0xd0, 0x36, 0x01, 0xe7, 0x6f, 0x89, + 0xbe, 0x58, 0xb3, 0x55, 0x62, 0x84, 0x0c, 0xea, 0xdd, 0x3b, + 0x16, 0xf0, 0xc7, 0x21, 0xa9, 0x4f, 0x78, 0x9e, 0x75, 0x93, + 0xa4, 0x42, 0xca, 0x2c, 0x1b, 0xfd, 0x00, 0xe7, 0xd3, 0x34, + 0xbb, 0x5c, 0x68, 0x8f, 0x6b, 0x8c, 0xb8, 0x5f, 0xd0, 0x37, + 0x03, 0xe4, 0xd6, 0x31, 0x05, 0xe2, 0x6d, 0x8a, 0xbe, 0x59, + 0xbd, 0x5a, 0x6e, 0x89, 0x06, 0xe1, 0xd5, 0x32, 0xb1, 0x56, + 0x62, 0x85, 0x0a, 0xed, 0xd9, 0x3e, 0xda, 0x3d, 0x09, 0xee, + 0x61, 0x86, 0xb2, 0x55, 0x67, 0x80, 0xb4, 0x53, 0xdc, 0x3b, + 0x0f, 0xe8, 0x0c, 0xeb, 0xdf, 0x38, 0xb7, 0x50, 0x64, 0x83, + 0x7f, 0x98, 0xac, 0x4b, 0xc4, 0x23, 0x17, 0xf0, 0x14, 0xf3, + 0xc7, 0x20, 0xaf, 0x48, 0x7c, 0x9b, 0xa9, 0x4e, 0x7a, 0x9d, + 0x12, 0xf5, 0xc1, 0x26, 0xc2, 0x25, 0x11, 0xf6, 0x79, 0x9e, + 0xaa, 0x4d, 0xce, 0x29, 0x1d, 0xfa, 0x75, 0x92, 0xa6, 0x41, + 0xa5, 0x42, 0x76, 0x91, 0x1e, 0xf9, 0xcd, 0x2a, 0x18, 0xff, + 0xcb, 0x2c, 0xa3, 0x44, 0x70, 0x97, 0x73, 0x94, 0xa0, 0x47, + 0xc8, 0x2f, 0x1b, 0xfc, 0xfe, 0x19, 0x2d, 0xca, 0x45, 0xa2, + 0x96, 0x71, 0x95, 0x72, 0x46, 0xa1, 0x2e, 0xc9, 0xfd, 0x1a, + 0x28, 0xcf, 0xfb, 0x1c, 0x93, 0x74, 0x40, 0xa7, 0x43, 0xa4, + 0x90, 0x77, 0xf8, 0x1f, 0x2b, 0xcc, 0x4f, 0xa8, 0x9c, 0x7b, + 0xf4, 0x13, 0x27, 0xc0, 0x24, 0xc3, 0xf7, 0x10, 0x9f, 0x78, + 0x4c, 0xab, 0x99, 0x7e, 0x4a, 0xad, 0x22, 0xc5, 0xf1, 0x16, + 0xf2, 0x15, 0x21, 0xc6, 0x49, 0xae, 0x9a, 0x7d, 0x81, 0x66, + 0x52, 0xb5, 0x3a, 0xdd, 0xe9, 0x0e, 0xea, 0x0d, 0x39, 0xde, + 0x51, 0xb6, 0x82, 0x65, 0x57, 0xb0, 0x84, 0x63, 0xec, 0x0b, + 0x3f, 0xd8, 0x3c, 0xdb, 0xef, 0x08, 0x87, 0x60, 0x54, 0xb3, + 0x30, 0xd7, 0xe3, 0x04, 0x8b, 0x6c, 0x58, 0xbf, 0x5b, 0xbc, + 0x88, 0x6f, 0xe0, 0x07, 0x33, 0xd4, 0xe6, 0x01, 0x35, 0xd2, + 0x5d, 0xba, 0x8e, 0x69, 0x8d, 0x6a, 0x5e, 0xb9, 0x36, 0xd1, + 0xe5, 0x02, 0x00, 0xe8, 0xcd, 0x25, 0x87, 0x6f, 0x4a, 0xa2, + 0x13, 0xfb, 0xde, 0x36, 0x94, 0x7c, 0x59, 0xb1, 0x26, 0xce, + 0xeb, 0x03, 0xa1, 0x49, 0x6c, 0x84, 0x35, 0xdd, 0xf8, 0x10, + 0xb2, 0x5a, 0x7f, 0x97, 0x4c, 0xa4, 0x81, 0x69, 0xcb, 0x23, + 0x06, 0xee, 0x5f, 0xb7, 0x92, 0x7a, 0xd8, 0x30, 0x15, 0xfd, + 0x6a, 0x82, 0xa7, 0x4f, 0xed, 0x05, 0x20, 0xc8, 0x79, 0x91, + 0xb4, 0x5c, 0xfe, 0x16, 0x33, 0xdb, 0x98, 0x70, 0x55, 0xbd, + 0x1f, 0xf7, 0xd2, 0x3a, 0x8b, 0x63, 0x46, 0xae, 0x0c, 0xe4, + 0xc1, 0x29, 0xbe, 0x56, 0x73, 0x9b, 0x39, 0xd1, 0xf4, 0x1c, + 0xad, 0x45, 0x60, 0x88, 0x2a, 0xc2, 0xe7, 0x0f, 0xd4, 0x3c, + 0x19, 0xf1, 0x53, 0xbb, 0x9e, 0x76, 0xc7, 0x2f, 0x0a, 0xe2, + 0x40, 0xa8, 0x8d, 0x65, 0xf2, 0x1a, 0x3f, 0xd7, 0x75, 0x9d, + 0xb8, 0x50, 0xe1, 0x09, 0x2c, 0xc4, 0x66, 0x8e, 0xab, 0x43, + 0x2d, 0xc5, 0xe0, 0x08, 0xaa, 0x42, 0x67, 0x8f, 0x3e, 0xd6, + 0xf3, 0x1b, 0xb9, 0x51, 0x74, 0x9c, 0x0b, 0xe3, 0xc6, 0x2e, + 0x8c, 0x64, 0x41, 0xa9, 0x18, 0xf0, 0xd5, 0x3d, 0x9f, 0x77, + 0x52, 0xba, 0x61, 0x89, 0xac, 0x44, 0xe6, 0x0e, 0x2b, 0xc3, + 0x72, 0x9a, 0xbf, 0x57, 0xf5, 0x1d, 0x38, 0xd0, 0x47, 0xaf, + 0x8a, 0x62, 0xc0, 0x28, 0x0d, 0xe5, 0x54, 0xbc, 0x99, 0x71, + 0xd3, 0x3b, 0x1e, 0xf6, 0xb5, 0x5d, 0x78, 0x90, 0x32, 0xda, + 0xff, 0x17, 0xa6, 0x4e, 0x6b, 0x83, 0x21, 0xc9, 0xec, 0x04, + 0x93, 0x7b, 0x5e, 0xb6, 0x14, 0xfc, 0xd9, 0x31, 0x80, 0x68, + 0x4d, 0xa5, 0x07, 0xef, 0xca, 0x22, 0xf9, 0x11, 0x34, 0xdc, + 0x7e, 0x96, 0xb3, 0x5b, 0xea, 0x02, 0x27, 0xcf, 0x6d, 0x85, + 0xa0, 0x48, 0xdf, 0x37, 0x12, 0xfa, 0x58, 0xb0, 0x95, 0x7d, + 0xcc, 0x24, 0x01, 0xe9, 0x4b, 0xa3, 0x86, 0x6e, 0x00, 0xe9, + 0xcf, 0x26, 0x83, 0x6a, 0x4c, 0xa5, 0x1b, 0xf2, 0xd4, 0x3d, + 0x98, 0x71, 0x57, 0xbe, 0x36, 0xdf, 0xf9, 0x10, 0xb5, 0x5c, + 0x7a, 0x93, 0x2d, 0xc4, 0xe2, 0x0b, 0xae, 0x47, 0x61, 0x88, + 0x6c, 0x85, 0xa3, 0x4a, 0xef, 0x06, 0x20, 0xc9, 0x77, 0x9e, + 0xb8, 0x51, 0xf4, 0x1d, 0x3b, 0xd2, 0x5a, 0xb3, 0x95, 0x7c, + 0xd9, 0x30, 0x16, 0xff, 0x41, 0xa8, 0x8e, 0x67, 0xc2, 0x2b, + 0x0d, 0xe4, 0xd8, 0x31, 0x17, 0xfe, 0x5b, 0xb2, 0x94, 0x7d, + 0xc3, 0x2a, 0x0c, 0xe5, 0x40, 0xa9, 0x8f, 0x66, 0xee, 0x07, + 0x21, 0xc8, 0x6d, 0x84, 0xa2, 0x4b, 0xf5, 0x1c, 0x3a, 0xd3, + 0x76, 0x9f, 0xb9, 0x50, 0xb4, 0x5d, 0x7b, 0x92, 0x37, 0xde, + 0xf8, 0x11, 0xaf, 0x46, 0x60, 0x89, 0x2c, 0xc5, 0xe3, 0x0a, + 0x82, 0x6b, 0x4d, 0xa4, 0x01, 0xe8, 0xce, 0x27, 0x99, 0x70, + 0x56, 0xbf, 0x1a, 0xf3, 0xd5, 0x3c, 0xad, 0x44, 0x62, 0x8b, + 0x2e, 0xc7, 0xe1, 0x08, 0xb6, 0x5f, 0x79, 0x90, 0x35, 0xdc, + 0xfa, 0x13, 0x9b, 0x72, 0x54, 0xbd, 0x18, 0xf1, 0xd7, 0x3e, + 0x80, 0x69, 0x4f, 0xa6, 0x03, 0xea, 0xcc, 0x25, 0xc1, 0x28, + 0x0e, 0xe7, 0x42, 0xab, 0x8d, 0x64, 0xda, 0x33, 0x15, 0xfc, + 0x59, 0xb0, 0x96, 0x7f, 0xf7, 0x1e, 0x38, 0xd1, 0x74, 0x9d, + 0xbb, 0x52, 0xec, 0x05, 0x23, 0xca, 0x6f, 0x86, 0xa0, 0x49, + 0x75, 0x9c, 0xba, 0x53, 0xf6, 0x1f, 0x39, 0xd0, 0x6e, 0x87, + 0xa1, 0x48, 0xed, 0x04, 0x22, 0xcb, 0x43, 0xaa, 0x8c, 0x65, + 0xc0, 0x29, 0x0f, 0xe6, 0x58, 0xb1, 0x97, 0x7e, 0xdb, 0x32, + 0x14, 0xfd, 0x19, 0xf0, 0xd6, 0x3f, 0x9a, 0x73, 0x55, 0xbc, + 0x02, 0xeb, 0xcd, 0x24, 0x81, 0x68, 0x4e, 0xa7, 0x2f, 0xc6, + 0xe0, 0x09, 0xac, 0x45, 0x63, 0x8a, 0x34, 0xdd, 0xfb, 0x12, + 0xb7, 0x5e, 0x78, 0x91, 0x00, 0xea, 0xc9, 0x23, 0x8f, 0x65, + 0x46, 0xac, 0x03, 0xe9, 0xca, 0x20, 0x8c, 0x66, 0x45, 0xaf, + 0x06, 0xec, 0xcf, 0x25, 0x89, 0x63, 0x40, 0xaa, 0x05, 0xef, + 0xcc, 0x26, 0x8a, 0x60, 0x43, 0xa9, 0x0c, 0xe6, 0xc5, 0x2f, + 0x83, 0x69, 0x4a, 0xa0, 0x0f, 0xe5, 0xc6, 0x2c, 0x80, 0x6a, + 0x49, 0xa3, 0x0a, 0xe0, 0xc3, 0x29, 0x85, 0x6f, 0x4c, 0xa6, + 0x09, 0xe3, 0xc0, 0x2a, 0x86, 0x6c, 0x4f, 0xa5, 0x18, 0xf2, + 0xd1, 0x3b, 0x97, 0x7d, 0x5e, 0xb4, 0x1b, 0xf1, 0xd2, 0x38, + 0x94, 0x7e, 0x5d, 0xb7, 0x1e, 0xf4, 0xd7, 0x3d, 0x91, 0x7b, + 0x58, 0xb2, 0x1d, 0xf7, 0xd4, 0x3e, 0x92, 0x78, 0x5b, 0xb1, + 0x14, 0xfe, 0xdd, 0x37, 0x9b, 0x71, 0x52, 0xb8, 0x17, 0xfd, + 0xde, 0x34, 0x98, 0x72, 0x51, 0xbb, 0x12, 0xf8, 0xdb, 0x31, + 0x9d, 0x77, 0x54, 0xbe, 0x11, 0xfb, 0xd8, 0x32, 0x9e, 0x74, + 0x57, 0xbd, 0x30, 0xda, 0xf9, 0x13, 0xbf, 0x55, 0x76, 0x9c, + 0x33, 0xd9, 0xfa, 0x10, 0xbc, 0x56, 0x75, 0x9f, 0x36, 0xdc, + 0xff, 0x15, 0xb9, 0x53, 0x70, 0x9a, 0x35, 0xdf, 0xfc, 0x16, + 0xba, 0x50, 0x73, 0x99, 0x3c, 0xd6, 0xf5, 0x1f, 0xb3, 0x59, + 0x7a, 0x90, 0x3f, 0xd5, 0xf6, 0x1c, 0xb0, 0x5a, 0x79, 0x93, + 0x3a, 0xd0, 0xf3, 0x19, 0xb5, 0x5f, 0x7c, 0x96, 0x39, 0xd3, + 0xf0, 0x1a, 0xb6, 0x5c, 0x7f, 0x95, 0x28, 0xc2, 0xe1, 0x0b, + 0xa7, 0x4d, 0x6e, 0x84, 0x2b, 0xc1, 0xe2, 0x08, 0xa4, 0x4e, + 0x6d, 0x87, 0x2e, 0xc4, 0xe7, 0x0d, 0xa1, 0x4b, 0x68, 0x82, + 0x2d, 0xc7, 0xe4, 0x0e, 0xa2, 0x48, 0x6b, 0x81, 0x24, 0xce, + 0xed, 0x07, 0xab, 0x41, 0x62, 0x88, 0x27, 0xcd, 0xee, 0x04, + 0xa8, 0x42, 0x61, 0x8b, 0x22, 0xc8, 0xeb, 0x01, 0xad, 0x47, + 0x64, 0x8e, 0x21, 0xcb, 0xe8, 0x02, 0xae, 0x44, 0x67, 0x8d, + 0x00, 0xeb, 0xcb, 0x20, 0x8b, 0x60, 0x40, 0xab, 0x0b, 0xe0, + 0xc0, 0x2b, 0x80, 0x6b, 0x4b, 0xa0, 0x16, 0xfd, 0xdd, 0x36, + 0x9d, 0x76, 0x56, 0xbd, 0x1d, 0xf6, 0xd6, 0x3d, 0x96, 0x7d, + 0x5d, 0xb6, 0x2c, 0xc7, 0xe7, 0x0c, 0xa7, 0x4c, 0x6c, 0x87, + 0x27, 0xcc, 0xec, 0x07, 0xac, 0x47, 0x67, 0x8c, 0x3a, 0xd1, + 0xf1, 0x1a, 0xb1, 0x5a, 0x7a, 0x91, 0x31, 0xda, 0xfa, 0x11, + 0xba, 0x51, 0x71, 0x9a, 0x58, 0xb3, 0x93, 0x78, 0xd3, 0x38, + 0x18, 0xf3, 0x53, 0xb8, 0x98, 0x73, 0xd8, 0x33, 0x13, 0xf8, + 0x4e, 0xa5, 0x85, 0x6e, 0xc5, 0x2e, 0x0e, 0xe5, 0x45, 0xae, + 0x8e, 0x65, 0xce, 0x25, 0x05, 0xee, 0x74, 0x9f, 0xbf, 0x54, + 0xff, 0x14, 0x34, 0xdf, 0x7f, 0x94, 0xb4, 0x5f, 0xf4, 0x1f, + 0x3f, 0xd4, 0x62, 0x89, 0xa9, 0x42, 0xe9, 0x02, 0x22, 0xc9, + 0x69, 0x82, 0xa2, 0x49, 0xe2, 0x09, 0x29, 0xc2, 0xb0, 0x5b, + 0x7b, 0x90, 0x3b, 0xd0, 0xf0, 0x1b, 0xbb, 0x50, 0x70, 0x9b, + 0x30, 0xdb, 0xfb, 0x10, 0xa6, 0x4d, 0x6d, 0x86, 0x2d, 0xc6, + 0xe6, 0x0d, 0xad, 0x46, 0x66, 0x8d, 0x26, 0xcd, 0xed, 0x06, + 0x9c, 0x77, 0x57, 0xbc, 0x17, 0xfc, 0xdc, 0x37, 0x97, 0x7c, + 0x5c, 0xb7, 0x1c, 0xf7, 0xd7, 0x3c, 0x8a, 0x61, 0x41, 0xaa, + 0x01, 0xea, 0xca, 0x21, 0x81, 0x6a, 0x4a, 0xa1, 0x0a, 0xe1, + 0xc1, 0x2a, 0xe8, 0x03, 0x23, 0xc8, 0x63, 0x88, 0xa8, 0x43, + 0xe3, 0x08, 0x28, 0xc3, 0x68, 0x83, 0xa3, 0x48, 0xfe, 0x15, + 0x35, 0xde, 0x75, 0x9e, 0xbe, 0x55, 0xf5, 0x1e, 0x3e, 0xd5, + 0x7e, 0x95, 0xb5, 0x5e, 0xc4, 0x2f, 0x0f, 0xe4, 0x4f, 0xa4, + 0x84, 0x6f, 0xcf, 0x24, 0x04, 0xef, 0x44, 0xaf, 0x8f, 0x64, + 0xd2, 0x39, 0x19, 0xf2, 0x59, 0xb2, 0x92, 0x79, 0xd9, 0x32, + 0x12, 0xf9, 0x52, 0xb9, 0x99, 0x72, 0x00, 0xec, 0xc5, 0x29, + 0x97, 0x7b, 0x52, 0xbe, 0x33, 0xdf, 0xf6, 0x1a, 0xa4, 0x48, + 0x61, 0x8d, 0x66, 0x8a, 0xa3, 0x4f, 0xf1, 0x1d, 0x34, 0xd8, + 0x55, 0xb9, 0x90, 0x7c, 0xc2, 0x2e, 0x07, 0xeb, 0xcc, 0x20, + 0x09, 0xe5, 0x5b, 0xb7, 0x9e, 0x72, 0xff, 0x13, 0x3a, 0xd6, + 0x68, 0x84, 0xad, 0x41, 0xaa, 0x46, 0x6f, 0x83, 0x3d, 0xd1, + 0xf8, 0x14, 0x99, 0x75, 0x5c, 0xb0, 0x0e, 0xe2, 0xcb, 0x27, + 0x85, 0x69, 0x40, 0xac, 0x12, 0xfe, 0xd7, 0x3b, 0xb6, 0x5a, + 0x73, 0x9f, 0x21, 0xcd, 0xe4, 0x08, 0xe3, 0x0f, 0x26, 0xca, + 0x74, 0x98, 0xb1, 0x5d, 0xd0, 0x3c, 0x15, 0xf9, 0x47, 0xab, + 0x82, 0x6e, 0x49, 0xa5, 0x8c, 0x60, 0xde, 0x32, 0x1b, 0xf7, + 0x7a, 0x96, 0xbf, 0x53, 0xed, 0x01, 0x28, 0xc4, 0x2f, 0xc3, + 0xea, 0x06, 0xb8, 0x54, 0x7d, 0x91, 0x1c, 0xf0, 0xd9, 0x35, + 0x8b, 0x67, 0x4e, 0xa2, 0x17, 0xfb, 0xd2, 0x3e, 0x80, 0x6c, + 0x45, 0xa9, 0x24, 0xc8, 0xe1, 0x0d, 0xb3, 0x5f, 0x76, 0x9a, + 0x71, 0x9d, 0xb4, 0x58, 0xe6, 0x0a, 0x23, 0xcf, 0x42, 0xae, + 0x87, 0x6b, 0xd5, 0x39, 0x10, 0xfc, 0xdb, 0x37, 0x1e, 0xf2, + 0x4c, 0xa0, 0x89, 0x65, 0xe8, 0x04, 0x2d, 0xc1, 0x7f, 0x93, + 0xba, 0x56, 0xbd, 0x51, 0x78, 0x94, 0x2a, 0xc6, 0xef, 0x03, + 0x8e, 0x62, 0x4b, 0xa7, 0x19, 0xf5, 0xdc, 0x30, 0x92, 0x7e, + 0x57, 0xbb, 0x05, 0xe9, 0xc0, 0x2c, 0xa1, 0x4d, 0x64, 0x88, + 0x36, 0xda, 0xf3, 0x1f, 0xf4, 0x18, 0x31, 0xdd, 0x63, 0x8f, + 0xa6, 0x4a, 0xc7, 0x2b, 0x02, 0xee, 0x50, 0xbc, 0x95, 0x79, + 0x5e, 0xb2, 0x9b, 0x77, 0xc9, 0x25, 0x0c, 0xe0, 0x6d, 0x81, + 0xa8, 0x44, 0xfa, 0x16, 0x3f, 0xd3, 0x38, 0xd4, 0xfd, 0x11, + 0xaf, 0x43, 0x6a, 0x86, 0x0b, 0xe7, 0xce, 0x22, 0x9c, 0x70, + 0x59, 0xb5, 0x00, 0xed, 0xc7, 0x2a, 0x93, 0x7e, 0x54, 0xb9, + 0x3b, 0xd6, 0xfc, 0x11, 0xa8, 0x45, 0x6f, 0x82, 0x76, 0x9b, + 0xb1, 0x5c, 0xe5, 0x08, 0x22, 0xcf, 0x4d, 0xa0, 0x8a, 0x67, + 0xde, 0x33, 0x19, 0xf4, 0xec, 0x01, 0x2b, 0xc6, 0x7f, 0x92, + 0xb8, 0x55, 0xd7, 0x3a, 0x10, 0xfd, 0x44, 0xa9, 0x83, 0x6e, + 0x9a, 0x77, 0x5d, 0xb0, 0x09, 0xe4, 0xce, 0x23, 0xa1, 0x4c, + 0x66, 0x8b, 0x32, 0xdf, 0xf5, 0x18, 0xc5, 0x28, 0x02, 0xef, + 0x56, 0xbb, 0x91, 0x7c, 0xfe, 0x13, 0x39, 0xd4, 0x6d, 0x80, + 0xaa, 0x47, 0xb3, 0x5e, 0x74, 0x99, 0x20, 0xcd, 0xe7, 0x0a, + 0x88, 0x65, 0x4f, 0xa2, 0x1b, 0xf6, 0xdc, 0x31, 0x29, 0xc4, + 0xee, 0x03, 0xba, 0x57, 0x7d, 0x90, 0x12, 0xff, 0xd5, 0x38, + 0x81, 0x6c, 0x46, 0xab, 0x5f, 0xb2, 0x98, 0x75, 0xcc, 0x21, + 0x0b, 0xe6, 0x64, 0x89, 0xa3, 0x4e, 0xf7, 0x1a, 0x30, 0xdd, + 0x97, 0x7a, 0x50, 0xbd, 0x04, 0xe9, 0xc3, 0x2e, 0xac, 0x41, + 0x6b, 0x86, 0x3f, 0xd2, 0xf8, 0x15, 0xe1, 0x0c, 0x26, 0xcb, + 0x72, 0x9f, 0xb5, 0x58, 0xda, 0x37, 0x1d, 0xf0, 0x49, 0xa4, + 0x8e, 0x63, 0x7b, 0x96, 0xbc, 0x51, 0xe8, 0x05, 0x2f, 0xc2, + 0x40, 0xad, 0x87, 0x6a, 0xd3, 0x3e, 0x14, 0xf9, 0x0d, 0xe0, + 0xca, 0x27, 0x9e, 0x73, 0x59, 0xb4, 0x36, 0xdb, 0xf1, 0x1c, + 0xa5, 0x48, 0x62, 0x8f, 0x52, 0xbf, 0x95, 0x78, 0xc1, 0x2c, + 0x06, 0xeb, 0x69, 0x84, 0xae, 0x43, 0xfa, 0x17, 0x3d, 0xd0, + 0x24, 0xc9, 0xe3, 0x0e, 0xb7, 0x5a, 0x70, 0x9d, 0x1f, 0xf2, + 0xd8, 0x35, 0x8c, 0x61, 0x4b, 0xa6, 0xbe, 0x53, 0x79, 0x94, + 0x2d, 0xc0, 0xea, 0x07, 0x85, 0x68, 0x42, 0xaf, 0x16, 0xfb, + 0xd1, 0x3c, 0xc8, 0x25, 0x0f, 0xe2, 0x5b, 0xb6, 0x9c, 0x71, + 0xf3, 0x1e, 0x34, 0xd9, 0x60, 0x8d, 0xa7, 0x4a, 0x00, 0xee, + 0xc1, 0x2f, 0x9f, 0x71, 0x5e, 0xb0, 0x23, 0xcd, 0xe2, 0x0c, + 0xbc, 0x52, 0x7d, 0x93, 0x46, 0xa8, 0x87, 0x69, 0xd9, 0x37, + 0x18, 0xf6, 0x65, 0x8b, 0xa4, 0x4a, 0xfa, 0x14, 0x3b, 0xd5, + 0x8c, 0x62, 0x4d, 0xa3, 0x13, 0xfd, 0xd2, 0x3c, 0xaf, 0x41, + 0x6e, 0x80, 0x30, 0xde, 0xf1, 0x1f, 0xca, 0x24, 0x0b, 0xe5, + 0x55, 0xbb, 0x94, 0x7a, 0xe9, 0x07, 0x28, 0xc6, 0x76, 0x98, + 0xb7, 0x59, 0x05, 0xeb, 0xc4, 0x2a, 0x9a, 0x74, 0x5b, 0xb5, + 0x26, 0xc8, 0xe7, 0x09, 0xb9, 0x57, 0x78, 0x96, 0x43, 0xad, + 0x82, 0x6c, 0xdc, 0x32, 0x1d, 0xf3, 0x60, 0x8e, 0xa1, 0x4f, + 0xff, 0x11, 0x3e, 0xd0, 0x89, 0x67, 0x48, 0xa6, 0x16, 0xf8, + 0xd7, 0x39, 0xaa, 0x44, 0x6b, 0x85, 0x35, 0xdb, 0xf4, 0x1a, + 0xcf, 0x21, 0x0e, 0xe0, 0x50, 0xbe, 0x91, 0x7f, 0xec, 0x02, + 0x2d, 0xc3, 0x73, 0x9d, 0xb2, 0x5c, 0x0a, 0xe4, 0xcb, 0x25, + 0x95, 0x7b, 0x54, 0xba, 0x29, 0xc7, 0xe8, 0x06, 0xb6, 0x58, + 0x77, 0x99, 0x4c, 0xa2, 0x8d, 0x63, 0xd3, 0x3d, 0x12, 0xfc, + 0x6f, 0x81, 0xae, 0x40, 0xf0, 0x1e, 0x31, 0xdf, 0x86, 0x68, + 0x47, 0xa9, 0x19, 0xf7, 0xd8, 0x36, 0xa5, 0x4b, 0x64, 0x8a, + 0x3a, 0xd4, 0xfb, 0x15, 0xc0, 0x2e, 0x01, 0xef, 0x5f, 0xb1, + 0x9e, 0x70, 0xe3, 0x0d, 0x22, 0xcc, 0x7c, 0x92, 0xbd, 0x53, + 0x0f, 0xe1, 0xce, 0x20, 0x90, 0x7e, 0x51, 0xbf, 0x2c, 0xc2, + 0xed, 0x03, 0xb3, 0x5d, 0x72, 0x9c, 0x49, 0xa7, 0x88, 0x66, + 0xd6, 0x38, 0x17, 0xf9, 0x6a, 0x84, 0xab, 0x45, 0xf5, 0x1b, + 0x34, 0xda, 0x83, 0x6d, 0x42, 0xac, 0x1c, 0xf2, 0xdd, 0x33, + 0xa0, 0x4e, 0x61, 0x8f, 0x3f, 0xd1, 0xfe, 0x10, 0xc5, 0x2b, + 0x04, 0xea, 0x5a, 0xb4, 0x9b, 0x75, 0xe6, 0x08, 0x27, 0xc9, + 0x79, 0x97, 0xb8, 0x56, 0x00, 0xef, 0xc3, 0x2c, 0x9b, 0x74, + 0x58, 0xb7, 0x2b, 0xc4, 0xe8, 0x07, 0xb0, 0x5f, 0x73, 0x9c, + 0x56, 0xb9, 0x95, 0x7a, 0xcd, 0x22, 0x0e, 0xe1, 0x7d, 0x92, + 0xbe, 0x51, 0xe6, 0x09, 0x25, 0xca, 0xac, 0x43, 0x6f, 0x80, + 0x37, 0xd8, 0xf4, 0x1b, 0x87, 0x68, 0x44, 0xab, 0x1c, 0xf3, + 0xdf, 0x30, 0xfa, 0x15, 0x39, 0xd6, 0x61, 0x8e, 0xa2, 0x4d, + 0xd1, 0x3e, 0x12, 0xfd, 0x4a, 0xa5, 0x89, 0x66, 0x45, 0xaa, + 0x86, 0x69, 0xde, 0x31, 0x1d, 0xf2, 0x6e, 0x81, 0xad, 0x42, + 0xf5, 0x1a, 0x36, 0xd9, 0x13, 0xfc, 0xd0, 0x3f, 0x88, 0x67, + 0x4b, 0xa4, 0x38, 0xd7, 0xfb, 0x14, 0xa3, 0x4c, 0x60, 0x8f, + 0xe9, 0x06, 0x2a, 0xc5, 0x72, 0x9d, 0xb1, 0x5e, 0xc2, 0x2d, + 0x01, 0xee, 0x59, 0xb6, 0x9a, 0x75, 0xbf, 0x50, 0x7c, 0x93, + 0x24, 0xcb, 0xe7, 0x08, 0x94, 0x7b, 0x57, 0xb8, 0x0f, 0xe0, + 0xcc, 0x23, 0x8a, 0x65, 0x49, 0xa6, 0x11, 0xfe, 0xd2, 0x3d, + 0xa1, 0x4e, 0x62, 0x8d, 0x3a, 0xd5, 0xf9, 0x16, 0xdc, 0x33, + 0x1f, 0xf0, 0x47, 0xa8, 0x84, 0x6b, 0xf7, 0x18, 0x34, 0xdb, + 0x6c, 0x83, 0xaf, 0x40, 0x26, 0xc9, 0xe5, 0x0a, 0xbd, 0x52, + 0x7e, 0x91, 0x0d, 0xe2, 0xce, 0x21, 0x96, 0x79, 0x55, 0xba, + 0x70, 0x9f, 0xb3, 0x5c, 0xeb, 0x04, 0x28, 0xc7, 0x5b, 0xb4, + 0x98, 0x77, 0xc0, 0x2f, 0x03, 0xec, 0xcf, 0x20, 0x0c, 0xe3, + 0x54, 0xbb, 0x97, 0x78, 0xe4, 0x0b, 0x27, 0xc8, 0x7f, 0x90, + 0xbc, 0x53, 0x99, 0x76, 0x5a, 0xb5, 0x02, 0xed, 0xc1, 0x2e, + 0xb2, 0x5d, 0x71, 0x9e, 0x29, 0xc6, 0xea, 0x05, 0x63, 0x8c, + 0xa0, 0x4f, 0xf8, 0x17, 0x3b, 0xd4, 0x48, 0xa7, 0x8b, 0x64, + 0xd3, 0x3c, 0x10, 0xff, 0x35, 0xda, 0xf6, 0x19, 0xae, 0x41, + 0x6d, 0x82, 0x1e, 0xf1, 0xdd, 0x32, 0x85, 0x6a, 0x46, 0xa9, + 0x00, 0xf0, 0xfd, 0x0d, 0xe7, 0x17, 0x1a, 0xea, 0xd3, 0x23, + 0x2e, 0xde, 0x34, 0xc4, 0xc9, 0x39, 0xbb, 0x4b, 0x46, 0xb6, + 0x5c, 0xac, 0xa1, 0x51, 0x68, 0x98, 0x95, 0x65, 0x8f, 0x7f, + 0x72, 0x82, 0x6b, 0x9b, 0x96, 0x66, 0x8c, 0x7c, 0x71, 0x81, + 0xb8, 0x48, 0x45, 0xb5, 0x5f, 0xaf, 0xa2, 0x52, 0xd0, 0x20, + 0x2d, 0xdd, 0x37, 0xc7, 0xca, 0x3a, 0x03, 0xf3, 0xfe, 0x0e, + 0xe4, 0x14, 0x19, 0xe9, 0xd6, 0x26, 0x2b, 0xdb, 0x31, 0xc1, + 0xcc, 0x3c, 0x05, 0xf5, 0xf8, 0x08, 0xe2, 0x12, 0x1f, 0xef, + 0x6d, 0x9d, 0x90, 0x60, 0x8a, 0x7a, 0x77, 0x87, 0xbe, 0x4e, + 0x43, 0xb3, 0x59, 0xa9, 0xa4, 0x54, 0xbd, 0x4d, 0x40, 0xb0, + 0x5a, 0xaa, 0xa7, 0x57, 0x6e, 0x9e, 0x93, 0x63, 0x89, 0x79, + 0x74, 0x84, 0x06, 0xf6, 0xfb, 0x0b, 0xe1, 0x11, 0x1c, 0xec, + 0xd5, 0x25, 0x28, 0xd8, 0x32, 0xc2, 0xcf, 0x3f, 0xb1, 0x41, + 0x4c, 0xbc, 0x56, 0xa6, 0xab, 0x5b, 0x62, 0x92, 0x9f, 0x6f, + 0x85, 0x75, 0x78, 0x88, 0x0a, 0xfa, 0xf7, 0x07, 0xed, 0x1d, + 0x10, 0xe0, 0xd9, 0x29, 0x24, 0xd4, 0x3e, 0xce, 0xc3, 0x33, + 0xda, 0x2a, 0x27, 0xd7, 0x3d, 0xcd, 0xc0, 0x30, 0x09, 0xf9, + 0xf4, 0x04, 0xee, 0x1e, 0x13, 0xe3, 0x61, 0x91, 0x9c, 0x6c, + 0x86, 0x76, 0x7b, 0x8b, 0xb2, 0x42, 0x4f, 0xbf, 0x55, 0xa5, + 0xa8, 0x58, 0x67, 0x97, 0x9a, 0x6a, 0x80, 0x70, 0x7d, 0x8d, + 0xb4, 0x44, 0x49, 0xb9, 0x53, 0xa3, 0xae, 0x5e, 0xdc, 0x2c, + 0x21, 0xd1, 0x3b, 0xcb, 0xc6, 0x36, 0x0f, 0xff, 0xf2, 0x02, + 0xe8, 0x18, 0x15, 0xe5, 0x0c, 0xfc, 0xf1, 0x01, 0xeb, 0x1b, + 0x16, 0xe6, 0xdf, 0x2f, 0x22, 0xd2, 0x38, 0xc8, 0xc5, 0x35, + 0xb7, 0x47, 0x4a, 0xba, 0x50, 0xa0, 0xad, 0x5d, 0x64, 0x94, + 0x99, 0x69, 0x83, 0x73, 0x7e, 0x8e, 0x00, 0xf1, 0xff, 0x0e, + 0xe3, 0x12, 0x1c, 0xed, 0xdb, 0x2a, 0x24, 0xd5, 0x38, 0xc9, + 0xc7, 0x36, 0xab, 0x5a, 0x54, 0xa5, 0x48, 0xb9, 0xb7, 0x46, + 0x70, 0x81, 0x8f, 0x7e, 0x93, 0x62, 0x6c, 0x9d, 0x4b, 0xba, + 0xb4, 0x45, 0xa8, 0x59, 0x57, 0xa6, 0x90, 0x61, 0x6f, 0x9e, + 0x73, 0x82, 0x8c, 0x7d, 0xe0, 0x11, 0x1f, 0xee, 0x03, 0xf2, + 0xfc, 0x0d, 0x3b, 0xca, 0xc4, 0x35, 0xd8, 0x29, 0x27, 0xd6, + 0x96, 0x67, 0x69, 0x98, 0x75, 0x84, 0x8a, 0x7b, 0x4d, 0xbc, + 0xb2, 0x43, 0xae, 0x5f, 0x51, 0xa0, 0x3d, 0xcc, 0xc2, 0x33, + 0xde, 0x2f, 0x21, 0xd0, 0xe6, 0x17, 0x19, 0xe8, 0x05, 0xf4, + 0xfa, 0x0b, 0xdd, 0x2c, 0x22, 0xd3, 0x3e, 0xcf, 0xc1, 0x30, + 0x06, 0xf7, 0xf9, 0x08, 0xe5, 0x14, 0x1a, 0xeb, 0x76, 0x87, + 0x89, 0x78, 0x95, 0x64, 0x6a, 0x9b, 0xad, 0x5c, 0x52, 0xa3, + 0x4e, 0xbf, 0xb1, 0x40, 0x31, 0xc0, 0xce, 0x3f, 0xd2, 0x23, + 0x2d, 0xdc, 0xea, 0x1b, 0x15, 0xe4, 0x09, 0xf8, 0xf6, 0x07, + 0x9a, 0x6b, 0x65, 0x94, 0x79, 0x88, 0x86, 0x77, 0x41, 0xb0, + 0xbe, 0x4f, 0xa2, 0x53, 0x5d, 0xac, 0x7a, 0x8b, 0x85, 0x74, + 0x99, 0x68, 0x66, 0x97, 0xa1, 0x50, 0x5e, 0xaf, 0x42, 0xb3, + 0xbd, 0x4c, 0xd1, 0x20, 0x2e, 0xdf, 0x32, 0xc3, 0xcd, 0x3c, + 0x0a, 0xfb, 0xf5, 0x04, 0xe9, 0x18, 0x16, 0xe7, 0xa7, 0x56, + 0x58, 0xa9, 0x44, 0xb5, 0xbb, 0x4a, 0x7c, 0x8d, 0x83, 0x72, + 0x9f, 0x6e, 0x60, 0x91, 0x0c, 0xfd, 0xf3, 0x02, 0xef, 0x1e, + 0x10, 0xe1, 0xd7, 0x26, 0x28, 0xd9, 0x34, 0xc5, 0xcb, 0x3a, + 0xec, 0x1d, 0x13, 0xe2, 0x0f, 0xfe, 0xf0, 0x01, 0x37, 0xc6, + 0xc8, 0x39, 0xd4, 0x25, 0x2b, 0xda, 0x47, 0xb6, 0xb8, 0x49, + 0xa4, 0x55, 0x5b, 0xaa, 0x9c, 0x6d, 0x63, 0x92, 0x7f, 0x8e, + 0x80, 0x71, 0x00, 0xf2, 0xf9, 0x0b, 0xef, 0x1d, 0x16, 0xe4, + 0xc3, 0x31, 0x3a, 0xc8, 0x2c, 0xde, 0xd5, 0x27, 0x9b, 0x69, + 0x62, 0x90, 0x74, 0x86, 0x8d, 0x7f, 0x58, 0xaa, 0xa1, 0x53, + 0xb7, 0x45, 0x4e, 0xbc, 0x2b, 0xd9, 0xd2, 0x20, 0xc4, 0x36, + 0x3d, 0xcf, 0xe8, 0x1a, 0x11, 0xe3, 0x07, 0xf5, 0xfe, 0x0c, + 0xb0, 0x42, 0x49, 0xbb, 0x5f, 0xad, 0xa6, 0x54, 0x73, 0x81, + 0x8a, 0x78, 0x9c, 0x6e, 0x65, 0x97, 0x56, 0xa4, 0xaf, 0x5d, + 0xb9, 0x4b, 0x40, 0xb2, 0x95, 0x67, 0x6c, 0x9e, 0x7a, 0x88, + 0x83, 0x71, 0xcd, 0x3f, 0x34, 0xc6, 0x22, 0xd0, 0xdb, 0x29, + 0x0e, 0xfc, 0xf7, 0x05, 0xe1, 0x13, 0x18, 0xea, 0x7d, 0x8f, + 0x84, 0x76, 0x92, 0x60, 0x6b, 0x99, 0xbe, 0x4c, 0x47, 0xb5, + 0x51, 0xa3, 0xa8, 0x5a, 0xe6, 0x14, 0x1f, 0xed, 0x09, 0xfb, + 0xf0, 0x02, 0x25, 0xd7, 0xdc, 0x2e, 0xca, 0x38, 0x33, 0xc1, + 0xac, 0x5e, 0x55, 0xa7, 0x43, 0xb1, 0xba, 0x48, 0x6f, 0x9d, + 0x96, 0x64, 0x80, 0x72, 0x79, 0x8b, 0x37, 0xc5, 0xce, 0x3c, + 0xd8, 0x2a, 0x21, 0xd3, 0xf4, 0x06, 0x0d, 0xff, 0x1b, 0xe9, + 0xe2, 0x10, 0x87, 0x75, 0x7e, 0x8c, 0x68, 0x9a, 0x91, 0x63, + 0x44, 0xb6, 0xbd, 0x4f, 0xab, 0x59, 0x52, 0xa0, 0x1c, 0xee, + 0xe5, 0x17, 0xf3, 0x01, 0x0a, 0xf8, 0xdf, 0x2d, 0x26, 0xd4, + 0x30, 0xc2, 0xc9, 0x3b, 0xfa, 0x08, 0x03, 0xf1, 0x15, 0xe7, + 0xec, 0x1e, 0x39, 0xcb, 0xc0, 0x32, 0xd6, 0x24, 0x2f, 0xdd, + 0x61, 0x93, 0x98, 0x6a, 0x8e, 0x7c, 0x77, 0x85, 0xa2, 0x50, + 0x5b, 0xa9, 0x4d, 0xbf, 0xb4, 0x46, 0xd1, 0x23, 0x28, 0xda, + 0x3e, 0xcc, 0xc7, 0x35, 0x12, 0xe0, 0xeb, 0x19, 0xfd, 0x0f, + 0x04, 0xf6, 0x4a, 0xb8, 0xb3, 0x41, 0xa5, 0x57, 0x5c, 0xae, + 0x89, 0x7b, 0x70, 0x82, 0x66, 0x94, 0x9f, 0x6d, 0x00, 0xf3, + 0xfb, 0x08, 0xeb, 0x18, 0x10, 0xe3, 0xcb, 0x38, 0x30, 0xc3, + 0x20, 0xd3, 0xdb, 0x28, 0x8b, 0x78, 0x70, 0x83, 0x60, 0x93, + 0x9b, 0x68, 0x40, 0xb3, 0xbb, 0x48, 0xab, 0x58, 0x50, 0xa3, + 0x0b, 0xf8, 0xf0, 0x03, 0xe0, 0x13, 0x1b, 0xe8, 0xc0, 0x33, + 0x3b, 0xc8, 0x2b, 0xd8, 0xd0, 0x23, 0x80, 0x73, 0x7b, 0x88, + 0x6b, 0x98, 0x90, 0x63, 0x4b, 0xb8, 0xb0, 0x43, 0xa0, 0x53, + 0x5b, 0xa8, 0x16, 0xe5, 0xed, 0x1e, 0xfd, 0x0e, 0x06, 0xf5, + 0xdd, 0x2e, 0x26, 0xd5, 0x36, 0xc5, 0xcd, 0x3e, 0x9d, 0x6e, + 0x66, 0x95, 0x76, 0x85, 0x8d, 0x7e, 0x56, 0xa5, 0xad, 0x5e, + 0xbd, 0x4e, 0x46, 0xb5, 0x1d, 0xee, 0xe6, 0x15, 0xf6, 0x05, + 0x0d, 0xfe, 0xd6, 0x25, 0x2d, 0xde, 0x3d, 0xce, 0xc6, 0x35, + 0x96, 0x65, 0x6d, 0x9e, 0x7d, 0x8e, 0x86, 0x75, 0x5d, 0xae, + 0xa6, 0x55, 0xb6, 0x45, 0x4d, 0xbe, 0x2c, 0xdf, 0xd7, 0x24, + 0xc7, 0x34, 0x3c, 0xcf, 0xe7, 0x14, 0x1c, 0xef, 0x0c, 0xff, + 0xf7, 0x04, 0xa7, 0x54, 0x5c, 0xaf, 0x4c, 0xbf, 0xb7, 0x44, + 0x6c, 0x9f, 0x97, 0x64, 0x87, 0x74, 0x7c, 0x8f, 0x27, 0xd4, + 0xdc, 0x2f, 0xcc, 0x3f, 0x37, 0xc4, 0xec, 0x1f, 0x17, 0xe4, + 0x07, 0xf4, 0xfc, 0x0f, 0xac, 0x5f, 0x57, 0xa4, 0x47, 0xb4, + 0xbc, 0x4f, 0x67, 0x94, 0x9c, 0x6f, 0x8c, 0x7f, 0x77, 0x84, + 0x3a, 0xc9, 0xc1, 0x32, 0xd1, 0x22, 0x2a, 0xd9, 0xf1, 0x02, + 0x0a, 0xf9, 0x1a, 0xe9, 0xe1, 0x12, 0xb1, 0x42, 0x4a, 0xb9, + 0x5a, 0xa9, 0xa1, 0x52, 0x7a, 0x89, 0x81, 0x72, 0x91, 0x62, + 0x6a, 0x99, 0x31, 0xc2, 0xca, 0x39, 0xda, 0x29, 0x21, 0xd2, + 0xfa, 0x09, 0x01, 0xf2, 0x11, 0xe2, 0xea, 0x19, 0xba, 0x49, + 0x41, 0xb2, 0x51, 0xa2, 0xaa, 0x59, 0x71, 0x82, 0x8a, 0x79, + 0x9a, 0x69, 0x61, 0x92, 0x00, 0xf4, 0xf5, 0x01, 0xf7, 0x03, + 0x02, 0xf6, 0xf3, 0x07, 0x06, 0xf2, 0x04, 0xf0, 0xf1, 0x05, + 0xfb, 0x0f, 0x0e, 0xfa, 0x0c, 0xf8, 0xf9, 0x0d, 0x08, 0xfc, + 0xfd, 0x09, 0xff, 0x0b, 0x0a, 0xfe, 0xeb, 0x1f, 0x1e, 0xea, + 0x1c, 0xe8, 0xe9, 0x1d, 0x18, 0xec, 0xed, 0x19, 0xef, 0x1b, + 0x1a, 0xee, 0x10, 0xe4, 0xe5, 0x11, 0xe7, 0x13, 0x12, 0xe6, + 0xe3, 0x17, 0x16, 0xe2, 0x14, 0xe0, 0xe1, 0x15, 0xcb, 0x3f, + 0x3e, 0xca, 0x3c, 0xc8, 0xc9, 0x3d, 0x38, 0xcc, 0xcd, 0x39, + 0xcf, 0x3b, 0x3a, 0xce, 0x30, 0xc4, 0xc5, 0x31, 0xc7, 0x33, + 0x32, 0xc6, 0xc3, 0x37, 0x36, 0xc2, 0x34, 0xc0, 0xc1, 0x35, + 0x20, 0xd4, 0xd5, 0x21, 0xd7, 0x23, 0x22, 0xd6, 0xd3, 0x27, + 0x26, 0xd2, 0x24, 0xd0, 0xd1, 0x25, 0xdb, 0x2f, 0x2e, 0xda, + 0x2c, 0xd8, 0xd9, 0x2d, 0x28, 0xdc, 0xdd, 0x29, 0xdf, 0x2b, + 0x2a, 0xde, 0x8b, 0x7f, 0x7e, 0x8a, 0x7c, 0x88, 0x89, 0x7d, + 0x78, 0x8c, 0x8d, 0x79, 0x8f, 0x7b, 0x7a, 0x8e, 0x70, 0x84, + 0x85, 0x71, 0x87, 0x73, 0x72, 0x86, 0x83, 0x77, 0x76, 0x82, + 0x74, 0x80, 0x81, 0x75, 0x60, 0x94, 0x95, 0x61, 0x97, 0x63, + 0x62, 0x96, 0x93, 0x67, 0x66, 0x92, 0x64, 0x90, 0x91, 0x65, + 0x9b, 0x6f, 0x6e, 0x9a, 0x6c, 0x98, 0x99, 0x6d, 0x68, 0x9c, + 0x9d, 0x69, 0x9f, 0x6b, 0x6a, 0x9e, 0x40, 0xb4, 0xb5, 0x41, + 0xb7, 0x43, 0x42, 0xb6, 0xb3, 0x47, 0x46, 0xb2, 0x44, 0xb0, + 0xb1, 0x45, 0xbb, 0x4f, 0x4e, 0xba, 0x4c, 0xb8, 0xb9, 0x4d, + 0x48, 0xbc, 0xbd, 0x49, 0xbf, 0x4b, 0x4a, 0xbe, 0xab, 0x5f, + 0x5e, 0xaa, 0x5c, 0xa8, 0xa9, 0x5d, 0x58, 0xac, 0xad, 0x59, + 0xaf, 0x5b, 0x5a, 0xae, 0x50, 0xa4, 0xa5, 0x51, 0xa7, 0x53, + 0x52, 0xa6, 0xa3, 0x57, 0x56, 0xa2, 0x54, 0xa0, 0xa1, 0x55, + 0x00, 0xf5, 0xf7, 0x02, 0xf3, 0x06, 0x04, 0xf1, 0xfb, 0x0e, + 0x0c, 0xf9, 0x08, 0xfd, 0xff, 0x0a, 0xeb, 0x1e, 0x1c, 0xe9, + 0x18, 0xed, 0xef, 0x1a, 0x10, 0xe5, 0xe7, 0x12, 0xe3, 0x16, + 0x14, 0xe1, 0xcb, 0x3e, 0x3c, 0xc9, 0x38, 0xcd, 0xcf, 0x3a, + 0x30, 0xc5, 0xc7, 0x32, 0xc3, 0x36, 0x34, 0xc1, 0x20, 0xd5, + 0xd7, 0x22, 0xd3, 0x26, 0x24, 0xd1, 0xdb, 0x2e, 0x2c, 0xd9, + 0x28, 0xdd, 0xdf, 0x2a, 0x8b, 0x7e, 0x7c, 0x89, 0x78, 0x8d, + 0x8f, 0x7a, 0x70, 0x85, 0x87, 0x72, 0x83, 0x76, 0x74, 0x81, + 0x60, 0x95, 0x97, 0x62, 0x93, 0x66, 0x64, 0x91, 0x9b, 0x6e, + 0x6c, 0x99, 0x68, 0x9d, 0x9f, 0x6a, 0x40, 0xb5, 0xb7, 0x42, + 0xb3, 0x46, 0x44, 0xb1, 0xbb, 0x4e, 0x4c, 0xb9, 0x48, 0xbd, + 0xbf, 0x4a, 0xab, 0x5e, 0x5c, 0xa9, 0x58, 0xad, 0xaf, 0x5a, + 0x50, 0xa5, 0xa7, 0x52, 0xa3, 0x56, 0x54, 0xa1, 0x0b, 0xfe, + 0xfc, 0x09, 0xf8, 0x0d, 0x0f, 0xfa, 0xf0, 0x05, 0x07, 0xf2, + 0x03, 0xf6, 0xf4, 0x01, 0xe0, 0x15, 0x17, 0xe2, 0x13, 0xe6, + 0xe4, 0x11, 0x1b, 0xee, 0xec, 0x19, 0xe8, 0x1d, 0x1f, 0xea, + 0xc0, 0x35, 0x37, 0xc2, 0x33, 0xc6, 0xc4, 0x31, 0x3b, 0xce, + 0xcc, 0x39, 0xc8, 0x3d, 0x3f, 0xca, 0x2b, 0xde, 0xdc, 0x29, + 0xd8, 0x2d, 0x2f, 0xda, 0xd0, 0x25, 0x27, 0xd2, 0x23, 0xd6, + 0xd4, 0x21, 0x80, 0x75, 0x77, 0x82, 0x73, 0x86, 0x84, 0x71, + 0x7b, 0x8e, 0x8c, 0x79, 0x88, 0x7d, 0x7f, 0x8a, 0x6b, 0x9e, + 0x9c, 0x69, 0x98, 0x6d, 0x6f, 0x9a, 0x90, 0x65, 0x67, 0x92, + 0x63, 0x96, 0x94, 0x61, 0x4b, 0xbe, 0xbc, 0x49, 0xb8, 0x4d, + 0x4f, 0xba, 0xb0, 0x45, 0x47, 0xb2, 0x43, 0xb6, 0xb4, 0x41, + 0xa0, 0x55, 0x57, 0xa2, 0x53, 0xa6, 0xa4, 0x51, 0x5b, 0xae, + 0xac, 0x59, 0xa8, 0x5d, 0x5f, 0xaa, 0x00, 0xf6, 0xf1, 0x07, + 0xff, 0x09, 0x0e, 0xf8, 0xe3, 0x15, 0x12, 0xe4, 0x1c, 0xea, + 0xed, 0x1b, 0xdb, 0x2d, 0x2a, 0xdc, 0x24, 0xd2, 0xd5, 0x23, + 0x38, 0xce, 0xc9, 0x3f, 0xc7, 0x31, 0x36, 0xc0, 0xab, 0x5d, + 0x5a, 0xac, 0x54, 0xa2, 0xa5, 0x53, 0x48, 0xbe, 0xb9, 0x4f, + 0xb7, 0x41, 0x46, 0xb0, 0x70, 0x86, 0x81, 0x77, 0x8f, 0x79, + 0x7e, 0x88, 0x93, 0x65, 0x62, 0x94, 0x6c, 0x9a, 0x9d, 0x6b, + 0x4b, 0xbd, 0xba, 0x4c, 0xb4, 0x42, 0x45, 0xb3, 0xa8, 0x5e, + 0x59, 0xaf, 0x57, 0xa1, 0xa6, 0x50, 0x90, 0x66, 0x61, 0x97, + 0x6f, 0x99, 0x9e, 0x68, 0x73, 0x85, 0x82, 0x74, 0x8c, 0x7a, + 0x7d, 0x8b, 0xe0, 0x16, 0x11, 0xe7, 0x1f, 0xe9, 0xee, 0x18, + 0x03, 0xf5, 0xf2, 0x04, 0xfc, 0x0a, 0x0d, 0xfb, 0x3b, 0xcd, + 0xca, 0x3c, 0xc4, 0x32, 0x35, 0xc3, 0xd8, 0x2e, 0x29, 0xdf, + 0x27, 0xd1, 0xd6, 0x20, 0x96, 0x60, 0x67, 0x91, 0x69, 0x9f, + 0x98, 0x6e, 0x75, 0x83, 0x84, 0x72, 0x8a, 0x7c, 0x7b, 0x8d, + 0x4d, 0xbb, 0xbc, 0x4a, 0xb2, 0x44, 0x43, 0xb5, 0xae, 0x58, + 0x5f, 0xa9, 0x51, 0xa7, 0xa0, 0x56, 0x3d, 0xcb, 0xcc, 0x3a, + 0xc2, 0x34, 0x33, 0xc5, 0xde, 0x28, 0x2f, 0xd9, 0x21, 0xd7, + 0xd0, 0x26, 0xe6, 0x10, 0x17, 0xe1, 0x19, 0xef, 0xe8, 0x1e, + 0x05, 0xf3, 0xf4, 0x02, 0xfa, 0x0c, 0x0b, 0xfd, 0xdd, 0x2b, + 0x2c, 0xda, 0x22, 0xd4, 0xd3, 0x25, 0x3e, 0xc8, 0xcf, 0x39, + 0xc1, 0x37, 0x30, 0xc6, 0x06, 0xf0, 0xf7, 0x01, 0xf9, 0x0f, + 0x08, 0xfe, 0xe5, 0x13, 0x14, 0xe2, 0x1a, 0xec, 0xeb, 0x1d, + 0x76, 0x80, 0x87, 0x71, 0x89, 0x7f, 0x78, 0x8e, 0x95, 0x63, + 0x64, 0x92, 0x6a, 0x9c, 0x9b, 0x6d, 0xad, 0x5b, 0x5c, 0xaa, + 0x52, 0xa4, 0xa3, 0x55, 0x4e, 0xb8, 0xbf, 0x49, 0xb1, 0x47, + 0x40, 0xb6, 0x00, 0xf7, 0xf3, 0x04, 0xfb, 0x0c, 0x08, 0xff, + 0xeb, 0x1c, 0x18, 0xef, 0x10, 0xe7, 0xe3, 0x14, 0xcb, 0x3c, + 0x38, 0xcf, 0x30, 0xc7, 0xc3, 0x34, 0x20, 0xd7, 0xd3, 0x24, + 0xdb, 0x2c, 0x28, 0xdf, 0x8b, 0x7c, 0x78, 0x8f, 0x70, 0x87, + 0x83, 0x74, 0x60, 0x97, 0x93, 0x64, 0x9b, 0x6c, 0x68, 0x9f, + 0x40, 0xb7, 0xb3, 0x44, 0xbb, 0x4c, 0x48, 0xbf, 0xab, 0x5c, + 0x58, 0xaf, 0x50, 0xa7, 0xa3, 0x54, 0x0b, 0xfc, 0xf8, 0x0f, + 0xf0, 0x07, 0x03, 0xf4, 0xe0, 0x17, 0x13, 0xe4, 0x1b, 0xec, + 0xe8, 0x1f, 0xc0, 0x37, 0x33, 0xc4, 0x3b, 0xcc, 0xc8, 0x3f, + 0x2b, 0xdc, 0xd8, 0x2f, 0xd0, 0x27, 0x23, 0xd4, 0x80, 0x77, + 0x73, 0x84, 0x7b, 0x8c, 0x88, 0x7f, 0x6b, 0x9c, 0x98, 0x6f, + 0x90, 0x67, 0x63, 0x94, 0x4b, 0xbc, 0xb8, 0x4f, 0xb0, 0x47, + 0x43, 0xb4, 0xa0, 0x57, 0x53, 0xa4, 0x5b, 0xac, 0xa8, 0x5f, + 0x16, 0xe1, 0xe5, 0x12, 0xed, 0x1a, 0x1e, 0xe9, 0xfd, 0x0a, + 0x0e, 0xf9, 0x06, 0xf1, 0xf5, 0x02, 0xdd, 0x2a, 0x2e, 0xd9, + 0x26, 0xd1, 0xd5, 0x22, 0x36, 0xc1, 0xc5, 0x32, 0xcd, 0x3a, + 0x3e, 0xc9, 0x9d, 0x6a, 0x6e, 0x99, 0x66, 0x91, 0x95, 0x62, + 0x76, 0x81, 0x85, 0x72, 0x8d, 0x7a, 0x7e, 0x89, 0x56, 0xa1, + 0xa5, 0x52, 0xad, 0x5a, 0x5e, 0xa9, 0xbd, 0x4a, 0x4e, 0xb9, + 0x46, 0xb1, 0xb5, 0x42, 0x1d, 0xea, 0xee, 0x19, 0xe6, 0x11, + 0x15, 0xe2, 0xf6, 0x01, 0x05, 0xf2, 0x0d, 0xfa, 0xfe, 0x09, + 0xd6, 0x21, 0x25, 0xd2, 0x2d, 0xda, 0xde, 0x29, 0x3d, 0xca, + 0xce, 0x39, 0xc6, 0x31, 0x35, 0xc2, 0x96, 0x61, 0x65, 0x92, + 0x6d, 0x9a, 0x9e, 0x69, 0x7d, 0x8a, 0x8e, 0x79, 0x86, 0x71, + 0x75, 0x82, 0x5d, 0xaa, 0xae, 0x59, 0xa6, 0x51, 0x55, 0xa2, + 0xb6, 0x41, 0x45, 0xb2, 0x4d, 0xba, 0xbe, 0x49, 0x00, 0xf8, + 0xed, 0x15, 0xc7, 0x3f, 0x2a, 0xd2, 0x93, 0x6b, 0x7e, 0x86, + 0x54, 0xac, 0xb9, 0x41, 0x3b, 0xc3, 0xd6, 0x2e, 0xfc, 0x04, + 0x11, 0xe9, 0xa8, 0x50, 0x45, 0xbd, 0x6f, 0x97, 0x82, 0x7a, + 0x76, 0x8e, 0x9b, 0x63, 0xb1, 0x49, 0x5c, 0xa4, 0xe5, 0x1d, + 0x08, 0xf0, 0x22, 0xda, 0xcf, 0x37, 0x4d, 0xb5, 0xa0, 0x58, + 0x8a, 0x72, 0x67, 0x9f, 0xde, 0x26, 0x33, 0xcb, 0x19, 0xe1, + 0xf4, 0x0c, 0xec, 0x14, 0x01, 0xf9, 0x2b, 0xd3, 0xc6, 0x3e, + 0x7f, 0x87, 0x92, 0x6a, 0xb8, 0x40, 0x55, 0xad, 0xd7, 0x2f, + 0x3a, 0xc2, 0x10, 0xe8, 0xfd, 0x05, 0x44, 0xbc, 0xa9, 0x51, + 0x83, 0x7b, 0x6e, 0x96, 0x9a, 0x62, 0x77, 0x8f, 0x5d, 0xa5, + 0xb0, 0x48, 0x09, 0xf1, 0xe4, 0x1c, 0xce, 0x36, 0x23, 0xdb, + 0xa1, 0x59, 0x4c, 0xb4, 0x66, 0x9e, 0x8b, 0x73, 0x32, 0xca, + 0xdf, 0x27, 0xf5, 0x0d, 0x18, 0xe0, 0xc5, 0x3d, 0x28, 0xd0, + 0x02, 0xfa, 0xef, 0x17, 0x56, 0xae, 0xbb, 0x43, 0x91, 0x69, + 0x7c, 0x84, 0xfe, 0x06, 0x13, 0xeb, 0x39, 0xc1, 0xd4, 0x2c, + 0x6d, 0x95, 0x80, 0x78, 0xaa, 0x52, 0x47, 0xbf, 0xb3, 0x4b, + 0x5e, 0xa6, 0x74, 0x8c, 0x99, 0x61, 0x20, 0xd8, 0xcd, 0x35, + 0xe7, 0x1f, 0x0a, 0xf2, 0x88, 0x70, 0x65, 0x9d, 0x4f, 0xb7, + 0xa2, 0x5a, 0x1b, 0xe3, 0xf6, 0x0e, 0xdc, 0x24, 0x31, 0xc9, + 0x29, 0xd1, 0xc4, 0x3c, 0xee, 0x16, 0x03, 0xfb, 0xba, 0x42, + 0x57, 0xaf, 0x7d, 0x85, 0x90, 0x68, 0x12, 0xea, 0xff, 0x07, + 0xd5, 0x2d, 0x38, 0xc0, 0x81, 0x79, 0x6c, 0x94, 0x46, 0xbe, + 0xab, 0x53, 0x5f, 0xa7, 0xb2, 0x4a, 0x98, 0x60, 0x75, 0x8d, + 0xcc, 0x34, 0x21, 0xd9, 0x0b, 0xf3, 0xe6, 0x1e, 0x64, 0x9c, + 0x89, 0x71, 0xa3, 0x5b, 0x4e, 0xb6, 0xf7, 0x0f, 0x1a, 0xe2, + 0x30, 0xc8, 0xdd, 0x25, 0x00, 0xf9, 0xef, 0x16, 0xc3, 0x3a, + 0x2c, 0xd5, 0x9b, 0x62, 0x74, 0x8d, 0x58, 0xa1, 0xb7, 0x4e, + 0x2b, 0xd2, 0xc4, 0x3d, 0xe8, 0x11, 0x07, 0xfe, 0xb0, 0x49, + 0x5f, 0xa6, 0x73, 0x8a, 0x9c, 0x65, 0x56, 0xaf, 0xb9, 0x40, + 0x95, 0x6c, 0x7a, 0x83, 0xcd, 0x34, 0x22, 0xdb, 0x0e, 0xf7, + 0xe1, 0x18, 0x7d, 0x84, 0x92, 0x6b, 0xbe, 0x47, 0x51, 0xa8, + 0xe6, 0x1f, 0x09, 0xf0, 0x25, 0xdc, 0xca, 0x33, 0xac, 0x55, + 0x43, 0xba, 0x6f, 0x96, 0x80, 0x79, 0x37, 0xce, 0xd8, 0x21, + 0xf4, 0x0d, 0x1b, 0xe2, 0x87, 0x7e, 0x68, 0x91, 0x44, 0xbd, + 0xab, 0x52, 0x1c, 0xe5, 0xf3, 0x0a, 0xdf, 0x26, 0x30, 0xc9, + 0xfa, 0x03, 0x15, 0xec, 0x39, 0xc0, 0xd6, 0x2f, 0x61, 0x98, + 0x8e, 0x77, 0xa2, 0x5b, 0x4d, 0xb4, 0xd1, 0x28, 0x3e, 0xc7, + 0x12, 0xeb, 0xfd, 0x04, 0x4a, 0xb3, 0xa5, 0x5c, 0x89, 0x70, + 0x66, 0x9f, 0x45, 0xbc, 0xaa, 0x53, 0x86, 0x7f, 0x69, 0x90, + 0xde, 0x27, 0x31, 0xc8, 0x1d, 0xe4, 0xf2, 0x0b, 0x6e, 0x97, + 0x81, 0x78, 0xad, 0x54, 0x42, 0xbb, 0xf5, 0x0c, 0x1a, 0xe3, + 0x36, 0xcf, 0xd9, 0x20, 0x13, 0xea, 0xfc, 0x05, 0xd0, 0x29, + 0x3f, 0xc6, 0x88, 0x71, 0x67, 0x9e, 0x4b, 0xb2, 0xa4, 0x5d, + 0x38, 0xc1, 0xd7, 0x2e, 0xfb, 0x02, 0x14, 0xed, 0xa3, 0x5a, + 0x4c, 0xb5, 0x60, 0x99, 0x8f, 0x76, 0xe9, 0x10, 0x06, 0xff, + 0x2a, 0xd3, 0xc5, 0x3c, 0x72, 0x8b, 0x9d, 0x64, 0xb1, 0x48, + 0x5e, 0xa7, 0xc2, 0x3b, 0x2d, 0xd4, 0x01, 0xf8, 0xee, 0x17, + 0x59, 0xa0, 0xb6, 0x4f, 0x9a, 0x63, 0x75, 0x8c, 0xbf, 0x46, + 0x50, 0xa9, 0x7c, 0x85, 0x93, 0x6a, 0x24, 0xdd, 0xcb, 0x32, + 0xe7, 0x1e, 0x08, 0xf1, 0x94, 0x6d, 0x7b, 0x82, 0x57, 0xae, + 0xb8, 0x41, 0x0f, 0xf6, 0xe0, 0x19, 0xcc, 0x35, 0x23, 0xda, + 0x00, 0xfa, 0xe9, 0x13, 0xcf, 0x35, 0x26, 0xdc, 0x83, 0x79, + 0x6a, 0x90, 0x4c, 0xb6, 0xa5, 0x5f, 0x1b, 0xe1, 0xf2, 0x08, + 0xd4, 0x2e, 0x3d, 0xc7, 0x98, 0x62, 0x71, 0x8b, 0x57, 0xad, + 0xbe, 0x44, 0x36, 0xcc, 0xdf, 0x25, 0xf9, 0x03, 0x10, 0xea, + 0xb5, 0x4f, 0x5c, 0xa6, 0x7a, 0x80, 0x93, 0x69, 0x2d, 0xd7, + 0xc4, 0x3e, 0xe2, 0x18, 0x0b, 0xf1, 0xae, 0x54, 0x47, 0xbd, + 0x61, 0x9b, 0x88, 0x72, 0x6c, 0x96, 0x85, 0x7f, 0xa3, 0x59, + 0x4a, 0xb0, 0xef, 0x15, 0x06, 0xfc, 0x20, 0xda, 0xc9, 0x33, + 0x77, 0x8d, 0x9e, 0x64, 0xb8, 0x42, 0x51, 0xab, 0xf4, 0x0e, + 0x1d, 0xe7, 0x3b, 0xc1, 0xd2, 0x28, 0x5a, 0xa0, 0xb3, 0x49, + 0x95, 0x6f, 0x7c, 0x86, 0xd9, 0x23, 0x30, 0xca, 0x16, 0xec, + 0xff, 0x05, 0x41, 0xbb, 0xa8, 0x52, 0x8e, 0x74, 0x67, 0x9d, + 0xc2, 0x38, 0x2b, 0xd1, 0x0d, 0xf7, 0xe4, 0x1e, 0xd8, 0x22, + 0x31, 0xcb, 0x17, 0xed, 0xfe, 0x04, 0x5b, 0xa1, 0xb2, 0x48, + 0x94, 0x6e, 0x7d, 0x87, 0xc3, 0x39, 0x2a, 0xd0, 0x0c, 0xf6, + 0xe5, 0x1f, 0x40, 0xba, 0xa9, 0x53, 0x8f, 0x75, 0x66, 0x9c, + 0xee, 0x14, 0x07, 0xfd, 0x21, 0xdb, 0xc8, 0x32, 0x6d, 0x97, + 0x84, 0x7e, 0xa2, 0x58, 0x4b, 0xb1, 0xf5, 0x0f, 0x1c, 0xe6, + 0x3a, 0xc0, 0xd3, 0x29, 0x76, 0x8c, 0x9f, 0x65, 0xb9, 0x43, + 0x50, 0xaa, 0xb4, 0x4e, 0x5d, 0xa7, 0x7b, 0x81, 0x92, 0x68, + 0x37, 0xcd, 0xde, 0x24, 0xf8, 0x02, 0x11, 0xeb, 0xaf, 0x55, + 0x46, 0xbc, 0x60, 0x9a, 0x89, 0x73, 0x2c, 0xd6, 0xc5, 0x3f, + 0xe3, 0x19, 0x0a, 0xf0, 0x82, 0x78, 0x6b, 0x91, 0x4d, 0xb7, + 0xa4, 0x5e, 0x01, 0xfb, 0xe8, 0x12, 0xce, 0x34, 0x27, 0xdd, + 0x99, 0x63, 0x70, 0x8a, 0x56, 0xac, 0xbf, 0x45, 0x1a, 0xe0, + 0xf3, 0x09, 0xd5, 0x2f, 0x3c, 0xc6, 0x00, 0xfb, 0xeb, 0x10, + 0xcb, 0x30, 0x20, 0xdb, 0x8b, 0x70, 0x60, 0x9b, 0x40, 0xbb, + 0xab, 0x50, 0x0b, 0xf0, 0xe0, 0x1b, 0xc0, 0x3b, 0x2b, 0xd0, + 0x80, 0x7b, 0x6b, 0x90, 0x4b, 0xb0, 0xa0, 0x5b, 0x16, 0xed, + 0xfd, 0x06, 0xdd, 0x26, 0x36, 0xcd, 0x9d, 0x66, 0x76, 0x8d, + 0x56, 0xad, 0xbd, 0x46, 0x1d, 0xe6, 0xf6, 0x0d, 0xd6, 0x2d, + 0x3d, 0xc6, 0x96, 0x6d, 0x7d, 0x86, 0x5d, 0xa6, 0xb6, 0x4d, + 0x2c, 0xd7, 0xc7, 0x3c, 0xe7, 0x1c, 0x0c, 0xf7, 0xa7, 0x5c, + 0x4c, 0xb7, 0x6c, 0x97, 0x87, 0x7c, 0x27, 0xdc, 0xcc, 0x37, + 0xec, 0x17, 0x07, 0xfc, 0xac, 0x57, 0x47, 0xbc, 0x67, 0x9c, + 0x8c, 0x77, 0x3a, 0xc1, 0xd1, 0x2a, 0xf1, 0x0a, 0x1a, 0xe1, + 0xb1, 0x4a, 0x5a, 0xa1, 0x7a, 0x81, 0x91, 0x6a, 0x31, 0xca, + 0xda, 0x21, 0xfa, 0x01, 0x11, 0xea, 0xba, 0x41, 0x51, 0xaa, + 0x71, 0x8a, 0x9a, 0x61, 0x58, 0xa3, 0xb3, 0x48, 0x93, 0x68, + 0x78, 0x83, 0xd3, 0x28, 0x38, 0xc3, 0x18, 0xe3, 0xf3, 0x08, + 0x53, 0xa8, 0xb8, 0x43, 0x98, 0x63, 0x73, 0x88, 0xd8, 0x23, + 0x33, 0xc8, 0x13, 0xe8, 0xf8, 0x03, 0x4e, 0xb5, 0xa5, 0x5e, + 0x85, 0x7e, 0x6e, 0x95, 0xc5, 0x3e, 0x2e, 0xd5, 0x0e, 0xf5, + 0xe5, 0x1e, 0x45, 0xbe, 0xae, 0x55, 0x8e, 0x75, 0x65, 0x9e, + 0xce, 0x35, 0x25, 0xde, 0x05, 0xfe, 0xee, 0x15, 0x74, 0x8f, + 0x9f, 0x64, 0xbf, 0x44, 0x54, 0xaf, 0xff, 0x04, 0x14, 0xef, + 0x34, 0xcf, 0xdf, 0x24, 0x7f, 0x84, 0x94, 0x6f, 0xb4, 0x4f, + 0x5f, 0xa4, 0xf4, 0x0f, 0x1f, 0xe4, 0x3f, 0xc4, 0xd4, 0x2f, + 0x62, 0x99, 0x89, 0x72, 0xa9, 0x52, 0x42, 0xb9, 0xe9, 0x12, + 0x02, 0xf9, 0x22, 0xd9, 0xc9, 0x32, 0x69, 0x92, 0x82, 0x79, + 0xa2, 0x59, 0x49, 0xb2, 0xe2, 0x19, 0x09, 0xf2, 0x29, 0xd2, + 0xc2, 0x39, 0x00, 0xfc, 0xe5, 0x19, 0xd7, 0x2b, 0x32, 0xce, + 0xb3, 0x4f, 0x56, 0xaa, 0x64, 0x98, 0x81, 0x7d, 0x7b, 0x87, + 0x9e, 0x62, 0xac, 0x50, 0x49, 0xb5, 0xc8, 0x34, 0x2d, 0xd1, + 0x1f, 0xe3, 0xfa, 0x06, 0xf6, 0x0a, 0x13, 0xef, 0x21, 0xdd, + 0xc4, 0x38, 0x45, 0xb9, 0xa0, 0x5c, 0x92, 0x6e, 0x77, 0x8b, + 0x8d, 0x71, 0x68, 0x94, 0x5a, 0xa6, 0xbf, 0x43, 0x3e, 0xc2, + 0xdb, 0x27, 0xe9, 0x15, 0x0c, 0xf0, 0xf1, 0x0d, 0x14, 0xe8, + 0x26, 0xda, 0xc3, 0x3f, 0x42, 0xbe, 0xa7, 0x5b, 0x95, 0x69, + 0x70, 0x8c, 0x8a, 0x76, 0x6f, 0x93, 0x5d, 0xa1, 0xb8, 0x44, + 0x39, 0xc5, 0xdc, 0x20, 0xee, 0x12, 0x0b, 0xf7, 0x07, 0xfb, + 0xe2, 0x1e, 0xd0, 0x2c, 0x35, 0xc9, 0xb4, 0x48, 0x51, 0xad, + 0x63, 0x9f, 0x86, 0x7a, 0x7c, 0x80, 0x99, 0x65, 0xab, 0x57, + 0x4e, 0xb2, 0xcf, 0x33, 0x2a, 0xd6, 0x18, 0xe4, 0xfd, 0x01, + 0xff, 0x03, 0x1a, 0xe6, 0x28, 0xd4, 0xcd, 0x31, 0x4c, 0xb0, + 0xa9, 0x55, 0x9b, 0x67, 0x7e, 0x82, 0x84, 0x78, 0x61, 0x9d, + 0x53, 0xaf, 0xb6, 0x4a, 0x37, 0xcb, 0xd2, 0x2e, 0xe0, 0x1c, + 0x05, 0xf9, 0x09, 0xf5, 0xec, 0x10, 0xde, 0x22, 0x3b, 0xc7, + 0xba, 0x46, 0x5f, 0xa3, 0x6d, 0x91, 0x88, 0x74, 0x72, 0x8e, + 0x97, 0x6b, 0xa5, 0x59, 0x40, 0xbc, 0xc1, 0x3d, 0x24, 0xd8, + 0x16, 0xea, 0xf3, 0x0f, 0x0e, 0xf2, 0xeb, 0x17, 0xd9, 0x25, + 0x3c, 0xc0, 0xbd, 0x41, 0x58, 0xa4, 0x6a, 0x96, 0x8f, 0x73, + 0x75, 0x89, 0x90, 0x6c, 0xa2, 0x5e, 0x47, 0xbb, 0xc6, 0x3a, + 0x23, 0xdf, 0x11, 0xed, 0xf4, 0x08, 0xf8, 0x04, 0x1d, 0xe1, + 0x2f, 0xd3, 0xca, 0x36, 0x4b, 0xb7, 0xae, 0x52, 0x9c, 0x60, + 0x79, 0x85, 0x83, 0x7f, 0x66, 0x9a, 0x54, 0xa8, 0xb1, 0x4d, + 0x30, 0xcc, 0xd5, 0x29, 0xe7, 0x1b, 0x02, 0xfe, 0x00, 0xfd, + 0xe7, 0x1a, 0xd3, 0x2e, 0x34, 0xc9, 0xbb, 0x46, 0x5c, 0xa1, + 0x68, 0x95, 0x8f, 0x72, 0x6b, 0x96, 0x8c, 0x71, 0xb8, 0x45, + 0x5f, 0xa2, 0xd0, 0x2d, 0x37, 0xca, 0x03, 0xfe, 0xe4, 0x19, + 0xd6, 0x2b, 0x31, 0xcc, 0x05, 0xf8, 0xe2, 0x1f, 0x6d, 0x90, + 0x8a, 0x77, 0xbe, 0x43, 0x59, 0xa4, 0xbd, 0x40, 0x5a, 0xa7, + 0x6e, 0x93, 0x89, 0x74, 0x06, 0xfb, 0xe1, 0x1c, 0xd5, 0x28, + 0x32, 0xcf, 0xb1, 0x4c, 0x56, 0xab, 0x62, 0x9f, 0x85, 0x78, + 0x0a, 0xf7, 0xed, 0x10, 0xd9, 0x24, 0x3e, 0xc3, 0xda, 0x27, + 0x3d, 0xc0, 0x09, 0xf4, 0xee, 0x13, 0x61, 0x9c, 0x86, 0x7b, + 0xb2, 0x4f, 0x55, 0xa8, 0x67, 0x9a, 0x80, 0x7d, 0xb4, 0x49, + 0x53, 0xae, 0xdc, 0x21, 0x3b, 0xc6, 0x0f, 0xf2, 0xe8, 0x15, + 0x0c, 0xf1, 0xeb, 0x16, 0xdf, 0x22, 0x38, 0xc5, 0xb7, 0x4a, + 0x50, 0xad, 0x64, 0x99, 0x83, 0x7e, 0x7f, 0x82, 0x98, 0x65, + 0xac, 0x51, 0x4b, 0xb6, 0xc4, 0x39, 0x23, 0xde, 0x17, 0xea, + 0xf0, 0x0d, 0x14, 0xe9, 0xf3, 0x0e, 0xc7, 0x3a, 0x20, 0xdd, + 0xaf, 0x52, 0x48, 0xb5, 0x7c, 0x81, 0x9b, 0x66, 0xa9, 0x54, + 0x4e, 0xb3, 0x7a, 0x87, 0x9d, 0x60, 0x12, 0xef, 0xf5, 0x08, + 0xc1, 0x3c, 0x26, 0xdb, 0xc2, 0x3f, 0x25, 0xd8, 0x11, 0xec, + 0xf6, 0x0b, 0x79, 0x84, 0x9e, 0x63, 0xaa, 0x57, 0x4d, 0xb0, + 0xce, 0x33, 0x29, 0xd4, 0x1d, 0xe0, 0xfa, 0x07, 0x75, 0x88, + 0x92, 0x6f, 0xa6, 0x5b, 0x41, 0xbc, 0xa5, 0x58, 0x42, 0xbf, + 0x76, 0x8b, 0x91, 0x6c, 0x1e, 0xe3, 0xf9, 0x04, 0xcd, 0x30, + 0x2a, 0xd7, 0x18, 0xe5, 0xff, 0x02, 0xcb, 0x36, 0x2c, 0xd1, + 0xa3, 0x5e, 0x44, 0xb9, 0x70, 0x8d, 0x97, 0x6a, 0x73, 0x8e, + 0x94, 0x69, 0xa0, 0x5d, 0x47, 0xba, 0xc8, 0x35, 0x2f, 0xd2, + 0x1b, 0xe6, 0xfc, 0x01, 0x00, 0xfe, 0xe1, 0x1f, 0xdf, 0x21, + 0x3e, 0xc0, 0xa3, 0x5d, 0x42, 0xbc, 0x7c, 0x82, 0x9d, 0x63, + 0x5b, 0xa5, 0xba, 0x44, 0x84, 0x7a, 0x65, 0x9b, 0xf8, 0x06, + 0x19, 0xe7, 0x27, 0xd9, 0xc6, 0x38, 0xb6, 0x48, 0x57, 0xa9, + 0x69, 0x97, 0x88, 0x76, 0x15, 0xeb, 0xf4, 0x0a, 0xca, 0x34, + 0x2b, 0xd5, 0xed, 0x13, 0x0c, 0xf2, 0x32, 0xcc, 0xd3, 0x2d, + 0x4e, 0xb0, 0xaf, 0x51, 0x91, 0x6f, 0x70, 0x8e, 0x71, 0x8f, + 0x90, 0x6e, 0xae, 0x50, 0x4f, 0xb1, 0xd2, 0x2c, 0x33, 0xcd, + 0x0d, 0xf3, 0xec, 0x12, 0x2a, 0xd4, 0xcb, 0x35, 0xf5, 0x0b, + 0x14, 0xea, 0x89, 0x77, 0x68, 0x96, 0x56, 0xa8, 0xb7, 0x49, + 0xc7, 0x39, 0x26, 0xd8, 0x18, 0xe6, 0xf9, 0x07, 0x64, 0x9a, + 0x85, 0x7b, 0xbb, 0x45, 0x5a, 0xa4, 0x9c, 0x62, 0x7d, 0x83, + 0x43, 0xbd, 0xa2, 0x5c, 0x3f, 0xc1, 0xde, 0x20, 0xe0, 0x1e, + 0x01, 0xff, 0xe2, 0x1c, 0x03, 0xfd, 0x3d, 0xc3, 0xdc, 0x22, + 0x41, 0xbf, 0xa0, 0x5e, 0x9e, 0x60, 0x7f, 0x81, 0xb9, 0x47, + 0x58, 0xa6, 0x66, 0x98, 0x87, 0x79, 0x1a, 0xe4, 0xfb, 0x05, + 0xc5, 0x3b, 0x24, 0xda, 0x54, 0xaa, 0xb5, 0x4b, 0x8b, 0x75, + 0x6a, 0x94, 0xf7, 0x09, 0x16, 0xe8, 0x28, 0xd6, 0xc9, 0x37, + 0x0f, 0xf1, 0xee, 0x10, 0xd0, 0x2e, 0x31, 0xcf, 0xac, 0x52, + 0x4d, 0xb3, 0x73, 0x8d, 0x92, 0x6c, 0x93, 0x6d, 0x72, 0x8c, + 0x4c, 0xb2, 0xad, 0x53, 0x30, 0xce, 0xd1, 0x2f, 0xef, 0x11, + 0x0e, 0xf0, 0xc8, 0x36, 0x29, 0xd7, 0x17, 0xe9, 0xf6, 0x08, + 0x6b, 0x95, 0x8a, 0x74, 0xb4, 0x4a, 0x55, 0xab, 0x25, 0xdb, + 0xc4, 0x3a, 0xfa, 0x04, 0x1b, 0xe5, 0x86, 0x78, 0x67, 0x99, + 0x59, 0xa7, 0xb8, 0x46, 0x7e, 0x80, 0x9f, 0x61, 0xa1, 0x5f, + 0x40, 0xbe, 0xdd, 0x23, 0x3c, 0xc2, 0x02, 0xfc, 0xe3, 0x1d, + 0x00, 0xff, 0xe3, 0x1c, 0xdb, 0x24, 0x38, 0xc7, 0xab, 0x54, + 0x48, 0xb7, 0x70, 0x8f, 0x93, 0x6c, 0x4b, 0xb4, 0xa8, 0x57, + 0x90, 0x6f, 0x73, 0x8c, 0xe0, 0x1f, 0x03, 0xfc, 0x3b, 0xc4, + 0xd8, 0x27, 0x96, 0x69, 0x75, 0x8a, 0x4d, 0xb2, 0xae, 0x51, + 0x3d, 0xc2, 0xde, 0x21, 0xe6, 0x19, 0x05, 0xfa, 0xdd, 0x22, + 0x3e, 0xc1, 0x06, 0xf9, 0xe5, 0x1a, 0x76, 0x89, 0x95, 0x6a, + 0xad, 0x52, 0x4e, 0xb1, 0x31, 0xce, 0xd2, 0x2d, 0xea, 0x15, + 0x09, 0xf6, 0x9a, 0x65, 0x79, 0x86, 0x41, 0xbe, 0xa2, 0x5d, + 0x7a, 0x85, 0x99, 0x66, 0xa1, 0x5e, 0x42, 0xbd, 0xd1, 0x2e, + 0x32, 0xcd, 0x0a, 0xf5, 0xe9, 0x16, 0xa7, 0x58, 0x44, 0xbb, + 0x7c, 0x83, 0x9f, 0x60, 0x0c, 0xf3, 0xef, 0x10, 0xd7, 0x28, + 0x34, 0xcb, 0xec, 0x13, 0x0f, 0xf0, 0x37, 0xc8, 0xd4, 0x2b, + 0x47, 0xb8, 0xa4, 0x5b, 0x9c, 0x63, 0x7f, 0x80, 0x62, 0x9d, + 0x81, 0x7e, 0xb9, 0x46, 0x5a, 0xa5, 0xc9, 0x36, 0x2a, 0xd5, + 0x12, 0xed, 0xf1, 0x0e, 0x29, 0xd6, 0xca, 0x35, 0xf2, 0x0d, + 0x11, 0xee, 0x82, 0x7d, 0x61, 0x9e, 0x59, 0xa6, 0xba, 0x45, + 0xf4, 0x0b, 0x17, 0xe8, 0x2f, 0xd0, 0xcc, 0x33, 0x5f, 0xa0, + 0xbc, 0x43, 0x84, 0x7b, 0x67, 0x98, 0xbf, 0x40, 0x5c, 0xa3, + 0x64, 0x9b, 0x87, 0x78, 0x14, 0xeb, 0xf7, 0x08, 0xcf, 0x30, + 0x2c, 0xd3, 0x53, 0xac, 0xb0, 0x4f, 0x88, 0x77, 0x6b, 0x94, + 0xf8, 0x07, 0x1b, 0xe4, 0x23, 0xdc, 0xc0, 0x3f, 0x18, 0xe7, + 0xfb, 0x04, 0xc3, 0x3c, 0x20, 0xdf, 0xb3, 0x4c, 0x50, 0xaf, + 0x68, 0x97, 0x8b, 0x74, 0xc5, 0x3a, 0x26, 0xd9, 0x1e, 0xe1, + 0xfd, 0x02, 0x6e, 0x91, 0x8d, 0x72, 0xb5, 0x4a, 0x56, 0xa9, + 0x8e, 0x71, 0x6d, 0x92, 0x55, 0xaa, 0xb6, 0x49, 0x25, 0xda, + 0xc6, 0x39, 0xfe, 0x01, 0x1d, 0xe2 +}; + +unsigned char gf_inv_table_base[] = { + 0x00, 0x01, 0x8e, 0xf4, 0x47, 0xa7, 0x7a, 0xba, 0xad, 0x9d, + 0xdd, 0x98, 0x3d, 0xaa, 0x5d, 0x96, 0xd8, 0x72, 0xc0, 0x58, + 0xe0, 0x3e, 0x4c, 0x66, 0x90, 0xde, 0x55, 0x80, 0xa0, 0x83, + 0x4b, 0x2a, 0x6c, 0xed, 0x39, 0x51, 0x60, 0x56, 0x2c, 0x8a, + 0x70, 0xd0, 0x1f, 0x4a, 0x26, 0x8b, 0x33, 0x6e, 0x48, 0x89, + 0x6f, 0x2e, 0xa4, 0xc3, 0x40, 0x5e, 0x50, 0x22, 0xcf, 0xa9, + 0xab, 0x0c, 0x15, 0xe1, 0x36, 0x5f, 0xf8, 0xd5, 0x92, 0x4e, + 0xa6, 0x04, 0x30, 0x88, 0x2b, 0x1e, 0x16, 0x67, 0x45, 0x93, + 0x38, 0x23, 0x68, 0x8c, 0x81, 0x1a, 0x25, 0x61, 0x13, 0xc1, + 0xcb, 0x63, 0x97, 0x0e, 0x37, 0x41, 0x24, 0x57, 0xca, 0x5b, + 0xb9, 0xc4, 0x17, 0x4d, 0x52, 0x8d, 0xef, 0xb3, 0x20, 0xec, + 0x2f, 0x32, 0x28, 0xd1, 0x11, 0xd9, 0xe9, 0xfb, 0xda, 0x79, + 0xdb, 0x77, 0x06, 0xbb, 0x84, 0xcd, 0xfe, 0xfc, 0x1b, 0x54, + 0xa1, 0x1d, 0x7c, 0xcc, 0xe4, 0xb0, 0x49, 0x31, 0x27, 0x2d, + 0x53, 0x69, 0x02, 0xf5, 0x18, 0xdf, 0x44, 0x4f, 0x9b, 0xbc, + 0x0f, 0x5c, 0x0b, 0xdc, 0xbd, 0x94, 0xac, 0x09, 0xc7, 0xa2, + 0x1c, 0x82, 0x9f, 0xc6, 0x34, 0xc2, 0x46, 0x05, 0xce, 0x3b, + 0x0d, 0x3c, 0x9c, 0x08, 0xbe, 0xb7, 0x87, 0xe5, 0xee, 0x6b, + 0xeb, 0xf2, 0xbf, 0xaf, 0xc5, 0x64, 0x07, 0x7b, 0x95, 0x9a, + 0xae, 0xb6, 0x12, 0x59, 0xa5, 0x35, 0x65, 0xb8, 0xa3, 0x9e, + 0xd2, 0xf7, 0x62, 0x5a, 0x85, 0x7d, 0xa8, 0x3a, 0x29, 0x71, + 0xc8, 0xf6, 0xf9, 0x43, 0xd7, 0xd6, 0x10, 0x73, 0x76, 0x78, + 0x99, 0x0a, 0x19, 0x91, 0x14, 0x3f, 0xe6, 0xf0, 0x86, 0xb1, + 0xe2, 0xf1, 0xfa, 0x74, 0xf3, 0xb4, 0x6d, 0x21, 0xb2, 0x6a, + 0xe3, 0xe7, 0xb5, 0xea, 0x03, 0x8f, 0xd3, 0xc9, 0x42, 0xd4, + 0xe8, 0x75, 0x7f, 0xff, 0x7e, 0xfd +}; +#endif // GF_LARGE_TABLES + +#endif //_EC_BASE_H_ diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_code.h b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_code.h new file mode 100644 index 000000000..570944c37 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_code.h @@ -0,0 +1,933 @@ +/********************************************************************** + Copyright(c) 2011-2015 Intel Corporation All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**********************************************************************/ + + +#ifndef _ERASURE_CODE_H_ +#define _ERASURE_CODE_H_ + +/** + * @file erasure_code.h + * @brief Interface to functions supporting erasure code encode and decode. + * + * This file defines the interface to optimized functions used in erasure + * codes. Encode and decode of erasures in GF(2^8) are made by calculating the + * dot product of the symbols (bytes in GF(2^8)) across a set of buffers and a + * set of coefficients. Values for the coefficients are determined by the type + * of erasure code. Using a general dot product means that any sequence of + * coefficients may be used including erasure codes based on random + * coefficients. + * Multiple versions of dot product are supplied to calculate 1-6 output + * vectors in one pass. + * Base GF multiply and divide functions can be sped up by defining + * GF_LARGE_TABLES at the expense of memory size. + * + */ + +#include "gf_vect_mul.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize tables for fast Erasure Code encode and decode. + * + * Generates the expanded tables needed for fast encode or decode for erasure + * codes on blocks of data. 32bytes is generated for each input coefficient. + * + * @param k The number of vector sources or rows in the generator matrix + * for coding. + * @param rows The number of output vectors to concurrently encode/decode. + * @param a Pointer to sets of arrays of input coefficients used to encode + * or decode data. + * @param gftbls Pointer to start of space for concatenated output tables + * generated from input coefficients. Must be of size 32*k*rows. + * @returns none + */ + +void ec_init_tables(int k, int rows, unsigned char* a, unsigned char* gftbls); + +/** + * @brief Generate or decode erasure codes on blocks of data, runs appropriate version. + * + * Given a list of source data blocks, generate one or multiple blocks of + * encoded data as specified by a matrix of GF(2^8) coefficients. When given a + * suitable set of coefficients, this function will perform the fast generation + * or decoding of Reed-Solomon type erasure codes. + * + * This function determines what instruction sets are enabled and + * selects the appropriate version at runtime. + * + * @param len Length of each block of data (vector) of source or dest data. + * @param k The number of vector sources or rows in the generator matrix + * for coding. + * @param rows The number of output vectors to concurrently encode/decode. + * @param gftbls Pointer to array of input tables generated from coding + * coefficients in ec_init_tables(). Must be of size 32*k*rows + * @param data Array of pointers to source input buffers. + * @param coding Array of pointers to coded output buffers. + * @returns none + */ + +void ec_encode_data(int len, int k, int rows, unsigned char *gftbls, unsigned char **data, + unsigned char **coding); + +/** + * @brief Generate or decode erasure codes on blocks of data. + * + * Arch specific version of ec_encode_data() with same parameters. + * @requires SSE4.1 + */ +void ec_encode_data_sse(int len, int k, int rows, unsigned char *gftbls, unsigned char **data, + unsigned char **coding); + +/** + * @brief Generate or decode erasure codes on blocks of data. + * + * Arch specific version of ec_encode_data() with same parameters. + * @requires AVX + */ +void ec_encode_data_avx(int len, int k, int rows, unsigned char *gftbls, unsigned char **data, + unsigned char **coding); + +/** + * @brief Generate or decode erasure codes on blocks of data. + * + * Arch specific version of ec_encode_data() with same parameters. + * @requires AVX2 + */ +void ec_encode_data_avx2(int len, int k, int rows, unsigned char *gftbls, unsigned char **data, + unsigned char **coding); + +/** + * @brief Generate or decode erasure codes on blocks of data, runs baseline version. + * + * Baseline version of ec_encode_data() with same parameters. + */ +void ec_encode_data_base(int len, int srcs, int dests, unsigned char *v, unsigned char **src, + unsigned char **dest); + +/** + * @brief Generate update for encode or decode of erasure codes from single source, runs appropriate version. + * + * Given one source data block, update one or multiple blocks of encoded data as + * specified by a matrix of GF(2^8) coefficients. When given a suitable set of + * coefficients, this function will perform the fast generation or decoding of + * Reed-Solomon type erasure codes from one input source at a time. + * + * This function determines what instruction sets are enabled and selects the + * appropriate version at runtime. + * + * @param len Length of each block of data (vector) of source or dest data. + * @param k The number of vector sources or rows in the generator matrix + * for coding. + * @param rows The number of output vectors to concurrently encode/decode. + * @param vec_i The vector index corresponding to the single input source. + * @param g_tbls Pointer to array of input tables generated from coding + * coefficients in ec_init_tables(). Must be of size 32*k*rows + * @param data Pointer to single input source used to update output parity. + * @param coding Array of pointers to coded output buffers. + * @returns none + */ +void ec_encode_data_update(int len, int k, int rows, int vec_i, unsigned char *g_tbls, + unsigned char *data, unsigned char **coding); + +/** + * @brief Generate update for encode or decode of erasure codes from single source. + * + * Arch specific version of ec_encode_data_update() with same parameters. + * @requires SSE4.1 + */ + +void ec_encode_data_update_sse(int len, int k, int rows, int vec_i, unsigned char *g_tbls, + unsigned char *data, unsigned char **coding); + +/** + * @brief Generate update for encode or decode of erasure codes from single source. + * + * Arch specific version of ec_encode_data_update() with same parameters. + * @requires AVX + */ + +void ec_encode_data_update_avx(int len, int k, int rows, int vec_i, unsigned char *g_tbls, + unsigned char *data, unsigned char **coding); + +/** + * @brief Generate update for encode or decode of erasure codes from single source. + * + * Arch specific version of ec_encode_data_update() with same parameters. + * @requires AVX2 + */ + +void ec_encode_data_update_avx2(int len, int k, int rows, int vec_i, unsigned char *g_tbls, + unsigned char *data, unsigned char **coding); + +/** + * @brief Generate update for encode or decode of erasure codes from single source. + * + * Baseline version of ec_encode_data_update(). + */ + +void ec_encode_data_update_base(int len, int k, int rows, int vec_i, unsigned char *v, + unsigned char *data, unsigned char **dest); + + +/** + * @brief GF(2^8) vector dot product. + * + * Does a GF(2^8) dot product across each byte of the input array and a constant + * set of coefficients to produce each byte of the output. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 32*vlen byte constant array based on the input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 32*vlen byte array of pre-calculated constants based + * on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Pointer to destination data array. + * @returns none + */ + +void gf_vect_dot_prod_sse(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char *dest); + +/** + * @brief GF(2^8) vector dot product. + * + * Does a GF(2^8) dot product across each byte of the input array and a constant + * set of coefficients to produce each byte of the output. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 32*vlen byte constant array based on the input coefficients. + * @requires AVX + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 32*vlen byte array of pre-calculated constants based + * on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Pointer to destination data array. + * @returns none + */ + +void gf_vect_dot_prod_avx(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char *dest); + +/** + * @brief GF(2^8) vector dot product. + * + * Does a GF(2^8) dot product across each byte of the input array and a constant + * set of coefficients to produce each byte of the output. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 32*vlen byte constant array based on the input coefficients. + * @requires AVX2 + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 32*vlen byte array of pre-calculated constants based + * on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Pointer to destination data array. + * @returns none + */ + +void gf_vect_dot_prod_avx2(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char *dest); + +/** + * @brief GF(2^8) vector dot product with two outputs. + * + * Vector dot product optimized to calculate two ouputs at a time. Does two + * GF(2^8) dot products across each byte of the input array and two constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 2*32*vlen byte constant array based on the two sets of input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 2*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_2vect_dot_prod_sse(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with two outputs. + * + * Vector dot product optimized to calculate two ouputs at a time. Does two + * GF(2^8) dot products across each byte of the input array and two constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 2*32*vlen byte constant array based on the two sets of input coefficients. + * @requires AVX + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 2*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_2vect_dot_prod_avx(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with two outputs. + * + * Vector dot product optimized to calculate two ouputs at a time. Does two + * GF(2^8) dot products across each byte of the input array and two constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 2*32*vlen byte constant array based on the two sets of input coefficients. + * @requires AVX2 + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 2*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_2vect_dot_prod_avx2(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with three outputs. + * + * Vector dot product optimized to calculate three ouputs at a time. Does three + * GF(2^8) dot products across each byte of the input array and three constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 3*32*vlen byte constant array based on the three sets of input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 3*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_3vect_dot_prod_sse(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with three outputs. + * + * Vector dot product optimized to calculate three ouputs at a time. Does three + * GF(2^8) dot products across each byte of the input array and three constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 3*32*vlen byte constant array based on the three sets of input coefficients. + * @requires AVX + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 3*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_3vect_dot_prod_avx(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with three outputs. + * + * Vector dot product optimized to calculate three ouputs at a time. Does three + * GF(2^8) dot products across each byte of the input array and three constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 3*32*vlen byte constant array based on the three sets of input coefficients. + * @requires AVX2 + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 3*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_3vect_dot_prod_avx2(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with four outputs. + * + * Vector dot product optimized to calculate four ouputs at a time. Does four + * GF(2^8) dot products across each byte of the input array and four constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 4*32*vlen byte constant array based on the four sets of input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 4*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_4vect_dot_prod_sse(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with four outputs. + * + * Vector dot product optimized to calculate four ouputs at a time. Does four + * GF(2^8) dot products across each byte of the input array and four constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 4*32*vlen byte constant array based on the four sets of input coefficients. + * @requires AVX + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 4*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_4vect_dot_prod_avx(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with four outputs. + * + * Vector dot product optimized to calculate four ouputs at a time. Does four + * GF(2^8) dot products across each byte of the input array and four constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 4*32*vlen byte constant array based on the four sets of input coefficients. + * @requires AVX2 + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 4*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_4vect_dot_prod_avx2(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with five outputs. + * + * Vector dot product optimized to calculate five ouputs at a time. Does five + * GF(2^8) dot products across each byte of the input array and five constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 5*32*vlen byte constant array based on the five sets of input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 5*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_5vect_dot_prod_sse(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with five outputs. + * + * Vector dot product optimized to calculate five ouputs at a time. Does five + * GF(2^8) dot products across each byte of the input array and five constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 5*32*vlen byte constant array based on the five sets of input coefficients. + * @requires AVX + * + * @param len Length of each vector in bytes. Must >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 5*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_5vect_dot_prod_avx(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with five outputs. + * + * Vector dot product optimized to calculate five ouputs at a time. Does five + * GF(2^8) dot products across each byte of the input array and five constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 5*32*vlen byte constant array based on the five sets of input coefficients. + * @requires AVX2 + * + * @param len Length of each vector in bytes. Must >= 32. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 5*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_5vect_dot_prod_avx2(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with six outputs. + * + * Vector dot product optimized to calculate six ouputs at a time. Does six + * GF(2^8) dot products across each byte of the input array and six constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 6*32*vlen byte constant array based on the six sets of input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 6*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_6vect_dot_prod_sse(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with six outputs. + * + * Vector dot product optimized to calculate six ouputs at a time. Does six + * GF(2^8) dot products across each byte of the input array and six constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 6*32*vlen byte constant array based on the six sets of input coefficients. + * @requires AVX + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 6*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_6vect_dot_prod_avx(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product with six outputs. + * + * Vector dot product optimized to calculate six ouputs at a time. Does six + * GF(2^8) dot products across each byte of the input array and six constant + * sets of coefficients to produce each byte of the outputs. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 6*32*vlen byte constant array based on the six sets of input coefficients. + * @requires AVX2 + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 6*32*vlen byte array of pre-calculated constants + * based on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Array of pointers to destination data buffers. + * @returns none + */ + +void gf_6vect_dot_prod_avx2(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char **dest); + +/** + * @brief GF(2^8) vector dot product, runs baseline version. + * + * Does a GF(2^8) dot product across each byte of the input array and a constant + * set of coefficients to produce each byte of the output. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 32*vlen byte constant array based on the input coefficients. + * + * @param len Length of each vector in bytes. Must be >= 16. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 32*vlen byte array of pre-calculated constants based + * on the array of input coefficients. Only elements 32*CONST*j + 1 + * of this array are used, where j = (0, 1, 2...) and CONST is the + * number of elements in the array of input coefficients. The + * elements used correspond to the original input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Pointer to destination data array. + * @returns none + */ + +void gf_vect_dot_prod_base(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char *dest); + +/** + * @brief GF(2^8) vector dot product, runs appropriate version. + * + * Does a GF(2^8) dot product across each byte of the input array and a constant + * set of coefficients to produce each byte of the output. Can be used for + * erasure coding encode and decode. Function requires pre-calculation of a + * 32*vlen byte constant array based on the input coefficients. + * + * This function determines what instruction sets are enabled and + * selects the appropriate version at runtime. + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vlen Number of vector sources. + * @param gftbls Pointer to 32*vlen byte array of pre-calculated constants based + * on the array of input coefficients. + * @param src Array of pointers to source inputs. + * @param dest Pointer to destination data array. + * @returns none + */ + +void gf_vect_dot_prod(int len, int vlen, unsigned char *gftbls, + unsigned char **src, unsigned char *dest); + + +/** + * @brief GF(2^8) vector multiply accumulate, runs appropriate version. + * + * Does a GF(2^8) multiply across each byte of input source with expanded + * constant and add to destination array. Can be used for erasure coding encode + * and decode update when only one source is available at a time. Function + * requires pre-calculation of a 32*vec byte constant array based on the input + * coefficients. + * + * This function determines what instruction sets are enabled and selects the + * appropriate version at runtime. + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vec The number of vector sources or rows in the generator matrix + * for coding. + * @param vec_i The vector index corresponding to the single input source. + * @param gftbls Pointer to array of input tables generated from coding + * coefficients in ec_init_tables(). Must be of size 32*vec. + * @param src Array of pointers to source inputs. + * @param dest Pointer to destination data array. + * @returns none + */ + +void gf_vect_mad(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char *dest); + +/** + * @brief GF(2^8) vector multiply accumulate, arch specific version. + * + * Arch specific version of gf_vect_mad() with same parameters. + * @requires SSE4.1 + */ + +void gf_vect_mad_sse(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char *dest); +/** + * @brief GF(2^8) vector multiply accumulate, arch specific version. + * + * Arch specific version of gf_vect_mad() with same parameters. + * @requires AVX + */ + +void gf_vect_mad_avx(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char *dest); + +/** + * @brief GF(2^8) vector multiply accumulate, arch specific version. + * + * Arch specific version of gf_vect_mad() with same parameters. + * @requires AVX2 + */ + +void gf_vect_mad_avx2(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char *dest); + +/** + * @brief GF(2^8) vector multiply accumulate, baseline version. + * + * Baseline version of gf_vect_mad() with same parameters. + */ + +void gf_vect_mad_base(int len, int vec, int vec_i, unsigned char *v, unsigned char *src, + unsigned char *dest); + +/** + * @brief GF(2^8) vector multiply with 2 accumulate. SSE version. + * + * Does a GF(2^8) multiply across each byte of input source with expanded + * constants and add to destination arrays. Can be used for erasure coding + * encode and decode update when only one source is available at a + * time. Function requires pre-calculation of a 32*vec byte constant array based + * on the input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vec The number of vector sources or rows in the generator matrix + * for coding. + * @param vec_i The vector index corresponding to the single input source. + * @param gftbls Pointer to array of input tables generated from coding + * coefficients in ec_init_tables(). Must be of size 32*vec. + * @param src Pointer to source input array. + * @param dest Array of pointers to destination input/outputs. + * @returns none + */ + +void gf_2vect_mad_sse(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 2 accumulate. AVX version of gf_2vect_mad_sse(). + * @requires AVX + */ +void gf_2vect_mad_avx(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); +/** + * @brief GF(2^8) vector multiply with 2 accumulate. AVX2 version of gf_2vect_mad_sse(). + * @requires AVX2 + */ +void gf_2vect_mad_avx2(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 3 accumulate. SSE version. + * + * Does a GF(2^8) multiply across each byte of input source with expanded + * constants and add to destination arrays. Can be used for erasure coding + * encode and decode update when only one source is available at a + * time. Function requires pre-calculation of a 32*vec byte constant array based + * on the input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vec The number of vector sources or rows in the generator matrix + * for coding. + * @param vec_i The vector index corresponding to the single input source. + * @param gftbls Pointer to array of input tables generated from coding + * coefficients in ec_init_tables(). Must be of size 32*vec. + * @param src Pointer to source input array. + * @param dest Array of pointers to destination input/outputs. + * @returns none + */ + +void gf_3vect_mad_sse(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 3 accumulate. AVX version of gf_3vect_mad_sse(). + * @requires AVX + */ +void gf_3vect_mad_avx(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 3 accumulate. AVX2 version of gf_3vect_mad_sse(). + * @requires AVX2 + */ +void gf_3vect_mad_avx2(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 4 accumulate. SSE version. + * + * Does a GF(2^8) multiply across each byte of input source with expanded + * constants and add to destination arrays. Can be used for erasure coding + * encode and decode update when only one source is available at a + * time. Function requires pre-calculation of a 32*vec byte constant array based + * on the input coefficients. + * @requires SSE4.1 + * + * @param len Length of each vector in bytes. Must be >= 32. + * @param vec The number of vector sources or rows in the generator matrix + * for coding. + * @param vec_i The vector index corresponding to the single input source. + * @param gftbls Pointer to array of input tables generated from coding + * coefficients in ec_init_tables(). Must be of size 32*vec. + * @param src Pointer to source input array. + * @param dest Array of pointers to destination input/outputs. + * @returns none + */ + +void gf_4vect_mad_sse(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 4 accumulate. AVX version of gf_4vect_mad_sse(). + * @requires AVX + */ +void gf_4vect_mad_avx(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); +/** + * @brief GF(2^8) vector multiply with 4 accumulate. AVX2 version of gf_4vect_mad_sse(). + * @requires AVX2 + */ +void gf_4vect_mad_avx2(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 5 accumulate. SSE version. + * @requires SSE4.1 + */ +void gf_5vect_mad_sse(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 5 accumulate. AVX version. + * @requires AVX + */ +void gf_5vect_mad_avx(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); +/** + * @brief GF(2^8) vector multiply with 5 accumulate. AVX2 version. + * @requires AVX2 + */ +void gf_5vect_mad_avx2(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 6 accumulate. SSE version. + * @requires SSE4.1 + */ +void gf_6vect_mad_sse(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); +/** + * @brief GF(2^8) vector multiply with 6 accumulate. AVX version. + * @requires AVX + */ +void gf_6vect_mad_avx(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + +/** + * @brief GF(2^8) vector multiply with 6 accumulate. AVX2 version. + * @requires AVX2 + */ +void gf_6vect_mad_avx2(int len, int vec, int vec_i, unsigned char *gftbls, unsigned char *src, + unsigned char **dest); + + +/********************************************************************** + * The remaining are lib support functions used in GF(2^8) operations. + */ + +/** + * @brief Single element GF(2^8) multiply. + * + * @param a Multiplicand a + * @param b Multiplicand b + * @returns Product of a and b in GF(2^8) + */ + +unsigned char gf_mul(unsigned char a, unsigned char b); + +/** + * @brief Single element GF(2^8) inverse. + * + * @param a Input element + * @returns Field element b such that a x b = {1} + */ + +unsigned char gf_inv(unsigned char a); + +/** + * @brief Generate a matrix of coefficients to be used for encoding. + * + * Vandermonde matrix example of encoding coefficients where high portion of + * matrix is identity matrix I and lower portion is constructed as 2^{i*(j-k+1)} + * i:{0,k-1} j:{k,m-1}. Commonly used method for choosing coefficients in + * erasure encoding but does not guarantee invertable for every sub matrix. For + * large k it is possible to find cases where the decode matrix chosen from + * sources and parity not in erasure are not invertable. Users may want to + * adjust for k > 5. + * + * @param a [mxk] array to hold coefficients + * @param m number of rows in matrix corresponding to srcs + parity. + * @param k number of columns in matrix corresponding to srcs. + * @returns none + */ + +void gf_gen_rs_matrix(unsigned char *a, int m, int k); + +/** + * @brief Generate a Cauchy matrix of coefficients to be used for encoding. + * + * Cauchy matrix example of encoding coefficients where high portion of matrix + * is identity matrix I and lower portion is constructed as 1/(i + j) | i != j, + * i:{0,k-1} j:{k,m-1}. Any sub-matrix of a Cauchy matrix should be invertable. + * + * @param a [mxk] array to hold coefficients + * @param m number of rows in matrix corresponding to srcs + parity. + * @param k number of columns in matrix corresponding to srcs. + * @returns none + */ + +void gf_gen_cauchy1_matrix(unsigned char *a, int m, int k); + +/** + * @brief Invert a matrix in GF(2^8) + * + * @param in input matrix + * @param out output matrix such that [in] x [out] = [I] - identity matrix + * @param n size of matrix [nxn] + * @returns 0 successful, other fail on singular input matrix + */ + +int gf_invert_matrix(unsigned char *in, unsigned char *out, const int n); + + +/*************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif //_ERASURE_CODE_H_ diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_highlevel_func.c b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_highlevel_func.c new file mode 100644 index 000000000..9b9c8dc0f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_highlevel_func.c @@ -0,0 +1,267 @@ +/********************************************************************** + Copyright(c) 2011-2015 Intel Corporation All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**********************************************************************/ +#include +#include "ec_code.h" +#include "ec_types.h" + +void ec_init_tables(int k, int rows, unsigned char *a, unsigned char *g_tbls) +{ + int i, j; + + for (i = 0; i < rows; i++) { + for (j = 0; j < k; j++) { + gf_vect_mul_init(*a++, g_tbls); + g_tbls += 32; + } + } +} + +void ec_encode_data_sse(int len, int k, int rows, unsigned char *g_tbls, unsigned char **data, + unsigned char **coding) +{ + + if (len < 16) { + ec_encode_data_base(len, k, rows, g_tbls, data, coding); + return; + } + + while (rows >= 4) { + gf_4vect_dot_prod_sse(len, k, g_tbls, data, coding); + g_tbls += 4 * k * 32; + coding += 4; + rows -= 4; + } + switch (rows) { + case 3: + gf_3vect_dot_prod_sse(len, k, g_tbls, data, coding); + break; + case 2: + gf_2vect_dot_prod_sse(len, k, g_tbls, data, coding); + break; + case 1: + gf_vect_dot_prod_sse(len, k, g_tbls, data, *coding); + break; + case 0: + break; + } + +} + +void ec_encode_data_avx(int len, int k, int rows, unsigned char *g_tbls, unsigned char **data, + unsigned char **coding) +{ + if (len < 16) { + ec_encode_data_base(len, k, rows, g_tbls, data, coding); + return; + } + + while (rows >= 4) { + gf_4vect_dot_prod_avx(len, k, g_tbls, data, coding); + g_tbls += 4 * k * 32; + coding += 4; + rows -= 4; + } + switch (rows) { + case 3: + gf_3vect_dot_prod_avx(len, k, g_tbls, data, coding); + break; + case 2: + gf_2vect_dot_prod_avx(len, k, g_tbls, data, coding); + break; + case 1: + gf_vect_dot_prod_avx(len, k, g_tbls, data, *coding); + break; + case 0: + break; + } + +} + +void ec_encode_data_avx2(int len, int k, int rows, unsigned char *g_tbls, unsigned char **data, + unsigned char **coding) +{ + + if (len < 32) { + ec_encode_data_base(len, k, rows, g_tbls, data, coding); + return; + } + + while (rows >= 4) { + gf_4vect_dot_prod_avx2(len, k, g_tbls, data, coding); + g_tbls += 4 * k * 32; + coding += 4; + rows -= 4; + } + switch (rows) { + case 3: + gf_3vect_dot_prod_avx2(len, k, g_tbls, data, coding); + break; + case 2: + gf_2vect_dot_prod_avx2(len, k, g_tbls, data, coding); + break; + case 1: + gf_vect_dot_prod_avx2(len, k, g_tbls, data, *coding); + break; + case 0: + break; + } + +} + +#if __WORDSIZE == 64 || _WIN64 || __x86_64__ + +void ec_encode_data_update_sse(int len, int k, int rows, int vec_i, unsigned char *g_tbls, + unsigned char *data, unsigned char **coding) +{ + if (len < 16) { + ec_encode_data_update_base(len, k, rows, vec_i, g_tbls, data, coding); + return; + } + + while (rows > 6) { + gf_6vect_mad_sse(len, k, vec_i, g_tbls, data, coding); + g_tbls += 6 * k * 32; + coding += 6; + rows -= 6; + } + switch (rows) { + case 6: + gf_6vect_mad_sse(len, k, vec_i, g_tbls, data, coding); + break; + case 5: + gf_5vect_mad_sse(len, k, vec_i, g_tbls, data, coding); + break; + case 4: + gf_4vect_mad_sse(len, k, vec_i, g_tbls, data, coding); + break; + case 3: + gf_3vect_mad_sse(len, k, vec_i, g_tbls, data, coding); + break; + case 2: + gf_2vect_mad_sse(len, k, vec_i, g_tbls, data, coding); + break; + case 1: + gf_vect_mad_sse(len, k, vec_i, g_tbls, data, *coding); + break; + case 0: + break; + } + +} + +void ec_encode_data_update_avx(int len, int k, int rows, int vec_i, unsigned char *g_tbls, + unsigned char *data, unsigned char **coding) +{ + if (len < 16) { + ec_encode_data_update_base(len, k, rows, vec_i, g_tbls, data, coding); + return; + } + while (rows > 6) { + gf_6vect_mad_avx(len, k, vec_i, g_tbls, data, coding); + g_tbls += 6 * k * 32; + coding += 6; + rows -= 6; + } + switch (rows) { + case 6: + gf_6vect_mad_avx(len, k, vec_i, g_tbls, data, coding); + break; + case 5: + gf_5vect_mad_avx(len, k, vec_i, g_tbls, data, coding); + break; + case 4: + gf_4vect_mad_avx(len, k, vec_i, g_tbls, data, coding); + break; + case 3: + gf_3vect_mad_avx(len, k, vec_i, g_tbls, data, coding); + break; + case 2: + gf_2vect_mad_avx(len, k, vec_i, g_tbls, data, coding); + break; + case 1: + gf_vect_mad_avx(len, k, vec_i, g_tbls, data, *coding); + break; + case 0: + break; + } + +} + +void ec_encode_data_update_avx2(int len, int k, int rows, int vec_i, unsigned char *g_tbls, + unsigned char *data, unsigned char **coding) +{ + if (len < 32) { + ec_encode_data_update_base(len, k, rows, vec_i, g_tbls, data, coding); + return; + } + while (rows > 6) { + gf_6vect_mad_avx2(len, k, vec_i, g_tbls, data, coding); + g_tbls += 6 * k * 32; + coding += 6; + rows -= 6; + } + switch (rows) { + case 6: + gf_6vect_mad_avx2(len, k, vec_i, g_tbls, data, coding); + break; + case 5: + gf_5vect_mad_avx2(len, k, vec_i, g_tbls, data, coding); + break; + case 4: + gf_4vect_mad_avx2(len, k, vec_i, g_tbls, data, coding); + break; + case 3: + gf_3vect_mad_avx2(len, k, vec_i, g_tbls, data, coding); + break; + case 2: + gf_2vect_mad_avx2(len, k, vec_i, g_tbls, data, coding); + break; + case 1: + gf_vect_mad_avx2(len, k, vec_i, g_tbls, data, *coding); + break; + case 0: + break; + } + +} + +#endif //__WORDSIZE == 64 || _WIN64 || __x86_64__ + +struct slver { + UINT16 snum; + UINT8 ver; + UINT8 core; +}; + +// Version info +struct slver ec_init_tables_slver_00010068; +struct slver ec_init_tables_slver = { 0x0068, 0x01, 0x00 }; + +struct slver ec_encode_data_sse_slver_00020069; +struct slver ec_encode_data_sse_slver = { 0x0069, 0x02, 0x00 }; diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_isal-l.h b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_isal-l.h new file mode 100644 index 000000000..77be0812a --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_isal-l.h @@ -0,0 +1,41 @@ +/********************************************************************** + Copyright(c) 2011-2015 Intel Corporation All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**********************************************************************/ + +#ifndef _ISAL_H_ +#define _ISAL_H_ + +#define ISAL_MAJOR_VERSION 2 +#define ISAL_MINOR_VERSION 13 +#define ISAL_PATCH_VERSION 0 +#define ISAL_MAKE_VERSION(maj, min, patch) ((maj) * 0x10000 + (min) * 0x100 + (patch)) +#define ISAL_VERSION ISAL_MAKE_VERSION(ISAL_MAJOR_VERSION, ISAL_MINOR_VERSION, ISAL_PATCH_VERSION) + +#include "ec_code.h" +#include "gf_vect_mul.h" +#endif //_ISAL_H_ diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_common.h b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_common.h new file mode 100644 index 000000000..75f4cbc16 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_common.h @@ -0,0 +1,39 @@ +/* + * Mini Object Storage, (C) 2014 Minio, Inc. + * + * 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. + */ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include + +int32_t minio_init_encoder (int technique, int k, int m, + unsigned char **encode_matrix, + unsigned char **encode_tbls); + +int32_t minio_init_decoder (int32_t *error_index, + int k, int n, int errs, + unsigned char *encoding_matrix, + unsigned char **decode_matrix, + unsigned char **decode_tbls, + uint32_t **decode_index); + +int32_t minio_get_source_target (int errs, int k, int m, + int32_t *error_index, + uint32_t *decode_index, + unsigned char **buffs, + unsigned char ***source, + unsigned char ***target); +#endif /* __COMMON_H__ */ diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_decode.c b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_decode.c new file mode 100644 index 000000000..a40967024 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_decode.c @@ -0,0 +1,134 @@ +/* + * Minimalist Object Storage, (C) 2014 Minio, Inc. + * + * 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. + */ + +#include +#include +#include + +#include "ec_isal-l.h" +#include "ec_minio_common.h" + +static +int32_t _minio_src_index_in_error (int r, int32_t *error_index) +{ + int i; + for (i = 0; error_index[i] != -1; i++) { + if (error_index[i] == r) { + // true + return 1; + } + } + // false + return 0; +} + +// Separate out source data and target buffers +int32_t minio_get_source_target (int errs, int k, int m, + int32_t *error_index, + uint32_t *decode_index, + unsigned char **buffs, + unsigned char ***source, + unsigned char ***target) +{ + int i; + unsigned char *tmp_source[k]; + unsigned char *tmp_target[m]; + + if (k < 0 || m < 0) { + return -1; + } + + memset (tmp_source, 0, k); + memset (tmp_target, 0, m); + + for (i = 0; i < k; i++) { + tmp_source[i] = (unsigned char *) buffs[decode_index[i]]; + } + + for (i = 0; i < m; i++) { + if (i < errs) + tmp_target[i] = (unsigned char *) buffs[error_index[i]]; + } + + *source = tmp_source; + *target = tmp_target; + + return 0; +} + +/* + Generate decode matrix during the decoding phase +*/ + +int minio_init_decoder (int32_t *error_index, + int k, int n, int errs, + unsigned char *encode_matrix, + unsigned char **decode_matrix, + unsigned char **decode_tbls, + uint32_t **decode_index) +{ + int i, j, r, s, l, z; + unsigned char input_matrix[k * n]; + unsigned char inverse_matrix[k * n]; + unsigned char tmp_decode_matrix[k * n]; + unsigned char tmp_decode_tbls[k * n * 32]; + uint32_t tmp_decode_index[k]; + + for (i = 0, r = 0; i < k; i++, r++) { + while (_minio_src_index_in_error(r, error_index)) + r++; + for (j = 0; j < k; j++) { + input_matrix[k * i + j] = encode_matrix[k * r + j]; + } + tmp_decode_index[i] = r; + } + + // Not all vandermonde matrix can be inverted + if (gf_invert_matrix(input_matrix, inverse_matrix, k) < 0) { + return -1; + } + + for (l = 0; l < errs; l++) { + if (error_index[l] < k) { + // decoding matrix elements for data chunks + for (j = 0; j < k; j++) { + tmp_decode_matrix[k * l + j] = + inverse_matrix[k * + error_index[l] + j]; + } + } else { + int s = 0; + // decoding matrix element for coding chunks + for (i = 0; i < k; i++) { + s = 0; + for (j = 0; j < k; j++) { + s ^= gf_mul(inverse_matrix[j * k + i], + encode_matrix[k * + error_index[l] + j]); + } + tmp_decode_matrix[k * l + i] = s; + } + } + } + + ec_init_tables (k, errs, tmp_decode_matrix, tmp_decode_tbls); + + *decode_matrix = tmp_decode_matrix; + *decode_tbls = tmp_decode_tbls; + *decode_index = tmp_decode_index; + + return 0; +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_encode.c b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_encode.c new file mode 100644 index 000000000..8f90ef10a --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_minio_encode.c @@ -0,0 +1,59 @@ +/* + * Minimalist Object Storage, (C) 2014 Minio, Inc. + * + * 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. + */ + +#include +#include + +#include "ec_isal-l.h" +#include "ec_minio_common.h" + +/* + Generate encode matrix during the encoding phase +*/ + +int32_t minio_init_encoder (int technique, int k, int m, + unsigned char **encode_matrix, + unsigned char **encode_tbls) +{ + size_t encode_matrix_size; + size_t encode_tbls_size; + unsigned char *tmp_matrix; + unsigned char *tmp_tbls; + + tmp_matrix = (unsigned char *) malloc (k * (k + m)); + tmp_tbls = (unsigned char *) malloc (k * (k + m) * 32); + + if (technique == 0) { + /* + Commonly used method for choosing coefficients in erasure + encoding but does not guarantee invertable for every sub + matrix. For large k it is possible to find cases where the + decode matrix chosen from sources and parity not in erasure + are not invertable. Users may want to adjust for k > 5. + -- Intel + */ + gf_gen_rs_matrix (tmp_matrix, k + m, k); + } else if (technique == 1) { + gf_gen_cauchy1_matrix (tmp_matrix, k + m, k); + } + + ec_init_tables(k, m, &tmp_matrix[k * k], tmp_tbls); + + *encode_matrix = tmp_matrix; + *encode_tbls = tmp_tbls; + + return 0; +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_multibinary.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_multibinary.asm new file mode 100644 index 000000000..910fdca8a --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_multibinary.asm @@ -0,0 +1,462 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%ifidn __OUTPUT_FORMAT__, elf64 + %define WRT_OPT wrt ..plt +%else + %define WRT_OPT +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define EC_ENCODE_DATA_SSE _ec_encode_data_sse + %define EC_ENCODE_DATA_AVX _ec_encode_data_avx + %define EC_ENCODE_DATA_AVX2 _ec_encode_data_avx2 + %define EC_ENCODE_DATA_BASE _ec_encode_data_base + %define EC_ENCODE_DATA _ec_encode_data + + %define EC_ENCODE_DATA_UPDATE_BASE _ec_encode_data_update_base + %define EC_ENCODE_DATA_UPDATE_SSE _ec_encode_data_update_sse + %define EC_ENCODE_DATA_UPDATE_AVX _ec_encode_data_update_avx + %define EC_ENCODE_DATA_UPDATE_AVX2 _ec_encode_data_update_avx2 + + %define GF_VECT_MAD_BASE _gf_vect_mad_base + %define GF_VECT_MAD_SSE _gf_vect_mad_sse + %define GF_VECT_MAD_AVX _gf_vect_mad_avx + %define GF_VECT_MAD_AVX2 _gf_vect_mad_avx2 + + %define GF_VECT_MUL_SSE _gf_vect_mul_sse + %define GF_VECT_MUL_AVX _gf_vect_mul_avx + %define GF_VECT_MUL_BASE _gf_vect_mul_base + %define GF_VECT_MUL _gf_vect_mul + + %define GF_VECT_DOT_PROD_SSE _gf_vect_dot_prod_sse + %define GF_VECT_DOT_PROD_AVX _gf_vect_dot_prod_avx + %define GF_VECT_DOT_PROD_AVX2 _gf_vect_dot_prod_avx2 + %define GF_VECT_DOT_PROD_BASE _gf_vect_dot_prod_base + %define GF_VECT_DOT_PROD _gf_vect_dot_prod + +%else + %define EC_ENCODE_DATA_SSE ec_encode_data_sse + %define EC_ENCODE_DATA_AVX ec_encode_data_avx + %define EC_ENCODE_DATA_AVX2 ec_encode_data_avx2 + %define EC_ENCODE_DATA_BASE ec_encode_data_base + %define EC_ENCODE_DATA ec_encode_data + + %define EC_ENCODE_DATA_UPDATE_BASE ec_encode_data_update_base + %define EC_ENCODE_DATA_UPDATE_SSE ec_encode_data_update_sse + %define EC_ENCODE_DATA_UPDATE_AVX ec_encode_data_update_avx + %define EC_ENCODE_DATA_UPDATE_AVX2 ec_encode_data_update_avx2 + + %define GF_VECT_MAD_BASE gf_vect_mad_base + %define GF_VECT_MAD_SSE gf_vect_mad_sse + %define GF_VECT_MAD_AVX gf_vect_mad_avx + %define GF_VECT_MAD_AVX2 gf_vect_mad_avx2 + + %define GF_VECT_MUL_SSE gf_vect_mul_sse + %define GF_VECT_MUL_AVX gf_vect_mul_avx + %define GF_VECT_MUL_BASE gf_vect_mul_base + %define GF_VECT_MUL gf_vect_mul + + %define GF_VECT_DOT_PROD_SSE gf_vect_dot_prod_sse + %define GF_VECT_DOT_PROD_AVX gf_vect_dot_prod_avx + %define GF_VECT_DOT_PROD_AVX2 gf_vect_dot_prod_avx2 + %define GF_VECT_DOT_PROD_BASE gf_vect_dot_prod_base + %define GF_VECT_DOT_PROD gf_vect_dot_prod + +%endif + +%include "ec_reg_sizes.asm" + +%ifidn __OUTPUT_FORMAT__, elf32 + +[bits 32] + + %define def_wrd dd + %define wrd_sz dword + %define arg1 esi + %define arg2 eax + %define arg3 ebx + %define arg4 ecx + %define arg5 edx + +%else + + default rel + [bits 64] + + %define def_wrd dq + %define wrd_sz qword + %define arg1 rsi + %define arg2 rax + %define arg3 rbx + %define arg4 rcx + %define arg5 rdx + + + extern EC_ENCODE_DATA_UPDATE_SSE + extern EC_ENCODE_DATA_UPDATE_AVX + extern EC_ENCODE_DATA_UPDATE_AVX2 + extern GF_VECT_MUL_SSE + extern GF_VECT_MUL_AVX + + extern GF_VECT_MAD_SSE + extern GF_VECT_MAD_AVX + extern GF_VECT_MAD_AVX2 +%endif + +extern GF_VECT_MUL_BASE +extern EC_ENCODE_DATA_BASE +extern EC_ENCODE_DATA_UPDATE_BASE +extern GF_VECT_DOT_PROD_BASE +extern GF_VECT_MAD_BASE + +extern GF_VECT_DOT_PROD_SSE +extern GF_VECT_DOT_PROD_AVX +extern GF_VECT_DOT_PROD_AVX2 +extern EC_ENCODE_DATA_SSE +extern EC_ENCODE_DATA_AVX +extern EC_ENCODE_DATA_AVX2 + + +section .data +;;; *_mbinit are initial values for *_dispatched; is updated on first call. +;;; Therefore, *_dispatch_init is only executed on first call. + +ec_encode_data_dispatched: + def_wrd ec_encode_data_mbinit + +gf_vect_mul_dispatched: + def_wrd gf_vect_mul_mbinit + +gf_vect_dot_prod_dispatched: + def_wrd gf_vect_dot_prod_mbinit + +ec_encode_data_update_dispatched: + def_wrd ec_encode_data_update_mbinit + +gf_vect_mad_dispatched: + def_wrd gf_vect_mad_mbinit + +section .text +;;;; +; ec_encode_data multibinary function +;;;; +global EC_ENCODE_DATA:function +ec_encode_data_mbinit: + call ec_encode_data_dispatch_init + +EC_ENCODE_DATA: + jmp wrd_sz [ec_encode_data_dispatched] + +ec_encode_data_dispatch_init: + push arg1 + push arg2 + push arg3 + push arg4 + push arg5 + lea arg1, [EC_ENCODE_DATA_BASE WRT_OPT] ; Default + + mov eax, 1 + cpuid + lea arg3, [EC_ENCODE_DATA_SSE WRT_OPT] + test ecx, FLAG_CPUID1_ECX_SSE4_1 + cmovne arg1, arg3 + + and ecx, (FLAG_CPUID1_ECX_AVX | FLAG_CPUID1_ECX_OSXSAVE) + cmp ecx, (FLAG_CPUID1_ECX_AVX | FLAG_CPUID1_ECX_OSXSAVE) + lea arg3, [EC_ENCODE_DATA_AVX WRT_OPT] + + jne _done_ec_encode_data_init + mov arg1, arg3 + + ;; Try for AVX2 + xor ecx, ecx + mov eax, 7 + cpuid + test ebx, FLAG_CPUID1_EBX_AVX2 + lea arg3, [EC_ENCODE_DATA_AVX2 WRT_OPT] + cmovne arg1, arg3 + ;; Does it have xmm and ymm support + xor ecx, ecx + xgetbv + and eax, FLAG_XGETBV_EAX_XMM_YMM + cmp eax, FLAG_XGETBV_EAX_XMM_YMM + je _done_ec_encode_data_init + lea arg1, [EC_ENCODE_DATA_SSE WRT_OPT] + +_done_ec_encode_data_init: + pop arg5 + pop arg4 + pop arg3 + pop arg2 + mov [ec_encode_data_dispatched], arg1 + pop arg1 + ret + +;;;; +; gf_vect_mul multibinary function +;;;; +global GF_VECT_MUL:function +gf_vect_mul_mbinit: + call gf_vect_mul_dispatch_init + +GF_VECT_MUL: + jmp wrd_sz [gf_vect_mul_dispatched] + +gf_vect_mul_dispatch_init: + push arg1 +%ifidn __OUTPUT_FORMAT__, elf32 ;; 32-bit check + lea arg1, [GF_VECT_MUL_BASE] +%else + push rax + push rbx + push rcx + push rdx + lea arg1, [GF_VECT_MUL_BASE WRT_OPT] ; Default + + mov eax, 1 + cpuid + test ecx, FLAG_CPUID1_ECX_SSE4_2 + lea rbx, [GF_VECT_MUL_SSE WRT_OPT] + je _done_gf_vect_mul_dispatch_init + mov arg1, rbx + + ;; Try for AVX + and ecx, (FLAG_CPUID1_ECX_OSXSAVE | FLAG_CPUID1_ECX_AVX) + cmp ecx, (FLAG_CPUID1_ECX_OSXSAVE | FLAG_CPUID1_ECX_AVX) + jne _done_gf_vect_mul_dispatch_init + + ;; Does it have xmm and ymm support + xor ecx, ecx + xgetbv + and eax, FLAG_XGETBV_EAX_XMM_YMM + cmp eax, FLAG_XGETBV_EAX_XMM_YMM + jne _done_gf_vect_mul_dispatch_init + lea arg1, [GF_VECT_MUL_AVX WRT_OPT] + +_done_gf_vect_mul_dispatch_init: + pop rdx + pop rcx + pop rbx + pop rax +%endif ;; END 32-bit check + mov [gf_vect_mul_dispatched], arg1 + pop arg1 + ret + +;;;; +; ec_encode_data_update multibinary function +;;;; +global EC_ENCODE_DATA_UPDATE:function +ec_encode_data_update_mbinit: + call ec_encode_data_update_dispatch_init + +EC_ENCODE_DATA_UPDATE: + jmp wrd_sz [ec_encode_data_update_dispatched] + +ec_encode_data_update_dispatch_init: + push arg1 +%ifidn __OUTPUT_FORMAT__, elf32 ;; 32-bit check + lea arg1, [ec_encode_data_update_base] +%else + push rax + push rbx + push rcx + push rdx + lea arg1, [EC_ENCODE_DATA_UPDATE_BASE WRT_OPT] ; Default + + mov eax, 1 + cpuid + lea rbx, [EC_ENCODE_DATA_UPDATE_SSE WRT_OPT] + test ecx, FLAG_CPUID1_ECX_SSE4_1 + cmovne arg1, rbx + + and ecx, (FLAG_CPUID1_ECX_AVX | FLAG_CPUID1_ECX_OSXSAVE) + cmp ecx, (FLAG_CPUID1_ECX_AVX | FLAG_CPUID1_ECX_OSXSAVE) + lea rbx, [EC_ENCODE_DATA_UPDATE_AVX WRT_OPT] + + jne _done_ec_encode_data_update_init + mov rsi, rbx + + ;; Try for AVX2 + xor ecx, ecx + mov eax, 7 + cpuid + test ebx, FLAG_CPUID1_EBX_AVX2 + lea rbx, [EC_ENCODE_DATA_UPDATE_AVX2 WRT_OPT] + cmovne rsi, rbx + + ;; Does it have xmm and ymm support + xor ecx, ecx + xgetbv + and eax, FLAG_XGETBV_EAX_XMM_YMM + cmp eax, FLAG_XGETBV_EAX_XMM_YMM + je _done_ec_encode_data_update_init + lea rsi, [EC_ENCODE_DATA_UPDATE_SSE WRT_OPT] + +_done_ec_encode_data_update_init: + pop rdx + pop rcx + pop rbx + pop rax +%endif ;; END 32-bit check + mov [ec_encode_data_update_dispatched], arg1 + pop arg1 + ret + +;;;; +; gf_vect_dot_prod multibinary function +;;;; +global GF_VECT_DOT_PROD:function +gf_vect_dot_prod_mbinit: + call gf_vect_dot_prod_dispatch_init + +GF_VECT_DOT_PROD: + jmp wrd_sz [gf_vect_dot_prod_dispatched] + +gf_vect_dot_prod_dispatch_init: + push arg1 + push arg2 + push arg3 + push arg4 + push arg5 + lea arg1, [GF_VECT_DOT_PROD_BASE WRT_OPT] ; Default + + mov eax, 1 + cpuid + lea arg3, [GF_VECT_DOT_PROD_SSE WRT_OPT] + test ecx, FLAG_CPUID1_ECX_SSE4_1 + cmovne arg1, arg3 + + and ecx, (FLAG_CPUID1_ECX_AVX | FLAG_CPUID1_ECX_OSXSAVE) + cmp ecx, (FLAG_CPUID1_ECX_AVX | FLAG_CPUID1_ECX_OSXSAVE) + lea arg3, [GF_VECT_DOT_PROD_AVX WRT_OPT] + + jne _done_gf_vect_dot_prod_init + mov arg1, arg3 + + ;; Try for AVX2 + xor ecx, ecx + mov eax, 7 + cpuid + test ebx, FLAG_CPUID1_EBX_AVX2 + lea arg3, [GF_VECT_DOT_PROD_AVX2 WRT_OPT] + cmovne arg1, arg3 + ;; Does it have xmm and ymm support + xor ecx, ecx + xgetbv + and eax, FLAG_XGETBV_EAX_XMM_YMM + cmp eax, FLAG_XGETBV_EAX_XMM_YMM + je _done_gf_vect_dot_prod_init + lea arg1, [GF_VECT_DOT_PROD_SSE WRT_OPT] + +_done_gf_vect_dot_prod_init: + pop arg5 + pop arg4 + pop arg3 + pop arg2 + mov [gf_vect_dot_prod_dispatched], arg1 + pop arg1 + ret + +;;;; +; gf_vect_mad multibinary function +;;;; +global GF_VECT_MAD:function +gf_vect_mad_mbinit: + call gf_vect_mad_dispatch_init + +GF_VECT_MAD: + jmp wrd_sz [gf_vect_mad_dispatched] + +gf_vect_mad_dispatch_init: + push arg1 +%ifidn __OUTPUT_FORMAT__, elf32 ;; 32-bit check + lea arg1, [gf_vect_mad_base] +%else + push rax + push rbx + push rcx + push rdx + lea arg1, [GF_VECT_MAD_BASE WRT_OPT] ; Default + + mov eax, 1 + cpuid + lea rbx, [GF_VECT_MAD_SSE WRT_OPT] + test ecx, FLAG_CPUID1_ECX_SSE4_1 + cmovne arg1, rbx + + and ecx, (FLAG_CPUID1_ECX_AVX | FLAG_CPUID1_ECX_OSXSAVE) + cmp ecx, (FLAG_CPUID1_ECX_AVX | FLAG_CPUID1_ECX_OSXSAVE) + lea rbx, [GF_VECT_MAD_AVX WRT_OPT] + + jne _done_gf_vect_mad_init + mov rsi, rbx + + ;; Try for AVX2 + xor ecx, ecx + mov eax, 7 + cpuid + test ebx, FLAG_CPUID1_EBX_AVX2 + lea rbx, [GF_VECT_MAD_AVX2 WRT_OPT] + cmovne rsi, rbx + + ;; Does it have xmm and ymm support + xor ecx, ecx + xgetbv + and eax, FLAG_XGETBV_EAX_XMM_YMM + cmp eax, FLAG_XGETBV_EAX_XMM_YMM + je _done_gf_vect_mad_init + lea rsi, [GF_VECT_MAD_SSE WRT_OPT] + +_done_gf_vect_mad_init: + pop rdx + pop rcx + pop rbx + pop rax +%endif ;; END 32-bit check + mov [gf_vect_mad_dispatched], arg1 + pop arg1 + ret + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro + +;;; func core, ver, snum +slversion EC_ENCODE_DATA, 00, 03, 0133 +slversion GF_VECT_MUL, 00, 02, 0134 +slversion EC_ENCODE_DATA_UPDATE, 00, 02, 0212 +slversion GF_VECT_DOT_PROD, 00, 02, 0138 +slversion GF_VECT_MAD, 00, 01, 0213 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_reg_sizes.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_reg_sizes.asm new file mode 100644 index 000000000..8a6f377d3 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_reg_sizes.asm @@ -0,0 +1,96 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%define EFLAGS_HAS_CPUID (1<<21) +%define FLAG_CPUID1_ECX_CLMUL (1<<1) +%define FLAG_CPUID1_EDX_SSE2 (1<<26) +%define FLAG_CPUID1_ECX_SSE3 (1) +%define FLAG_CPUID1_ECX_SSE4_1 (1<<19) +%define FLAG_CPUID1_ECX_SSE4_2 (1<<20) +%define FLAG_CPUID1_ECX_POPCNT (1<<23) +%define FLAG_CPUID1_ECX_AESNI (1<<25) +%define FLAG_CPUID1_ECX_OSXSAVE (1<<27) +%define FLAG_CPUID1_ECX_AVX (1<<28) +%define FLAG_CPUID1_EBX_AVX2 (1<<5) +%define FLAG_XGETBV_EAX_XMM_YMM 0x6 + +%define FLAG_CPUID1_EAX_AVOTON 0x000406d0 + +; define d and w variants for registers + +%define raxd eax +%define raxw ax +%define raxb al + +%define rbxd ebx +%define rbxw bx +%define rbxb bl + +%define rcxd ecx +%define rcxw cx +%define rcxb cl + +%define rdxd edx +%define rdxw dx +%define rdxb dl + +%define rsid esi +%define rsiw si +%define rsib sil + +%define rdid edi +%define rdiw di +%define rdib dil + +%define rbpd ebp +%define rbpw bp +%define rbpb bpl + +%define ymm0x xmm0 +%define ymm1x xmm1 +%define ymm2x xmm2 +%define ymm3x xmm3 +%define ymm4x xmm4 +%define ymm5x xmm5 +%define ymm6x xmm6 +%define ymm7x xmm7 +%define ymm8x xmm8 +%define ymm9x xmm9 +%define ymm10x xmm10 +%define ymm11x xmm11 +%define ymm12x xmm12 +%define ymm13x xmm13 +%define ymm14x xmm14 +%define ymm15x xmm15 + +%define DWORD(reg) reg %+ d +%define WORD(reg) reg %+ w +%define BYTE(reg) reg %+ b + +%define XWORD(reg) reg %+ x diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_types.h b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_types.h new file mode 100644 index 000000000..62e61e2dd --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/ec_types.h @@ -0,0 +1,80 @@ +/********************************************************************** + Copyright(c) 2011-2015 Intel Corporation All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**********************************************************************/ + + +/** + * @file types.h + * @brief Defines standard width types. + * + */ + +#ifndef __TYPES_H +#define __TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(__unix__) && !defined(__APPLE__) +#ifdef __MINGW32__ +# include <_mingw.h> +#endif +typedef unsigned __int64 UINT64; +typedef __int64 INT64; +typedef unsigned __int32 UINT32; +typedef unsigned __int16 UINT16; +typedef unsigned char UINT8; +#else +typedef unsigned long int UINT64; +typedef long int INT64; +typedef unsigned int UINT32; +typedef unsigned short int UINT16; +typedef unsigned char UINT8; +#endif + + +#if defined(__unix__) || defined(__APPLE__) +# define DECLARE_ALIGNED(decl, alignval) decl __attribute__((aligned(alignval))) +# define __forceinline static inline +#else +# define DECLARE_ALIGNED(decl, alignval) __declspec(align(alignval)) decl +# define posix_memalign(p, algn, len) (NULL == (*((char**)(p)) = (void*) _aligned_malloc(len, algn))) +#endif + +#ifdef DEBUG +# define DEBUG_PRINT(x) printf x +#else +# define DEBUG_PRINT(x) do {} while (0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif //__TYPES_H diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_decode.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_decode.go new file mode 100644 index 000000000..91c42ce1b --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_decode.go @@ -0,0 +1,122 @@ +/* + * Minimalist Object Storage, (C) 2014 Minio, Inc. + * + * 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 erasure + +// #cgo CFLAGS: -O0 +// #include +// #include "ec_isal-l.h" +// #include "ec_minio_common.h" +import "C" +import ( + "errors" + "fmt" + "unsafe" +) + +// Decode decodes erasure coded blocks of data into its original +// form. Erasure coded data contains K data blocks and M parity +// blocks. Decode can withstand data loss up to any M number of blocks. +// +// "encodedDataBlocks" is an array of K data blocks and M parity +// blocks. Data blocks are position and order dependent. Missing blocks +// are set to "nil". There must be at least "K" number of data|parity +// blocks. +// +// "dataLen" is the length of original source data +func (e *Erasure) Decode(encodedDataBlocks [][]byte, dataLen int) (decodedData []byte, err error) { + var source, target **C.uchar + + k := int(e.params.K) + m := int(e.params.M) + n := k + m + // We need the data and parity blocks preserved in the same order. Missing blocks are set to nil. + if len(encodedDataBlocks) != n { + msg := fmt.Sprintf("Encoded data blocks slice must of length [%d]", n) + return nil, errors.New(msg) + } + + // Length of a single encoded block + encodedBlockLen := GetEncodedBlockLen(dataLen, uint8(k)) + + // Keep track of errors per block. + missingEncodedBlocks := make([]int, n+1) + var missingEncodedBlocksCount int + + // Check for the missing encoded blocks + for i := range encodedDataBlocks { + if encodedDataBlocks[i] == nil || len(encodedDataBlocks[i]) == 0 { + missingEncodedBlocks[missingEncodedBlocksCount] = i + missingEncodedBlocksCount++ + } + } + missingEncodedBlocks[missingEncodedBlocksCount] = -1 + missingEncodedBlocksCount++ + + // Cannot reconstruct original data. Need at least M number of data or parity blocks. + if missingEncodedBlocksCount-1 > m { + return nil, fmt.Errorf("Cannot reconstruct original data. Need at least [%d] data or parity blocks", m) + } + + // Convert from Go int slice to C int array + missingEncodedBlocksC := intSlice2CIntArray(missingEncodedBlocks[:missingEncodedBlocksCount]) + + // Allocate buffer for the missing blocks + for i := range encodedDataBlocks { + if encodedDataBlocks[i] == nil || len(encodedDataBlocks[i]) == 0 { + encodedDataBlocks[i] = make([]byte, encodedBlockLen) + } + } + + // If not already initialized, recompute and cache + if e.decodeMatrix == nil || e.decodeTbls == nil || e.decodeIndex == nil { + var decodeMatrix, decodeTbls *C.uchar + var decodeIndex *C.uint32_t + + C.minio_init_decoder(missingEncodedBlocksC, C.int(k), C.int(n), C.int(missingEncodedBlocksCount-1), + e.encodeMatrix, &decodeMatrix, &decodeTbls, &decodeIndex) + + // cache this for future needs + e.decodeMatrix = decodeMatrix + e.decodeTbls = decodeTbls + e.decodeIndex = decodeIndex + } + + // Make a slice of pointers to encoded blocks. Necessary to bridge to the C world. + pointers := make([]*byte, n) + for i := range encodedDataBlocks { + pointers[i] = &encodedDataBlocks[i][0] + } + + // Get pointers to source "data" and target "parity" blocks from the output byte array. + ret := C.minio_get_source_target(C.int(missingEncodedBlocksCount-1), C.int(k), C.int(m), missingEncodedBlocksC, + e.decodeIndex, (**C.uchar)(unsafe.Pointer(&pointers[0])), &source, &target) + if int(ret) == -1 { + return nil, errors.New("Unable to decode data") + } + + // Decode data + C.ec_encode_data(C.int(encodedBlockLen), C.int(k), C.int(missingEncodedBlocksCount-1), e.decodeTbls, + source, target) + + // Allocate buffer to output buffer + decodedData = make([]byte, 0, encodedBlockLen*int(k)) + for i := 0; i < int(k); i++ { + decodedData = append(decodedData, encodedDataBlocks[i]...) + } + + return decodedData[:dataLen], nil +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_encode.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_encode.go new file mode 100644 index 000000000..5088edfbb --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_encode.go @@ -0,0 +1,197 @@ +/* + * Minimalist Object Storage, (C) 2014 Minio, Inc. + * + * 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 erasure + +// #cgo CFLAGS: -O0 +// #include +// #include "ec_isal-l.h" +// #include "ec_minio_common.h" +import "C" +import ( + "errors" + "unsafe" +) + +// Technique - type of matrix type used in encoding +type Technique uint8 + +// Different types of supported matrix types +const ( + Vandermonde Technique = iota + Cauchy + None +) + +// Default Data and Parity blocks +const ( + K = 10 + M = 3 +) + +// Block alignment +const ( + SIMDAlign = 32 +) + +// ErasureParams is a configuration set for building an encoder. It is created using ValidateParams(). +type ErasureParams struct { + K uint8 + M uint8 + Technique Technique // cauchy or vandermonde matrix (RS) +} + +// Erasure is an object used to encode and decode data. +type Erasure struct { + params *ErasureParams + encodeMatrix, encodeTbls *C.uchar + decodeMatrix, decodeTbls *C.uchar + decodeIndex *C.uint32_t +} + +// ValidateParams creates an ErasureParams object. +// +// k and m represent the matrix size, which corresponds to the protection level +// technique is the matrix type. Valid inputs are Cauchy (recommended) or Vandermonde. +// +func ValidateParams(k, m uint8, technique Technique) (*ErasureParams, error) { + if k < 1 { + return nil, errors.New("k cannot be zero") + } + + if m < 1 { + return nil, errors.New("m cannot be zero") + } + + if k+m > 255 { + return nil, errors.New("(k + m) cannot be bigger than Galois field GF(2^8) - 1") + } + + switch technique { + case Vandermonde: + break + case Cauchy: + break + default: + return nil, errors.New("Technique can be either vandermonde or cauchy") + } + + return &ErasureParams{ + K: k, + M: m, + Technique: technique, + }, nil +} + +// NewErasure creates an encoder object with a given set of parameters. +func NewErasure(ep *ErasureParams) *Erasure { + var k = C.int(ep.K) + var m = C.int(ep.M) + + var encodeMatrix *C.uchar + var encodeTbls *C.uchar + + C.minio_init_encoder(C.int(ep.Technique), k, m, &encodeMatrix, + &encodeTbls) + + return &Erasure{ + params: ep, + encodeMatrix: encodeMatrix, + encodeTbls: encodeTbls, + decodeMatrix: nil, + decodeTbls: nil, + decodeIndex: nil, + } +} + +// GetEncodedBlocksLen - total length of all encoded blocks +func GetEncodedBlocksLen(inputLen int, k, m uint8) (outputLen int) { + outputLen = GetEncodedBlockLen(inputLen, k) * int(k+m) + return outputLen +} + +// GetEncodedBlockLen - length per block of encoded blocks +func GetEncodedBlockLen(inputLen int, k uint8) (encodedOutputLen int) { + alignment := int(k) * SIMDAlign + remainder := inputLen % alignment + + paddedInputLen := inputLen + if remainder != 0 { + paddedInputLen = inputLen + (alignment - remainder) + } + encodedOutputLen = paddedInputLen / int(k) + return encodedOutputLen +} + +// Encode erasure codes a block of data in "k" data blocks and "m" parity blocks. +// Output is [k+m][]blocks of data and parity slices. +func (e *Erasure) Encode(inputData []byte) (encodedBlocks [][]byte, err error) { + k := int(e.params.K) // "k" data blocks + m := int(e.params.M) // "m" parity blocks + n := k + m // "n" total encoded blocks + + // Length of a single encoded chunk. + // Total number of encoded chunks = "k" data + "m" parity blocks + encodedBlockLen := GetEncodedBlockLen(len(inputData), uint8(k)) + + // Length of total number of "k" data chunks + encodedDataBlocksLen := encodedBlockLen * k + + // Length of extra padding required for the data blocks. + encodedDataBlocksPadLen := encodedDataBlocksLen - len(inputData) + + // Extend inputData buffer to accommodate coded data blocks if necesssary + if encodedDataBlocksPadLen > 0 { + padding := make([]byte, encodedDataBlocksPadLen) + // Expand with new padded blocks to the byte array + inputData = append(inputData, padding...) + } + + // Extend inputData buffer to accommodate coded parity blocks + { // Local Scope + encodedParityBlocksLen := encodedBlockLen * m + parityBlocks := make([]byte, encodedParityBlocksLen) + inputData = append(inputData, parityBlocks...) + } + + // Allocate memory to the "encoded blocks" return buffer + encodedBlocks = make([][]byte, n) // Return buffer + + // Nessary to bridge Go to the C world. C requires 2D arry of pointers to + // byte array. "encodedBlocks" is a 2D slice. + pointersToEncodedBlock := make([]*byte, n) // Pointers to encoded blocks. + + // Copy data block slices to encoded block buffer + for i := 0; i < k; i++ { + encodedBlocks[i] = inputData[i*encodedBlockLen : (i+1)*encodedBlockLen] + pointersToEncodedBlock[i] = &encodedBlocks[i][0] + } + + // Copy erasure block slices to encoded block buffer + for i := k; i < n; i++ { + encodedBlocks[i] = make([]byte, encodedBlockLen) + pointersToEncodedBlock[i] = &encodedBlocks[i][0] + } + + // Erasure code the data into K data blocks and M parity + // blocks. Only the parity blocks are filled. Data blocks remain + // intact. + C.ec_encode_data(C.int(encodedBlockLen), C.int(k), C.int(m), e.encodeTbls, + (**C.uchar)(unsafe.Pointer(&pointersToEncodedBlock[:k][0])), // Pointers to data blocks + (**C.uchar)(unsafe.Pointer(&pointersToEncodedBlock[k:][0]))) // Pointers to parity blocks + + return encodedBlocks, nil +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_darwin.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_darwin.go new file mode 100644 index 000000000..55380b0e2 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_darwin.go @@ -0,0 +1,43 @@ +// !build amd64 + +package erasure + +//go:generate yasm -f macho64 ec_multibinary.asm -o ec_multibinary.syso +//go:generate yasm -f macho64 gf_2vect_mad_avx2.asm -o gf_2vect_mad_avx2.syso +//go:generate yasm -f macho64 gf_2vect_mad_avx.asm -o gf_2vect_mad_avx.syso +//go:generate yasm -f macho64 gf_2vect_mad_sse.asm -o gf_2vect_mad_sse.syso +//go:generate yasm -f macho64 gf_3vect_mad_avx2.asm -o gf_3vect_mad_avx2.syso +//go:generate yasm -f macho64 gf_3vect_mad_avx.asm -o gf_3vect_mad_avx.syso +//go:generate yasm -f macho64 gf_3vect_mad_sse.asm -o gf_3vect_mad_sse.syso +//go:generate yasm -f macho64 gf_4vect_mad_avx2.asm -o gf_4vect_mad_avx2.syso +//go:generate yasm -f macho64 gf_4vect_mad_avx.asm -o gf_4vect_mad_avx.syso +//go:generate yasm -f macho64 gf_4vect_mad_sse.asm -o gf_4vect_mad_sse.syso +//go:generate yasm -f macho64 gf_5vect_mad_avx2.asm -o gf_5vect_mad_avx2.syso +//go:generate yasm -f macho64 gf_5vect_mad_avx.asm -o gf_5vect_mad_avx.syso +//go:generate yasm -f macho64 gf_5vect_mad_sse.asm -o gf_5vect_mad_sse.syso +//go:generate yasm -f macho64 gf_6vect_mad_avx2.asm -o gf_6vect_mad_avx2.syso +//go:generate yasm -f macho64 gf_6vect_mad_avx.asm -o gf_6vect_mad_avx.syso +//go:generate yasm -f macho64 gf_6vect_mad_sse.asm -o gf_6vect_mad_sse.syso +//go:generate yasm -f macho64 gf_vect_mad_avx2.asm -o gf_vect_mad_avx2.syso +//go:generate yasm -f macho64 gf_vect_mad_avx.asm -o gf_vect_mad_avx.syso +//go:generate yasm -f macho64 gf_vect_mad_sse.asm -o gf_vect_mad_sse.syso +//go:generate yasm -f macho64 gf_2vect_dot_prod_avx2.asm -o gf_2vect_dot_prod_avx2.syso +//go:generate yasm -f macho64 gf_2vect_dot_prod_avx.asm -o gf_2vect_dot_prod_avx.syso +//go:generate yasm -f macho64 gf_2vect_dot_prod_sse.asm -o gf_2vect_dot_prod_sse.syso +//go:generate yasm -f macho64 gf_3vect_dot_prod_avx2.asm -o gf_3vect_dot_prod_avx2.syso +//go:generate yasm -f macho64 gf_3vect_dot_prod_avx.asm -o gf_3vect_dot_prod_avx.syso +//go:generate yasm -f macho64 gf_3vect_dot_prod_sse.asm -o gf_3vect_dot_prod_sse.syso +//go:generate yasm -f macho64 gf_4vect_dot_prod_avx2.asm -o gf_4vect_dot_prod_avx2.syso +//go:generate yasm -f macho64 gf_4vect_dot_prod_avx.asm -o gf_4vect_dot_prod_avx.syso +//go:generate yasm -f macho64 gf_4vect_dot_prod_sse.asm -o gf_4vect_dot_prod_sse.syso +//go:generate yasm -f macho64 gf_5vect_dot_prod_avx2.asm -o gf_5vect_dot_prod_avx2.syso +//go:generate yasm -f macho64 gf_5vect_dot_prod_avx.asm -o gf_5vect_dot_prod_avx.syso +//go:generate yasm -f macho64 gf_5vect_dot_prod_sse.asm -o gf_5vect_dot_prod_sse.syso +//go:generate yasm -f macho64 gf_6vect_dot_prod_avx2.asm -o gf_6vect_dot_prod_avx2.syso +//go:generate yasm -f macho64 gf_6vect_dot_prod_avx.asm -o gf_6vect_dot_prod_avx.syso +//go:generate yasm -f macho64 gf_6vect_dot_prod_sse.asm -o gf_6vect_dot_prod_sse.syso +//go:generate yasm -f macho64 gf_vect_dot_prod_avx2.asm -o gf_vect_dot_prod_avx2.syso +//go:generate yasm -f macho64 gf_vect_dot_prod_avx.asm -o gf_vect_dot_prod_avx.syso +//go:generate yasm -f macho64 gf_vect_dot_prod_sse.asm -o gf_vect_dot_prod_sse.syso +//go:generate yasm -f macho64 gf_vect_mul_avx.asm -o gf_vect_mul_avx.syso +//go:generate yasm -f macho64 gf_vect_mul_sse.asm -o gf_vect_mul_sse.syso diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_linux.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_linux.go new file mode 100644 index 000000000..0574a7ccc --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_linux.go @@ -0,0 +1,43 @@ +// !build amd64 + +package erasure + +//go:generate yasm -f elf64 ec_multibinary.asm -o ec_multibinary.syso +//go:generate yasm -f elf64 gf_2vect_mad_avx2.asm -o gf_2vect_mad_avx2.syso +//go:generate yasm -f elf64 gf_2vect_mad_avx.asm -o gf_2vect_mad_avx.syso +//go:generate yasm -f elf64 gf_2vect_mad_sse.asm -o gf_2vect_mad_sse.syso +//go:generate yasm -f elf64 gf_3vect_mad_avx2.asm -o gf_3vect_mad_avx2.syso +//go:generate yasm -f elf64 gf_3vect_mad_avx.asm -o gf_3vect_mad_avx.syso +//go:generate yasm -f elf64 gf_3vect_mad_sse.asm -o gf_3vect_mad_sse.syso +//go:generate yasm -f elf64 gf_4vect_mad_avx2.asm -o gf_4vect_mad_avx2.syso +//go:generate yasm -f elf64 gf_4vect_mad_avx.asm -o gf_4vect_mad_avx.syso +//go:generate yasm -f elf64 gf_4vect_mad_sse.asm -o gf_4vect_mad_sse.syso +//go:generate yasm -f elf64 gf_5vect_mad_avx2.asm -o gf_5vect_mad_avx2.syso +//go:generate yasm -f elf64 gf_5vect_mad_avx.asm -o gf_5vect_mad_avx.syso +//go:generate yasm -f elf64 gf_5vect_mad_sse.asm -o gf_5vect_mad_sse.syso +//go:generate yasm -f elf64 gf_6vect_mad_avx2.asm -o gf_6vect_mad_avx2.syso +//go:generate yasm -f elf64 gf_6vect_mad_avx.asm -o gf_6vect_mad_avx.syso +//go:generate yasm -f elf64 gf_6vect_mad_sse.asm -o gf_6vect_mad_sse.syso +//go:generate yasm -f elf64 gf_vect_mad_avx2.asm -o gf_vect_mad_avx2.syso +//go:generate yasm -f elf64 gf_vect_mad_avx.asm -o gf_vect_mad_avx.syso +//go:generate yasm -f elf64 gf_vect_mad_sse.asm -o gf_vect_mad_sse.syso +//go:generate yasm -f elf64 gf_2vect_dot_prod_avx2.asm -o gf_2vect_dot_prod_avx2.syso +//go:generate yasm -f elf64 gf_2vect_dot_prod_avx.asm -o gf_2vect_dot_prod_avx.syso +//go:generate yasm -f elf64 gf_2vect_dot_prod_sse.asm -o gf_2vect_dot_prod_sse.syso +//go:generate yasm -f elf64 gf_3vect_dot_prod_avx2.asm -o gf_3vect_dot_prod_avx2.syso +//go:generate yasm -f elf64 gf_3vect_dot_prod_avx.asm -o gf_3vect_dot_prod_avx.syso +//go:generate yasm -f elf64 gf_3vect_dot_prod_sse.asm -o gf_3vect_dot_prod_sse.syso +//go:generate yasm -f elf64 gf_4vect_dot_prod_avx2.asm -o gf_4vect_dot_prod_avx2.syso +//go:generate yasm -f elf64 gf_4vect_dot_prod_avx.asm -o gf_4vect_dot_prod_avx.syso +//go:generate yasm -f elf64 gf_4vect_dot_prod_sse.asm -o gf_4vect_dot_prod_sse.syso +//go:generate yasm -f elf64 gf_5vect_dot_prod_avx2.asm -o gf_5vect_dot_prod_avx2.syso +//go:generate yasm -f elf64 gf_5vect_dot_prod_avx.asm -o gf_5vect_dot_prod_avx.syso +//go:generate yasm -f elf64 gf_5vect_dot_prod_sse.asm -o gf_5vect_dot_prod_sse.syso +//go:generate yasm -f elf64 gf_6vect_dot_prod_avx2.asm -o gf_6vect_dot_prod_avx2.syso +//go:generate yasm -f elf64 gf_6vect_dot_prod_avx.asm -o gf_6vect_dot_prod_avx.syso +//go:generate yasm -f elf64 gf_6vect_dot_prod_sse.asm -o gf_6vect_dot_prod_sse.syso +//go:generate yasm -f elf64 gf_vect_dot_prod_avx2.asm -o gf_vect_dot_prod_avx2.syso +//go:generate yasm -f elf64 gf_vect_dot_prod_avx.asm -o gf_vect_dot_prod_avx.syso +//go:generate yasm -f elf64 gf_vect_dot_prod_sse.asm -o gf_vect_dot_prod_sse.syso +//go:generate yasm -f elf64 gf_vect_mul_avx.asm -o gf_vect_mul_avx.syso +//go:generate yasm -f elf64 gf_vect_mul_sse.asm -o gf_vect_mul_sse.syso diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_windows.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_windows.go new file mode 100644 index 000000000..c3aa6f0de --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/erasure_yasm_windows.go @@ -0,0 +1,43 @@ +// !build amd64 + +package erasure + +//go:generate yasm -f win64 ec_multibinary.asm -o ec_multibinary.syso +//go:generate yasm -f win64 gf_2vect_mad_avx2.asm -o gf_2vect_mad_avx2.syso +//go:generate yasm -f win64 gf_2vect_mad_avx.asm -o gf_2vect_mad_avx.syso +//go:generate yasm -f win64 gf_2vect_mad_sse.asm -o gf_2vect_mad_sse.syso +//go:generate yasm -f win64 gf_3vect_mad_avx2.asm -o gf_3vect_mad_avx2.syso +//go:generate yasm -f win64 gf_3vect_mad_avx.asm -o gf_3vect_mad_avx.syso +//go:generate yasm -f win64 gf_3vect_mad_sse.asm -o gf_3vect_mad_sse.syso +//go:generate yasm -f win64 gf_4vect_mad_avx2.asm -o gf_4vect_mad_avx2.syso +//go:generate yasm -f win64 gf_4vect_mad_avx.asm -o gf_4vect_mad_avx.syso +//go:generate yasm -f win64 gf_4vect_mad_sse.asm -o gf_4vect_mad_sse.syso +//go:generate yasm -f win64 gf_5vect_mad_avx2.asm -o gf_5vect_mad_avx2.syso +//go:generate yasm -f win64 gf_5vect_mad_avx.asm -o gf_5vect_mad_avx.syso +//go:generate yasm -f win64 gf_5vect_mad_sse.asm -o gf_5vect_mad_sse.syso +//go:generate yasm -f win64 gf_6vect_mad_avx2.asm -o gf_6vect_mad_avx2.syso +//go:generate yasm -f win64 gf_6vect_mad_avx.asm -o gf_6vect_mad_avx.syso +//go:generate yasm -f win64 gf_6vect_mad_sse.asm -o gf_6vect_mad_sse.syso +//go:generate yasm -f win64 gf_vect_mad_avx2.asm -o gf_vect_mad_avx2.syso +//go:generate yasm -f win64 gf_vect_mad_avx.asm -o gf_vect_mad_avx.syso +//go:generate yasm -f win64 gf_vect_mad_sse.asm -o gf_vect_mad_sse.syso +//go:generate yasm -f win64 gf_2vect_dot_prod_avx2.asm -o gf_2vect_dot_prod_avx2.syso +//go:generate yasm -f win64 gf_2vect_dot_prod_avx.asm -o gf_2vect_dot_prod_avx.syso +//go:generate yasm -f win64 gf_2vect_dot_prod_sse.asm -o gf_2vect_dot_prod_sse.syso +//go:generate yasm -f win64 gf_3vect_dot_prod_avx2.asm -o gf_3vect_dot_prod_avx2.syso +//go:generate yasm -f win64 gf_3vect_dot_prod_avx.asm -o gf_3vect_dot_prod_avx.syso +//go:generate yasm -f win64 gf_3vect_dot_prod_sse.asm -o gf_3vect_dot_prod_sse.syso +//go:generate yasm -f win64 gf_4vect_dot_prod_avx2.asm -o gf_4vect_dot_prod_avx2.syso +//go:generate yasm -f win64 gf_4vect_dot_prod_avx.asm -o gf_4vect_dot_prod_avx.syso +//go:generate yasm -f win64 gf_4vect_dot_prod_sse.asm -o gf_4vect_dot_prod_sse.syso +//go:generate yasm -f win64 gf_5vect_dot_prod_avx2.asm -o gf_5vect_dot_prod_avx2.syso +//go:generate yasm -f win64 gf_5vect_dot_prod_avx.asm -o gf_5vect_dot_prod_avx.syso +//go:generate yasm -f win64 gf_5vect_dot_prod_sse.asm -o gf_5vect_dot_prod_sse.syso +//go:generate yasm -f win64 gf_6vect_dot_prod_avx2.asm -o gf_6vect_dot_prod_avx2.syso +//go:generate yasm -f win64 gf_6vect_dot_prod_avx.asm -o gf_6vect_dot_prod_avx.syso +//go:generate yasm -f win64 gf_6vect_dot_prod_sse.asm -o gf_6vect_dot_prod_sse.syso +//go:generate yasm -f win64 gf_vect_dot_prod_avx2.asm -o gf_vect_dot_prod_avx2.syso +//go:generate yasm -f win64 gf_vect_dot_prod_avx.asm -o gf_vect_dot_prod_avx.syso +//go:generate yasm -f win64 gf_vect_dot_prod_sse.asm -o gf_vect_dot_prod_sse.syso +//go:generate yasm -f win64 gf_vect_mul_avx.asm -o gf_vect_mul_avx.syso +//go:generate yasm -f win64 gf_vect_mul_sse.asm -o gf_vect_mul_sse.syso diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_avx.asm new file mode 100644 index 000000000..8dcc3382f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_avx.asm @@ -0,0 +1,381 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_2vect_dot_prod_avx(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_2VECT_DOT_PROD_AVX _gf_2vect_dot_prod_avx +%else + %define GF_2VECT_DOT_PROD_AVX gf_2vect_dot_prod_avx +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r9 + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 3*16 + 3*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_reg r12, 3*16 + 0*8 + save_reg r13, 3*16 + 1*8 + save_reg r14, 3*16 + 2*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + mov r12, [rsp + 3*16 + 0*8] + mov r13, [rsp + 3*16 + 1*8] + mov r14, [rsp + 3*16 + 2*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define tmp edx + %define tmp2 edi + %define tmp3 trans2 + %define tmp4 trans2 + %define tmp4_m var(0) + %define return eax + %macro SLDR 2 ;; stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*1 ;1 local variable + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*1 ;1 local variable + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 + +%define vec_i tmp2 +%define ptr tmp3 +%define dest2 tmp4 +%define pos return + + %ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp4_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +%ifidn PS,8 ; 64-bit code + default rel + [bits 64] +%endif + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f xmm8 + %define xgft1_lo xmm7 + %define xgft1_hi xmm6 + %define xgft2_lo xmm5 + %define xgft2_hi xmm4 + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 +%else ;32-bit code + %define xmask0f xmm4 + %define xgft1_lo xmm7 + %define xgft1_hi xmm6 + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 +%endif + +align 16 +global GF_2VECT_DOT_PROD_AVX:function + +func(GF_2VECT_DOT_PROD_AVX) + FUNC_SAVE + SLDR len, len_m + sub len, 16 + SSTR len_m, len + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop16 + vpxor xp1, xp1 + vpxor xp2, xp2 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect + SLDR src, src_m + mov ptr, [src+vec_i] + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + vmovdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + %ifidn PS,8 ; 64-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + vmovdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + add tmp, 32 + add vec_i, PS + %endif + XLDR x0, [ptr+pos] ;Get next source vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ; 32-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + vmovdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + add tmp, 32 + add vec_i, PS + %endif + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + + SLDR len, len_m + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_2VECT_DOT_PROD_AVX, 02, 04, 0191 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_avx2.asm new file mode 100644 index 000000000..583ce7416 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_avx2.asm @@ -0,0 +1,398 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_2vect_dot_prod_avx2(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_2VECT_DOT_PROD_AVX2 _gf_2vect_dot_prod_avx2 +%else + %define GF_2VECT_DOT_PROD_AVX2 gf_2vect_dot_prod_avx2 +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r9 + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r9 + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 3*16 + 3*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + vmovdqa [rsp + 0*16], xmm6 + vmovdqa [rsp + 1*16], xmm7 + vmovdqa [rsp + 2*16], xmm8 + save_reg r12, 3*16 + 0*8 + save_reg r13, 3*16 + 1*8 + save_reg r14, 3*16 + 2*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + mov r12, [rsp + 3*16 + 0*8] + mov r13, [rsp + 3*16 + 1*8] + mov r14, [rsp + 3*16 + 2*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define tmp edx + %define tmp.w edx + %define tmp.b dl + %define tmp2 edi + %define tmp3 trans2 + %define tmp4 trans2 + %define tmp4_m var(0) + %define return eax + %macro SLDR 2 ;stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*1 ;1 local variable + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*1 ;1 local variable + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 + +%define vec_i tmp2 +%define ptr tmp3 +%define dest2 tmp4 +%define pos return + +%ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp4_m +%endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else + +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +%ifidn PS,8 ;64-bit code + default rel + [bits 64] +%endif + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f ymm8 + %define xmask0fx xmm8 + %define xgft1_lo ymm7 + %define xgft1_hi ymm6 + %define xgft2_lo ymm5 + %define xgft2_hi ymm4 + + %define x0 ymm0 + %define xtmpa ymm1 + %define xp1 ymm2 + %define xp2 ymm3 +%else ;32-bit code + %define xmask0f ymm7 + %define xmask0fx xmm7 + %define xgft1_lo ymm5 + %define xgft1_hi ymm4 + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + + %define x0 ymm0 + %define xtmpa ymm1 + %define xp1 ymm2 + %define xp2 ymm3 + +%endif + +align 16 +global GF_2VECT_DOT_PROD_AVX2:function + +func(GF_2VECT_DOT_PROD_AVX2) + FUNC_SAVE + SLDR len, len_m + sub len, 32 + SSTR len_m, len + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop32 + vpxor xp1, xp1 + vpxor xp2, xp2 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect + SLDR src, src_m + mov ptr, [src+vec_i] + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft1_lo, xgft1_lo, xgft1_lo, 0x00 ; swapped to lo | lo + %ifidn PS,8 ; 64-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft2_lo, xgft2_lo, xgft2_lo, 0x00 ; swapped to lo | lo + + XLDR x0, [ptr+pos] ;Get next source vector + add tmp, 32 + add vec_i, PS + %else + XLDR x0, [ptr+pos] ;Get next source vector + %endif + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ; 32-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft2_lo, xgft2_lo, xgft2_lo, 0x00 ; swapped to lo | lo + add tmp, 32 + add vec_i, PS + %endif + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + + SLDR len, len_m + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop32 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_2VECT_DOT_PROD_AVX2, 04, 04, 0196 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_sse.asm new file mode 100644 index 000000000..5237314c6 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_dot_prod_sse.asm @@ -0,0 +1,383 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_2vect_dot_prod_sse(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_2VECT_DOT_PROD_SSE _gf_2vect_dot_prod_sse +%else + %define GF_2VECT_DOT_PROD_SSE gf_2vect_dot_prod_sse +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r9 + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 3*16 + 3*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_reg r12, 3*16 + 0*8 + save_reg r13, 3*16 + 1*8 + save_reg r14, 3*16 + 2*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + movdqa xmm6, [rsp + 0*16] + movdqa xmm7, [rsp + 1*16] + movdqa xmm8, [rsp + 2*16] + mov r12, [rsp + 3*16 + 0*8] + mov r13, [rsp + 3*16 + 1*8] + mov r14, [rsp + 3*16 + 2*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define tmp edx + %define tmp2 edi + %define tmp3 trans2 + %define tmp4 trans2 + %define tmp4_m var(0) + %define return eax + %macro SLDR 2 ;; stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*1 ;1 local variable + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*1 ;1 local variable + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 + +%define vec_i tmp2 +%define ptr tmp3 +%define dest2 tmp4 +%define pos return + + %ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp4_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +%ifidn PS,8 ;64-bit code + default rel + [bits 64] +%endif + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f xmm8 + %define xgft1_lo xmm7 + %define xgft1_hi xmm6 + %define xgft2_lo xmm5 + %define xgft2_hi xmm4 + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 +%else ;32-bit code + %define xmask0f xmm4 + %define xgft1_lo xmm7 + %define xgft1_hi xmm6 + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 +%endif + +align 16 +global GF_2VECT_DOT_PROD_SSE:function + +func(GF_2VECT_DOT_PROD_SSE) + FUNC_SAVE + SLDR len, len_m + sub len, 16 + SSTR len_m, len + jl .return_fail + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop16 + pxor xp1, xp1 + pxor xp2, xp2 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect + SLDR src, src_m + mov ptr, [src+vec_i] + + movdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + movdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + %ifidn PS,8 ;64-bit code + movdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + movdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + add tmp, 32 + add vec_i, PS + %endif + XLDR x0, [ptr+pos] ;Get next source vector + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + pshufb xgft1_hi, x0 ;Lookup mul table of high nibble + pshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft1_hi, xgft1_lo ;GF add high and low partials + pxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ;32-bit code + movdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + movdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + + add tmp, 32 + add vec_i, PS + %endif + pshufb xgft2_hi, x0 ;Lookup mul table of high nibble + pshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft2_hi, xgft2_lo ;GF add high and low partials + pxor xp2, xgft2_hi ;xp2 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + + SLDR len, len_m + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_2VECT_DOT_PROD_SSE, 00, 03, 0062 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_avx.asm new file mode 100644 index 000000000..9542e7e6b --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_avx.asm @@ -0,0 +1,264 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_2vect_mad_avx(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_2VECT_MAD_AVX _gf_2vect_mad_avx +%else + %define GF_2VECT_MAD_AVX gf_2vect_mad_avx +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp2 r10 + %define return rax + %define return.w eax + %define stack_size 16*9 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + save_reg r12, 9*16 + 0*8 + save_reg r15, 9*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + mov r12, [rsp + 9*16 + 0*8] + mov r15, [rsp + 9*16 + 1*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_2vect_mad_avx(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 tmp2 + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f xmm14 +%define xgft1_lo xmm13 +%define xgft1_hi xmm12 +%define xgft2_lo xmm11 +%define xgft2_hi xmm10 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xd1 xmm6 +%define xd2 xmm7 +%define xtmpd1 xmm8 +%define xtmpd2 xmm9 + + +align 16 +global GF_2VECT_MAD_AVX:function + +func(GF_2VECT_MAD_AVX) + FUNC_SAVE + sub len, 16 + jl .return_fail + + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 + lea tmp, [mul_array + vec_i] + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + vmovdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + vmovdqu xgft2_hi, [tmp+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + + mov dest2, [dest1+PS] + mov dest1, [dest1] + + XLDR xtmpd1, [dest1+len] ;backup the last 16 bytes in dest + XLDR xtmpd2, [dest2+len] ;backup the last 16 bytes in dest + +.loop16 + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector +.loop16_overlap: + XLDR x0, [src+pos] ;Get next source vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xtmph1, xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + vpshufb xtmph2, xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl2 ;GF add high and low partials + vpxor xd2, xd2, xtmph2 ;xd2 += partial + + XSTR [dest1+pos], xd1 + XSTR [dest2+pos], xd2 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + vmovdqa xd1, xtmpd1 ;Restore xd1 + vmovdqa xd2, xtmpd2 ;Restore xd2 + jmp .loop16_overlap ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_2VECT_MAD_AVX, 02, 00, 0204 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_avx2.asm new file mode 100644 index 000000000..a6a2253ea --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_avx2.asm @@ -0,0 +1,280 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_2vect_mad_avx2(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_2VECT_MAD_AVX2 _gf_2vect_mad_avx2 +%else + %define GF_2VECT_MAD_AVX2 gf_2vect_mad_avx2 +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define return rax + %define return.w eax + %define stack_size 16*9 + 3*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + sub rsp, stack_size + vmovdqa [rsp+16*0],xmm6 + vmovdqa [rsp+16*1],xmm7 + vmovdqa [rsp+16*2],xmm8 + vmovdqa [rsp+16*3],xmm9 + vmovdqa [rsp+16*4],xmm10 + vmovdqa [rsp+16*5],xmm11 + vmovdqa [rsp+16*6],xmm12 + vmovdqa [rsp+16*7],xmm13 + vmovdqa [rsp+16*8],xmm14 + save_reg r12, 9*16 + 0*8 + save_reg r15, 9*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp+16*0] + vmovdqa xmm7, [rsp+16*1] + vmovdqa xmm8, [rsp+16*2] + vmovdqa xmm9, [rsp+16*3] + vmovdqa xmm10, [rsp+16*4] + vmovdqa xmm11, [rsp+16*5] + vmovdqa xmm12, [rsp+16*6] + vmovdqa xmm13, [rsp+16*7] + vmovdqa xmm14, [rsp+16*8] + mov r12, [rsp + 9*16 + 0*8] + mov r15, [rsp + 9*16 + 1*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_2vect_mad_avx2(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 tmp2 + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else + +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f ymm14 +%define xmask0fx xmm14 +%define xgft1_lo ymm13 +%define xgft1_hi ymm12 +%define xgft2_lo ymm11 +%define xgft2_hi ymm10 + +%define x0 ymm0 +%define xtmpa ymm1 +%define xtmph1 ymm2 +%define xtmpl1 ymm3 +%define xtmph2 ymm4 +%define xtmpl2 ymm5 +%define xd1 ymm6 +%define xd2 ymm7 +%define xtmpd1 ymm8 +%define xtmpd2 ymm9 + +align 16 +global GF_2VECT_MAD_AVX2:function + +func(GF_2VECT_MAD_AVX2) + FUNC_SAVE + sub len, 32 + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 + lea tmp, [mul_array + vec_i] + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft1_lo, xgft1_lo, xgft1_lo, 0x00 ; swapped to lo | lo + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft2_lo, xgft2_lo, xgft2_lo, 0x00 ; swapped to lo | lo + mov dest2, [dest1+PS] ; reuse mul_array + mov dest1, [dest1] + + XLDR xtmpd1, [dest1+len] ;backup the last 16 bytes in dest + XLDR xtmpd2, [dest2+len] ;backup the last 16 bytes in dest + +.loop32 + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector +.loop32_overlap: + XLDR x0, [src+pos] ;Get next source vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xtmph1, xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + vpshufb xtmph2, xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl2 ;GF add high and low partials + vpxor xd2, xd2, xtmph2 ;xd2 += partial + + XSTR [dest1+pos], xd1 + XSTR [dest2+pos], xd2 + + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-32 + vmovdqa xd1, xtmpd1 ;Restore xd1 + vmovdqa xd2, xtmpd2 ;Restore xd2 + jmp .loop32_overlap ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_2VECT_MAD_AVX2, 04, 00, 0205 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_sse.asm new file mode 100644 index 000000000..af1b0c0d5 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_2vect_mad_sse.asm @@ -0,0 +1,267 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_2vect_mad_sse(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_2VECT_MAD_SSE _gf_2vect_mad_sse +%else + %define GF_2VECT_MAD_SSE gf_2vect_mad_sse +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp2 r10 + %define return rax + %define return.w eax + %define stack_size 16*9 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + save_reg r12, 9*16 + 0*8 + save_reg r15, 9*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + mov r12, [rsp + 9*16 + 0*8] + mov r15, [rsp + 9*16 + 1*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_2vect_mad_sse(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 tmp2 + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm14 +%define xgft1_lo xmm13 +%define xgft1_hi xmm12 +%define xgft2_lo xmm11 +%define xgft2_hi xmm10 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xd1 xmm6 +%define xd2 xmm7 +%define xtmpd1 xmm8 +%define xtmpd2 xmm9 + + +align 16 +global GF_2VECT_MAD_SSE:function +func(GF_2VECT_MAD_SSE) + FUNC_SAVE + sub len, 16 + jl .return_fail + + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 + lea tmp, [mul_array + vec_i] + movdqu xgft1_lo,[tmp] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + movdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + movdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + movdqu xgft2_hi, [tmp+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + mov dest2, [dest1+PS] + mov dest1, [dest1] + + XLDR xtmpd1, [dest1+len] ;backup the last 16 bytes in dest + XLDR xtmpd2, [dest2+len] ;backup the last 16 bytes in dest + +.loop16: + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector +.loop16_overlap: + XLDR x0, [src+pos] ;Get next source vector + movdqa xtmph1, xgft1_hi ;Reload const array registers + movdqa xtmpl1, xgft1_lo + movdqa xtmph2, xgft2_hi ;Reload const array registers + movdqa xtmpl2, xgft2_lo + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + pshufb xtmph1, x0 ;Lookup mul table of high nibble + pshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + pxor xtmph1, xtmpl1 ;GF add high and low partials + pxor xd1, xtmph1 + + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl2 ;GF add high and low partials + pxor xd2, xtmph2 + + XSTR [dest1+pos], xd1 ;Store result + XSTR [dest2+pos], xd2 ;Store result + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + movdqa xd1, xtmpd1 ;Restore xd1 + movdqa xd2, xtmpd2 ;Restore xd2 + jmp .loop16_overlap ;Do one more overlap pass + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 + +mask0f: + ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_2VECT_MAD_SSE, 00, 00, 0203 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_avx.asm new file mode 100644 index 000000000..70a468f25 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_avx.asm @@ -0,0 +1,421 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_3vect_dot_prod_avx(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_3VECT_DOT_PROD_AVX _gf_3vect_dot_prod_avx +%else + %define GF_3VECT_DOT_PROD_AVX gf_3vect_dot_prod_avx +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 6*16 + 5*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_xmm128 xmm9, 3*16 + save_xmm128 xmm10, 4*16 + save_xmm128 xmm11, 5*16 + save_reg r12, 6*16 + 0*8 + save_reg r13, 6*16 + 1*8 + save_reg r14, 6*16 + 2*8 + save_reg r15, 6*16 + 3*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + vmovdqa xmm9, [rsp + 3*16] + vmovdqa xmm10, [rsp + 4*16] + vmovdqa xmm11, [rsp + 5*16] + mov r12, [rsp + 6*16 + 0*8] + mov r13, [rsp + 6*16 + 1*8] + mov r14, [rsp + 6*16 + 2*8] + mov r15, [rsp + 6*16 + 3*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; var1 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define arg5 trans2 + %define tmp edx + %define tmp2 edi + %define tmp3 trans2 + %define tmp3_m var(0) + %define tmp4 trans2 + %define tmp4_m var(1) + %define return eax + %macro SLDR 2 ;; stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*2 ;2 local variables + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*2 ;2 local variables + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 +%define ptr arg5 + +%define vec_i tmp2 +%define dest2 tmp3 +%define dest3 tmp4 +%define pos return + + %ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp3_m + %define dest3_m tmp4_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +%ifidn PS,8 ; 64-bit code + default rel + [bits 64] +%endif + + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f xmm11 + %define xgft1_lo xmm10 + %define xgft1_hi xmm9 + %define xgft2_lo xmm8 + %define xgft2_hi xmm7 + %define xgft3_lo xmm6 + %define xgft3_hi xmm5 + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 + %define xp3 xmm4 +%else + %define xmask0f xmm7 + %define xgft1_lo xmm6 + %define xgft1_hi xmm5 + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + %define xgft3_lo xgft1_lo + %define xgft3_hi xgft1_hi + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 + %define xp3 xmm4 +%endif + +align 16 +global GF_3VECT_DOT_PROD_AVX:function +func(GF_3VECT_DOT_PROD_AVX) + FUNC_SAVE + SLDR len, len_m + sub len, 16 + SSTR len_m, len + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest3, [dest1+2*PS] + SSTR dest3_m, dest3 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop16: + vpxor xp1, xp1 + vpxor xp2, xp2 + vpxor xp3, xp3 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + SLDR src, src_m + mov ptr, [src+vec_i] + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + vmovdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + %ifidn PS,8 ; 64-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + vmovdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+vec*(64/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + vmovdqu xgft3_hi, [tmp+vec*(64/PS)+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + add tmp, 32 + add vec_i, PS + %endif + XLDR x0, [ptr+pos] ;Get next source vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ; 32-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + vmovdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + %endif + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + %ifidn PS,4 ; 32-bit code + sal vec, 1 + vmovdqu xgft3_lo, [tmp+vec*(32/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + vmovdqu xgft3_hi, [tmp+vec*(32/PS)+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + sar vec, 1 + add tmp, 32 + add vec_i, PS + %endif + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp3, xgft3_hi ;xp3 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + SLDR dest3, dest3_m + XSTR [dest3+pos], xp3 + + SLDR len, len_m + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_3VECT_DOT_PROD_AVX, 02, 04, 0192 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_avx2.asm new file mode 100644 index 000000000..469a41098 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_avx2.asm @@ -0,0 +1,441 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_3vect_dot_prod_avx2(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_3VECT_DOT_PROD_AVX2 _gf_3vect_dot_prod_avx2 +%else + %define GF_3VECT_DOT_PROD_AVX2 gf_3vect_dot_prod_avx2 +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 6*16 + 5*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + vmovdqa [rsp + 0*16], xmm6 + vmovdqa [rsp + 1*16], xmm7 + vmovdqa [rsp + 2*16], xmm8 + vmovdqa [rsp + 3*16], xmm9 + vmovdqa [rsp + 4*16], xmm10 + vmovdqa [rsp + 5*16], xmm11 + save_reg r12, 6*16 + 0*8 + save_reg r13, 6*16 + 1*8 + save_reg r14, 6*16 + 2*8 + save_reg r15, 6*16 + 3*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + vmovdqa xmm9, [rsp + 3*16] + vmovdqa xmm10, [rsp + 4*16] + vmovdqa xmm11, [rsp + 5*16] + mov r12, [rsp + 6*16 + 0*8] + mov r13, [rsp + 6*16 + 1*8] + mov r14, [rsp + 6*16 + 2*8] + mov r15, [rsp + 6*16 + 3*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; var1 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define arg5 trans2 + %define tmp edx + %define tmp.w edx + %define tmp.b dl + %define tmp2 edi + %define tmp3 trans2 + %define tmp3_m var(0) + %define tmp4 trans2 + %define tmp4_m var(1) + %define return eax + %macro SLDR 2 ;stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*2 ;2 local variables + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*2 ;2 local variables + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 +%define ptr arg5 + +%define vec_i tmp2 +%define dest2 tmp3 +%define dest3 tmp4 +%define pos return + +%ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp3_m + %define dest3_m tmp4_m +%endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +%ifidn PS,8 ;64-bit code + default rel + [bits 64] +%endif + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f ymm11 + %define xmask0fx xmm11 + %define xgft1_lo ymm10 + %define xgft1_hi ymm9 + %define xgft2_lo ymm8 + %define xgft2_hi ymm7 + %define xgft3_lo ymm6 + %define xgft3_hi ymm5 + + %define x0 ymm0 + %define xtmpa ymm1 + %define xp1 ymm2 + %define xp2 ymm3 + %define xp3 ymm4 +%else + %define xmask0f ymm7 + %define xmask0fx xmm7 + %define xgft1_lo ymm6 + %define xgft1_hi ymm5 + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + %define xgft3_lo xgft1_lo + %define xgft3_hi xgft1_hi + + %define x0 ymm0 + %define xtmpa ymm1 + %define xp1 ymm2 + %define xp2 ymm3 + %define xp3 ymm4 + +%endif + +align 16 +global GF_3VECT_DOT_PROD_AVX2:function +func(GF_3VECT_DOT_PROD_AVX2) + FUNC_SAVE + SLDR len, len_m + sub len, 32 + SSTR len_m, len + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest3, [dest1+2*PS] + SSTR dest3_m, dest3 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop32: + vpxor xp1, xp1 + vpxor xp2, xp2 + vpxor xp3, xp3 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + SLDR src, src_m + mov ptr, [src+vec_i] + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft1_lo, xgft1_lo, xgft1_lo, 0x00 ; swapped to lo | lo + %ifidn PS,8 ; 64-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft2_lo, xgft2_lo, xgft2_lo, 0x00 ; swapped to lo | lo + + vmovdqu xgft3_lo, [tmp+vec*(64/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + ; " Cx{00}, Cx{10}, ..., Cx{f0} + vperm2i128 xgft3_hi, xgft3_lo, xgft3_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft3_lo, xgft3_lo, xgft3_lo, 0x00 ; swapped to lo | lo + + add tmp, 32 + add vec_i, PS + %endif + XLDR x0, [ptr+pos] ;Get next source vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ; 32-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft2_lo, xgft2_lo, xgft2_lo, 0x00 ; swapped to lo | lo + %endif + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + %ifidn PS,4 ; 32-bit code + sal vec, 1 + vmovdqu xgft3_lo, [tmp+vec*(32/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + ; " Cx{00}, Cx{10}, ..., Cx{f0} + vperm2i128 xgft3_hi, xgft3_lo, xgft3_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft3_lo, xgft3_lo, xgft3_lo, 0x00 ; swapped to lo | lo + sar vec, 1 + add tmp, 32 + add vec_i, PS + %endif + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp3, xgft3_hi ;xp3 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + SLDR dest3, dest3_m + XSTR [dest3+pos], xp3 + + SLDR len, len_m + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop32 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_3VECT_DOT_PROD_AVX2, 04, 04, 0197 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_sse.asm new file mode 100644 index 000000000..bd0ae4f5f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_dot_prod_sse.asm @@ -0,0 +1,422 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_3vect_dot_prod_sse(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_3VECT_DOT_PROD_SSE _gf_3vect_dot_prod_sse +%else + %define GF_3VECT_DOT_PROD_SSE gf_3vect_dot_prod_sse +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 6*16 + 5*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_xmm128 xmm9, 3*16 + save_xmm128 xmm10, 4*16 + save_xmm128 xmm11, 5*16 + save_reg r12, 6*16 + 0*8 + save_reg r13, 6*16 + 1*8 + save_reg r14, 6*16 + 2*8 + save_reg r15, 6*16 + 3*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + movdqa xmm6, [rsp + 0*16] + movdqa xmm7, [rsp + 1*16] + movdqa xmm8, [rsp + 2*16] + movdqa xmm9, [rsp + 3*16] + movdqa xmm10, [rsp + 4*16] + movdqa xmm11, [rsp + 5*16] + mov r12, [rsp + 6*16 + 0*8] + mov r13, [rsp + 6*16 + 1*8] + mov r14, [rsp + 6*16 + 2*8] + mov r15, [rsp + 6*16 + 3*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; var1 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define arg5 trans2 + %define tmp edx + %define tmp2 edi + %define tmp3 trans2 + %define tmp3_m var(0) + %define tmp4 trans2 + %define tmp4_m var(1) + %define return eax + %macro SLDR 2 ;; stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*2 ;2 local variables + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*2 ;2 local variables + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 +%define ptr arg5 + +%define vec_i tmp2 +%define dest2 tmp3 +%define dest3 tmp4 +%define pos return + + %ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp3_m + %define dest3_m tmp4_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +%ifidn PS,8 ; 64-bit code + default rel + [bits 64] +%endif + + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f xmm11 + %define xgft1_lo xmm2 + %define xgft1_hi xmm3 + %define xgft2_lo xmm4 + %define xgft2_hi xmm7 + %define xgft3_lo xmm6 + %define xgft3_hi xmm5 + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm10 + %define xp2 xmm9 + %define xp3 xmm8 +%else + %define xmask0f xmm7 + %define xgft1_lo xmm6 + %define xgft1_hi xmm5 + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + %define xgft3_lo xgft1_lo + %define xgft3_hi xgft1_hi + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 + %define xp3 xmm4 +%endif + +align 16 +global GF_3VECT_DOT_PROD_SSE:function +func(GF_3VECT_DOT_PROD_SSE) + FUNC_SAVE + SLDR len, len_m + sub len, 16 + SSTR len_m, len + jl .return_fail + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest3, [dest1+2*PS] + SSTR dest3_m, dest3 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop16: + pxor xp1, xp1 + pxor xp2, xp2 + pxor xp3, xp3 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + SLDR src, src_m + mov ptr, [src+vec_i] + + movdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + movdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + %ifidn PS,8 ;64-bit code + movdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + movdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + movdqu xgft3_lo, [tmp+vec*(64/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + movdqu xgft3_hi, [tmp+vec*(64/PS)+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + add tmp, 32 + add vec_i, PS + %endif + XLDR x0, [ptr+pos] ;Get next source vector + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + pshufb xgft1_hi, x0 ;Lookup mul table of high nibble + pshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft1_hi, xgft1_lo ;GF add high and low partials + pxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ;32-bit code + movdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + movdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + %endif + pshufb xgft2_hi, x0 ;Lookup mul table of high nibble + pshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft2_hi, xgft2_lo ;GF add high and low partials + pxor xp2, xgft2_hi ;xp2 += partial + + %ifidn PS,4 ;32-bit code + sal vec, 1 + movdqu xgft3_lo, [tmp+vec*(32/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + movdqu xgft3_hi, [tmp+vec*(32/PS)+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + sar vec, 1 + add tmp, 32 + add vec_i, PS + %endif + pshufb xgft3_hi, x0 ;Lookup mul table of high nibble + pshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft3_hi, xgft3_lo ;GF add high and low partials + pxor xp3, xgft3_hi ;xp3 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + SLDR dest3, dest3_m + XSTR [dest3+pos], xp3 + + SLDR len, len_m + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_3VECT_DOT_PROD_SSE, 00, 05, 0063 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_avx.asm new file mode 100644 index 000000000..f3cabd68e --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_avx.asm @@ -0,0 +1,315 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_3vect_mad_avx(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_3VECT_MAD_AVX _gf_3vect_mad_avx +%else + %define GF_3VECT_MAD_AVX gf_3vect_mad_avx +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define return rax + %define return.w eax + %define stack_size 16*10 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + vmovdqa [rsp+16*0],xmm6 + vmovdqa [rsp+16*1],xmm7 + vmovdqa [rsp+16*2],xmm8 + vmovdqa [rsp+16*3],xmm9 + vmovdqa [rsp+16*4],xmm10 + vmovdqa [rsp+16*5],xmm11 + vmovdqa [rsp+16*6],xmm12 + vmovdqa [rsp+16*7],xmm13 + vmovdqa [rsp+16*8],xmm14 + vmovdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r15, 10*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp+16*0] + vmovdqa xmm7, [rsp+16*1] + vmovdqa xmm8, [rsp+16*2] + vmovdqa xmm9, [rsp+16*3] + vmovdqa xmm10, [rsp+16*4] + vmovdqa xmm11, [rsp+16*5] + vmovdqa xmm12, [rsp+16*6] + vmovdqa xmm13, [rsp+16*7] + vmovdqa xmm14, [rsp+16*8] + vmovdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r15, [rsp + 10*16 + 1*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_3vect_mad_avx(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 mul_array +%define dest3 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft1_lo xmm14 +%define xgft1_hi xmm13 +%define xgft2_lo xmm12 +%define xgft2_hi xmm11 +%define xgft3_lo xmm10 +%define xgft3_hi xmm9 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xtmph3 xmm6 +%define xtmpl3 xmm7 +%define xd1 xmm8 +%define xd2 xtmpl1 +%define xd3 xtmph1 + +align 16 +global GF_3VECT_MAD_AVX:function +func(GF_3VECT_MAD_AVX) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 + lea tmp, [mul_array + vec_i] + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + vmovdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + vmovdqu xgft2_hi, [tmp+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xgft3_lo, [tmp+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + vmovdqu xgft3_hi, [tmp+2*vec+16]; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + mov dest2, [dest1+PS] ; reuse mul_array + mov dest3, [dest1+2*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop16: + XLDR x0, [src+pos] ;Get next source vector + XLDR xd1, [dest1+pos] ;Get next dest vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ; dest1 + vpshufb xtmph1, xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + XLDR xd2, [dest2+pos] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest3+pos] ;reuse xtmph1. Get next dest vector + + ; dest2 + vpshufb xtmph2, xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl2 ;GF add high and low partials + vpxor xd2, xd2, xtmph2 ;xd2 += partial + + ; dest3 + vpshufb xtmph3, xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmph3, xtmpl3 ;GF add high and low partials + vpxor xd3, xd3, xtmph3 ;xd3 += partial + + XSTR [dest1+pos], xd1 + XSTR [dest2+pos], xd2 + XSTR [dest3+pos], xd3 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + +.lessthan16: + ;; Tail len + ;; Do one more overlap pass + mov tmp, len ;Overlapped offset length-16 + XLDR x0, [src+tmp] ;Get next source vector + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest3+tmp] ;reuse xtmph1. Get next dest vector + + sub len, pos + + movdqa xtmph3, [constip16] ;Load const of i + 16 + vpinsrb xtmpl3, xtmpl3, len.w, 15 + vpshufb xtmpl3, xtmpl3, xmask0f ;Broadcast len to all bytes + vpcmpgtb xtmpl3, xtmpl3, xtmph3 + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ; dest1 + vpshufb xgft1_hi, xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_hi, xgft1_lo ;GF add high and low partials + vpand xgft1_hi, xgft1_hi, xtmpl3 + vpxor xd1, xd1, xgft1_hi + + ; dest2 + vpshufb xgft2_hi, xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_hi, xgft2_lo ;GF add high and low partials + vpand xgft2_hi, xgft2_hi, xtmpl3 + vpxor xd2, xd2, xgft2_hi + + ; dest3 + vpshufb xgft3_hi, xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_hi, xgft3_lo ;GF add high and low partials + vpand xgft3_hi, xgft3_hi, xtmpl3 + vpxor xd3, xd3, xgft3_hi + + XSTR [dest1+tmp], xd1 + XSTR [dest2+tmp], xd2 + XSTR [dest3+tmp], xd3 + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +constip16: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_3VECT_MAD_AVX, 02, 00, 0207 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_avx2.asm new file mode 100644 index 000000000..092538000 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_avx2.asm @@ -0,0 +1,347 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_3vect_mad_avx2(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_3VECT_MAD_AVX2 _gf_3vect_mad_avx2 +%else + %define GF_3VECT_MAD_AVX2 gf_3vect_mad_avx2 +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + %define stack_size 16*10 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + + %macro FUNC_SAVE 0 + sub rsp, stack_size + vmovdqa [rsp+16*0],xmm6 + vmovdqa [rsp+16*1],xmm7 + vmovdqa [rsp+16*2],xmm8 + vmovdqa [rsp+16*3],xmm9 + vmovdqa [rsp+16*4],xmm10 + vmovdqa [rsp+16*5],xmm11 + vmovdqa [rsp+16*6],xmm12 + vmovdqa [rsp+16*7],xmm13 + vmovdqa [rsp+16*8],xmm14 + vmovdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r15, 10*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp+16*0] + vmovdqa xmm7, [rsp+16*1] + vmovdqa xmm8, [rsp+16*2] + vmovdqa xmm9, [rsp+16*3] + vmovdqa xmm10, [rsp+16*4] + vmovdqa xmm11, [rsp+16*5] + vmovdqa xmm12, [rsp+16*6] + vmovdqa xmm13, [rsp+16*7] + vmovdqa xmm14, [rsp+16*8] + vmovdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r15, [rsp + 10*16 + 1*8] + add rsp, stack_size + %endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_3vect_mad_avx2(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 mul_array +%define dest3 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f ymm15 +%define xmask0fx xmm15 +%define xgft1_lo ymm14 +%define xgft1_hi ymm13 +%define xgft2_lo ymm12 +%define xgft3_lo ymm11 + +%define x0 ymm0 +%define xtmpa ymm1 +%define xtmph1 ymm2 +%define xtmpl1 ymm3 +%define xtmph2 ymm4 +%define xtmpl2 ymm5 +%define xtmpl2x xmm5 +%define xtmph3 ymm6 +%define xtmpl3 ymm7 +%define xtmpl3x xmm7 +%define xd1 ymm8 +%define xd2 ymm9 +%define xd3 ymm10 + +align 16 +global GF_3VECT_MAD_AVX2:function +func(GF_3VECT_MAD_AVX2) + FUNC_SAVE + sub len, 32 + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 + lea tmp, [mul_array + vec_i] + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft1_lo, xgft1_lo, xgft1_lo, 0x00 ; swapped to lo | lo + + vmovdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xgft3_lo, [tmp+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + mov dest2, [dest1+PS] ; reuse mul_array + mov dest3, [dest1+2*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop32: + XLDR x0, [src+pos] ;Get next source vector + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector + XLDR xd3, [dest3+pos] ;Get next dest vector + vperm2i128 xtmph2, xgft2_lo, xgft2_lo, 0x11 ; swapped to hi | hi + vperm2i128 xtmpl2, xgft2_lo, xgft2_lo, 0x00 ; swapped to lo | lo + + vperm2i128 xtmph3, xgft3_lo, xgft3_lo, 0x11 ; swapped to hi | hi + vperm2i128 xtmpl3, xgft3_lo, xgft3_lo, 0x00 ; swapped to lo | lo + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ; dest1 + vpshufb xtmph1, xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + ; dest2 + vpshufb xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmpl2 ;GF add high and low partials + vpxor xd2, xtmph2 ;xd2 += partial + + ; dest3 + vpshufb xtmph3, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmpl3 ;GF add high and low partials + vpxor xd3, xtmph3 ;xd3 += partial + + XSTR [dest1+pos], xd1 + XSTR [dest2+pos], xd2 + XSTR [dest3+pos], xd3 + + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + +.lessthan32: + ;; Tail len + ;; Do one more overlap pass + mov tmp.b, 0x1f + vpinsrb xtmpl2x, xtmpl2x, tmp.w, 0 + vpbroadcastb xtmpl2, xtmpl2x ;Construct mask 0x1f1f1f... + + mov tmp, len ;Overlapped offset length-32 + + XLDR x0, [src+tmp] ;Get next source vector + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;Get next dest vector + XLDR xd3, [dest3+tmp] ;Get next dest vector + + sub len, pos + + vmovdqa xtmph3, [constip32] ;Load const of i + 32 + vpinsrb xtmpl3x, xtmpl3x, len.w, 15 + vinserti128 xtmpl3, xtmpl3, xtmpl3x, 1 ;swapped to xtmpl3x | xtmpl3x + vpshufb xtmpl3, xtmpl3, xtmpl2 ;Broadcast len to all bytes. xtmpl2=0x1f1f1f... + vpcmpgtb xtmpl3, xtmpl3, xtmph3 + + vperm2i128 xtmph2, xgft2_lo, xgft2_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft2_lo, xgft2_lo, xgft2_lo, 0x00 ; swapped to lo | lo + + vperm2i128 xtmph3, xgft3_lo, xgft3_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft3_lo, xgft3_lo, xgft3_lo, 0x00 ; swapped to lo | lo + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ; dest1 + vpshufb xtmph1, xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpand xtmph1, xtmph1, xtmpl3 + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xgft2_lo ;GF add high and low partials + vpand xtmph2, xtmph2, xtmpl3 + vpxor xd2, xd2, xtmph2 ;xd2 += partial + + ; dest3 + vpshufb xtmph3, xtmph3, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmph3, xgft3_lo ;GF add high and low partials + vpand xtmph3, xtmph3, xtmpl3 + vpxor xd3, xd3, xtmph3 ;xd3 += partial + + XSTR [dest1+tmp], xd1 + XSTR [dest2+tmp], xd2 + XSTR [dest3+tmp], xd3 + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 32 +constip32: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + ddq 0xe0e1e2e3e4e5e6e7e8e9eaebecedeeef + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_3VECT_MAD_AVX2, 04, 00, 0208 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_sse.asm new file mode 100644 index 000000000..c011eba8a --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_3vect_mad_sse.asm @@ -0,0 +1,326 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_3vect_mad_sse(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_3VECT_MAD_SSE _gf_3vect_mad_sse +%else + %define GF_3VECT_MAD_SSE gf_3vect_mad_sse +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define return rax + %define return.w eax + %define stack_size 16*10 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r15, 10*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r15, [rsp + 10*16 + 1*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_3vect_mad_sse(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 mul_array +%define dest3 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft1_lo xmm14 +%define xgft1_hi xmm13 +%define xgft2_lo xmm12 +%define xgft2_hi xmm11 +%define xgft3_lo xmm10 +%define xgft3_hi xmm9 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xtmph3 xmm6 +%define xtmpl3 xmm7 +%define xd1 xmm8 +%define xd2 xtmpl1 +%define xd3 xtmph1 + +align 16 +global GF_3VECT_MAD_SSE:function +func(GF_3VECT_MAD_SSE) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 + lea tmp, [mul_array + vec_i] + + movdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + movdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + movdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + movdqu xgft2_hi, [tmp+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + movdqu xgft3_lo, [tmp+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + movdqu xgft3_hi, [tmp+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + mov dest2, [dest1+PS] ; reuse mul_array + mov dest3, [dest1+2*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop16: + XLDR x0, [src+pos] ;Get next source vector + movdqa xtmph1, xgft1_hi ;Reload const array registers + movdqa xtmpl1, xgft1_lo + movdqa xtmph2, xgft2_hi ;Reload const array registers + movdqa xtmpl2, xgft2_lo + movdqa xtmph3, xgft3_hi ;Reload const array registers + movdqa xtmpl3, xgft3_lo + + XLDR xd1, [dest1+pos] ;Get next dest vector + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + ; dest1 + pshufb xtmph1, x0 ;Lookup mul table of high nibble + pshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + pxor xtmph1, xtmpl1 ;GF add high and low partials + pxor xd1, xtmph1 + + XLDR xd2, [dest2+pos] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest3+pos] ;reuse xtmph1. Get next dest vector + + ; dest2 + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl2 ;GF add high and low partials + pxor xd2, xtmph2 + + ; dest3 + pshufb xtmph3, x0 ;Lookup mul table of high nibble + pshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + pxor xtmph3, xtmpl3 ;GF add high and low partials + pxor xd3, xtmph3 + + XSTR [dest1+pos], xd1 ;Store result + XSTR [dest2+pos], xd2 ;Store result + XSTR [dest3+pos], xd3 ;Store result + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + +.lessthan16: + ;; Tail len + ;; Do one more overlap pass + mov tmp, len ;Overlapped offset length-16 + + XLDR x0, [src+tmp] ;Get next source vector + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest3+tmp] ;reuse xtmph1. Get next dest vector + + sub len, pos + + movdqa xtmph3, [constip16] ;Load const of i + 16 + pinsrb xtmpl3, len.w, 15 + pshufb xtmpl3, xmask0f ;Broadcast len to all bytes + pcmpgtb xtmpl3, xtmph3 + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + ; dest1 + pshufb xgft1_hi, x0 ;Lookup mul table of high nibble + pshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft1_hi, xgft1_lo ;GF add high and low partials + pand xgft1_hi, xtmpl3 + pxor xd1, xgft1_hi + + ; dest2 + pshufb xgft2_hi, x0 ;Lookup mul table of high nibble + pshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft2_hi, xgft2_lo ;GF add high and low partials + pand xgft2_hi, xtmpl3 + pxor xd2, xgft2_hi + + ; dest3 + pshufb xgft3_hi, x0 ;Lookup mul table of high nibble + pshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft3_hi, xgft3_lo ;GF add high and low partials + pand xgft3_hi, xtmpl3 + pxor xd3, xgft3_hi + + XSTR [dest1+tmp], xd1 ;Store result + XSTR [dest2+tmp], xd2 ;Store result + XSTR [dest3+tmp], xd3 ;Store result + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 + +mask0f: + ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +constip16: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_3VECT_MAD_SSE, 00, 00, 0206 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_avx.asm new file mode 100644 index 000000000..49c882948 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_avx.asm @@ -0,0 +1,489 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_4vect_dot_prod_avx(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_4VECT_DOT_PROD_AVX _gf_4vect_dot_prod_avx +%else + %define GF_4VECT_DOT_PROD_AVX gf_4vect_dot_prod_avx +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 9*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_xmm128 xmm9, 3*16 + save_xmm128 xmm10, 4*16 + save_xmm128 xmm11, 5*16 + save_xmm128 xmm12, 6*16 + save_xmm128 xmm13, 7*16 + save_xmm128 xmm14, 8*16 + save_reg r12, 9*16 + 0*8 + save_reg r13, 9*16 + 1*8 + save_reg r14, 9*16 + 2*8 + save_reg r15, 9*16 + 3*8 + save_reg rdi, 9*16 + 4*8 + save_reg rsi, 9*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + vmovdqa xmm9, [rsp + 3*16] + vmovdqa xmm10, [rsp + 4*16] + vmovdqa xmm11, [rsp + 5*16] + vmovdqa xmm12, [rsp + 6*16] + vmovdqa xmm13, [rsp + 7*16] + vmovdqa xmm14, [rsp + 8*16] + mov r12, [rsp + 9*16 + 0*8] + mov r13, [rsp + 9*16 + 1*8] + mov r14, [rsp + 9*16 + 2*8] + mov r15, [rsp + 9*16 + 3*8] + mov rdi, [rsp + 9*16 + 4*8] + mov rsi, [rsp + 9*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; var1 +;;; var2 +;;; var3 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define arg5 trans2 + %define tmp edx + %define tmp2 edi + %define tmp3 trans2 + %define tmp3_m var(0) + %define tmp4 trans2 + %define tmp4_m var(1) + %define tmp5 trans2 + %define tmp5_m var(2) + %define tmp6 trans2 + %define tmp6_m var(3) + %define return eax + %macro SLDR 2 ;stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*4 ;4 local variables + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*4 ;4 local variables + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest2 tmp3 +%define dest3 tmp4 +%define dest4 tmp5 +%define vskip3 tmp6 +%define pos return + + %ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp3_m + %define dest3_m tmp4_m + %define dest4_m tmp5_m + %define vskip3_m tmp6_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +%ifidn PS,8 ; 64-bit code + default rel + [bits 64] +%endif + + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f xmm14 + %define xgft1_lo xmm13 + %define xgft1_hi xmm12 + %define xgft2_lo xmm11 + %define xgft2_hi xmm10 + %define xgft3_lo xmm9 + %define xgft3_hi xmm8 + %define xgft4_lo xmm7 + %define xgft4_hi xmm6 + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 + %define xp3 xmm4 + %define xp4 xmm5 +%else + %define xmm_trans xmm7 ;reuse xmask0f and xgft1_lo + %define xmask0f xmm_trans + %define xgft1_lo xmm_trans + %define xgft1_hi xmm6 + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + %define xgft3_lo xgft1_lo + %define xgft3_hi xgft1_hi + %define xgft4_lo xgft1_lo + %define xgft4_hi xgft1_hi + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 + %define xp3 xmm4 + %define xp4 xmm5 +%endif +align 16 +global GF_4VECT_DOT_PROD_AVX:function +func(GF_4VECT_DOT_PROD_AVX) + FUNC_SAVE + SLDR len, len_m + sub len, 16 + SSTR len_m, len + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov vskip3, vec + imul vskip3, 96 + SSTR vskip3_m, vskip3 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest3, [dest1+2*PS] + SSTR dest3_m, dest3 + mov dest4, [dest1+3*PS] + SSTR dest4_m, dest4 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop16: + vpxor xp1, xp1 + vpxor xp2, xp2 + vpxor xp3, xp3 + vpxor xp4, xp4 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + SLDR src, src_m + mov ptr, [src+vec_i] + + %ifidn PS,8 ;64-bit code + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + vmovdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + vmovdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+vec*(64/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + vmovdqu xgft3_hi, [tmp+vec*(64/PS)+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + vmovdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + vmovdqu xgft4_hi, [tmp+vskip3+16] ; " Dx{00}, Dx{10}, ..., Dx{f0} + + XLDR x0, [ptr+pos] ;Get next source vector + add tmp, 32 + add vec_i, PS + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + %else ;32-bit code + XLDR x0, [ptr+pos] ;Get next source vector + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + vmovdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + %endif + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ;32-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + vmovdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + %endif + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + %ifidn PS,4 ;32-bit code + sal vec, 1 + vmovdqu xgft3_lo, [tmp+vec*(32/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + vmovdqu xgft3_hi, [tmp+vec*(32/PS)+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + sar vec, 1 + %endif + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp3, xgft3_hi ;xp3 += partial + + %ifidn PS,4 ;32-bit code + SLDR vskip3, vskip3_m + vmovdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + vmovdqu xgft4_hi, [tmp+vskip3+16] ; " Dx{00}, Dx{10}, ..., Dx{f0} + add tmp, 32 + add vec_i, PS + %endif + vpshufb xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft4_hi, xgft4_lo ;GF add high and low partials + vpxor xp4, xgft4_hi ;xp4 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + SLDR dest3, dest3_m + XSTR [dest3+pos], xp3 + SLDR dest4, dest4_m + XSTR [dest4+pos], xp4 + + SLDR len, len_m + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_4VECT_DOT_PROD_AVX, 02, 04, 0193 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_avx2.asm new file mode 100644 index 000000000..7c835e0b1 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_avx2.asm @@ -0,0 +1,510 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_4vect_dot_prod_avx2(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_4VECT_DOT_PROD_AVX2 _gf_4vect_dot_prod_avx2 +%else + %define GF_4VECT_DOT_PROD_AVX2 gf_4vect_dot_prod_avx2 +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 9*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + vmovdqa [rsp + 0*16], xmm6 + vmovdqa [rsp + 1*16], xmm7 + vmovdqa [rsp + 2*16], xmm8 + vmovdqa [rsp + 3*16], xmm9 + vmovdqa [rsp + 4*16], xmm10 + vmovdqa [rsp + 5*16], xmm11 + vmovdqa [rsp + 6*16], xmm12 + vmovdqa [rsp + 7*16], xmm13 + vmovdqa [rsp + 8*16], xmm14 + save_reg r12, 9*16 + 0*8 + save_reg r13, 9*16 + 1*8 + save_reg r14, 9*16 + 2*8 + save_reg r15, 9*16 + 3*8 + save_reg rdi, 9*16 + 4*8 + save_reg rsi, 9*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + vmovdqa xmm9, [rsp + 3*16] + vmovdqa xmm10, [rsp + 4*16] + vmovdqa xmm11, [rsp + 5*16] + vmovdqa xmm12, [rsp + 6*16] + vmovdqa xmm13, [rsp + 7*16] + vmovdqa xmm14, [rsp + 8*16] + mov r12, [rsp + 9*16 + 0*8] + mov r13, [rsp + 9*16 + 1*8] + mov r14, [rsp + 9*16 + 2*8] + mov r15, [rsp + 9*16 + 3*8] + mov rdi, [rsp + 9*16 + 4*8] + mov rsi, [rsp + 9*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; var1 +;;; var2 +;;; var3 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define arg5 trans2 + %define tmp edx + %define tmp.w edx + %define tmp.b dl + %define tmp2 edi + %define tmp3 trans2 + %define tmp3_m var(0) + %define tmp4 trans2 + %define tmp4_m var(1) + %define tmp5 trans2 + %define tmp5_m var(2) + %define tmp6 trans2 + %define tmp6_m var(3) + %define return eax + %macro SLDR 2 ;stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*4 ;4 local variables + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*4 ;4 local variables + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest2 tmp3 +%define dest3 tmp4 +%define dest4 tmp5 +%define vskip3 tmp6 +%define pos return + + %ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp3_m + %define dest3_m tmp4_m + %define dest4_m tmp5_m + %define vskip3_m tmp6_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +%ifidn PS,8 ;64-bit code + default rel + [bits 64] +%endif + + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f ymm14 + %define xmask0fx xmm14 + %define xgft1_lo ymm13 + %define xgft1_hi ymm12 + %define xgft2_lo ymm11 + %define xgft2_hi ymm10 + %define xgft3_lo ymm9 + %define xgft3_hi ymm8 + %define xgft4_lo ymm7 + %define xgft4_hi ymm6 + + %define x0 ymm0 + %define xtmpa ymm1 + %define xp1 ymm2 + %define xp2 ymm3 + %define xp3 ymm4 + %define xp4 ymm5 +%else + %define ymm_trans ymm7 ;reuse xmask0f and xgft1_hi + %define xmask0f ymm_trans + %define xmask0fx xmm7 + %define xgft1_lo ymm6 + %define xgft1_hi ymm_trans + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + %define xgft3_lo xgft1_lo + %define xgft3_hi xgft1_hi + %define xgft4_lo xgft1_lo + %define xgft4_hi xgft1_hi + + %define x0 ymm0 + %define xtmpa ymm1 + %define xp1 ymm2 + %define xp2 ymm3 + %define xp3 ymm4 + %define xp4 ymm5 +%endif +align 16 +global GF_4VECT_DOT_PROD_AVX2:function +func(GF_4VECT_DOT_PROD_AVX2) + FUNC_SAVE + SLDR len, len_m + sub len, 32 + SSTR len_m, len + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + mov vskip3, vec + imul vskip3, 96 + SSTR vskip3_m, vskip3 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest3, [dest1+2*PS] + SSTR dest3_m, dest3 + mov dest4, [dest1+3*PS] + SSTR dest4_m, dest4 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop32: + vpxor xp1, xp1 + vpxor xp2, xp2 + vpxor xp3, xp3 + vpxor xp4, xp4 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + SLDR src, src_m + mov ptr, [src+vec_i] + XLDR x0, [ptr+pos] ;Get next source vector + + add vec_i, PS + %ifidn PS,8 ;64-bit code + vpand xgft4_lo, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vperm2i128 xtmpa, xgft4_lo, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xgft4_lo, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+vec*(64/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + ; " Cx{00}, Cx{10}, ..., Cx{f0} + vmovdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + ; " Dx{00}, Dx{10}, ..., Dx{f0} + + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft3_hi, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft4_hi, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + add tmp, 32 + %else ;32-bit code + mov cl, 0x0f ;use ecx as a temp variable + vpinsrb xmask0fx, xmask0fx, ecx, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + vpand xgft4_lo, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vperm2i128 xtmpa, xgft4_lo, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xgft4_lo, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + %endif + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ; 32-bit code + vmovdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + %endif + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + %ifidn PS,4 ; 32-bit code + sal vec, 1 + vmovdqu xgft3_lo, [tmp+vec*(32/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + ; " Cx{00}, Cx{10}, ..., Cx{f0} + vperm2i128 xgft3_hi, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + sar vec, 1 + %endif + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp3, xgft3_hi ;xp3 += partial + + %ifidn PS,4 ; 32-bit code + SLDR vskip3, vskip3_m + vmovdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + ; " DX{00}, Dx{10}, ..., Dx{f0} + vperm2i128 xgft4_hi, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + add tmp, 32 + %endif + vpshufb xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft4_hi, xgft4_lo ;GF add high and low partials + vpxor xp4, xgft4_hi ;xp4 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + SLDR dest3, dest3_m + XSTR [dest3+pos], xp3 + SLDR dest4, dest4_m + XSTR [dest4+pos], xp4 + + SLDR len, len_m + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-32 + jmp .loop32 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_4VECT_DOT_PROD_AVX2, 04, 04, 0198 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_sse.asm new file mode 100644 index 000000000..59432e05d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_dot_prod_sse.asm @@ -0,0 +1,491 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_4vect_dot_prod_sse(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_4VECT_DOT_PROD_SSE _gf_4vect_dot_prod_sse +%else + %define GF_4VECT_DOT_PROD_SSE gf_4vect_dot_prod_sse +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define LOG_PS 3 + %define stack_size 9*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_xmm128 xmm9, 3*16 + save_xmm128 xmm10, 4*16 + save_xmm128 xmm11, 5*16 + save_xmm128 xmm12, 6*16 + save_xmm128 xmm13, 7*16 + save_xmm128 xmm14, 8*16 + save_reg r12, 9*16 + 0*8 + save_reg r13, 9*16 + 1*8 + save_reg r14, 9*16 + 2*8 + save_reg r15, 9*16 + 3*8 + save_reg rdi, 9*16 + 4*8 + save_reg rsi, 9*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + movdqa xmm6, [rsp + 0*16] + movdqa xmm7, [rsp + 1*16] + movdqa xmm8, [rsp + 2*16] + movdqa xmm9, [rsp + 3*16] + movdqa xmm10, [rsp + 4*16] + movdqa xmm11, [rsp + 5*16] + movdqa xmm12, [rsp + 6*16] + movdqa xmm13, [rsp + 7*16] + movdqa xmm14, [rsp + 8*16] + mov r12, [rsp + 9*16 + 0*8] + mov r13, [rsp + 9*16 + 1*8] + mov r14, [rsp + 9*16 + 2*8] + mov r15, [rsp + 9*16 + 3*8] + mov rdi, [rsp + 9*16 + 4*8] + mov rsi, [rsp + 9*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; var0 +;;; var1 +;;; var2 +;;; var3 +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + %define var(x) [ebp - PS - PS*x] + + %define trans ecx + %define trans2 esi + %define arg0 trans ;trans and trans2 are for the variables in stack + %define arg0_m arg(0) + %define arg1 ebx + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 trans + %define arg3_m arg(3) + %define arg4 trans + %define arg4_m arg(4) + %define arg5 trans2 + %define tmp edx + %define tmp2 edi + %define tmp3 trans2 + %define tmp3_m var(0) + %define tmp4 trans2 + %define tmp4_m var(1) + %define tmp5 trans2 + %define tmp5_m var(2) + %define tmp6 trans2 + %define tmp6_m var(3) + %define return eax + %macro SLDR 2 ;stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + sub esp, PS*4 ;4 local variables + push esi + push edi + push ebx + mov arg1, arg(1) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + add esp, PS*4 ;4 local variables + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest1 arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest2 tmp3 +%define dest3 tmp4 +%define dest4 tmp5 +%define vskip3 tmp6 +%define pos return + + %ifidn PS,4 ;32-bit code + %define len_m arg0_m + %define src_m arg3_m + %define dest1_m arg4_m + %define dest2_m tmp3_m + %define dest3_m tmp4_m + %define dest4_m tmp5_m + %define vskip3_m tmp6_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +%ifidn PS,8 ; 64-bit code + default rel + [bits 64] +%endif + + +section .text + +%ifidn PS,8 ;64-bit code + %define xmask0f xmm14 + %define xgft1_lo xmm2 + %define xgft1_hi xmm3 + %define xgft2_lo xmm11 + %define xgft2_hi xmm4 + %define xgft3_lo xmm9 + %define xgft3_hi xmm5 + %define xgft4_lo xmm7 + %define xgft4_hi xmm6 + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm8 + %define xp2 xmm10 + %define xp3 xmm12 + %define xp4 xmm13 +%else + %define xmm_trans xmm7 ;reuse xmask0f and xgft1_lo + %define xmask0f xmm_trans + %define xgft1_lo xmm_trans + %define xgft1_hi xmm6 + %define xgft2_lo xgft1_lo + %define xgft2_hi xgft1_hi + %define xgft3_lo xgft1_lo + %define xgft3_hi xgft1_hi + %define xgft4_lo xgft1_lo + %define xgft4_hi xgft1_hi + + %define x0 xmm0 + %define xtmpa xmm1 + %define xp1 xmm2 + %define xp2 xmm3 + %define xp3 xmm4 + %define xp4 xmm5 +%endif +align 16 +global GF_4VECT_DOT_PROD_SSE:function +func(GF_4VECT_DOT_PROD_SSE) + FUNC_SAVE + SLDR len, len_m + sub len, 16 + SSTR len_m, len + jl .return_fail + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov vskip3, vec + imul vskip3, 96 + SSTR vskip3_m, vskip3 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + SLDR dest1, dest1_m + mov dest2, [dest1+PS] + SSTR dest2_m, dest2 + mov dest3, [dest1+2*PS] + SSTR dest3_m, dest3 + mov dest4, [dest1+3*PS] + SSTR dest4_m, dest4 + mov dest1, [dest1] + SSTR dest1_m, dest1 + +.loop16: + pxor xp1, xp1 + pxor xp2, xp2 + pxor xp3, xp3 + pxor xp4, xp4 + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + SLDR src, src_m + mov ptr, [src+vec_i] + + %ifidn PS,8 ;64-bit code + movdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + movdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + movdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + movdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + movdqu xgft3_lo, [tmp+vec*(64/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + movdqu xgft3_hi, [tmp+vec*(64/PS)+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + movdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + movdqu xgft4_hi, [tmp+vskip3+16] ; " Dx{00}, Dx{10}, ..., Dx{f0} + + XLDR x0, [ptr+pos] ;Get next source vector + add tmp, 32 + add vec_i, PS + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + %else ;32-bit code + XLDR x0, [ptr+pos] ;Get next source vector + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + movdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + movdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + %endif + + pshufb xgft1_hi, x0 ;Lookup mul table of high nibble + pshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft1_hi, xgft1_lo ;GF add high and low partials + pxor xp1, xgft1_hi ;xp1 += partial + + %ifidn PS,4 ;32-bit code + movdqu xgft2_lo, [tmp+vec*(32/PS)] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + movdqu xgft2_hi, [tmp+vec*(32/PS)+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + %endif + pshufb xgft2_hi, x0 ;Lookup mul table of high nibble + pshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft2_hi, xgft2_lo ;GF add high and low partials + pxor xp2, xgft2_hi ;xp2 += partial + + %ifidn PS,4 ;32-bit code + sal vec, 1 + movdqu xgft3_lo, [tmp+vec*(32/PS)] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + movdqu xgft3_hi, [tmp+vec*(32/PS)+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + sar vec, 1 + %endif + pshufb xgft3_hi, x0 ;Lookup mul table of high nibble + pshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft3_hi, xgft3_lo ;GF add high and low partials + pxor xp3, xgft3_hi ;xp3 += partial + + %ifidn PS,4 ;32-bit code + SLDR vskip3, vskip3_m + movdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + movdqu xgft4_hi, [tmp+vskip3+16] ; " Dx{00}, Dx{10}, ..., Dx{f0} + add tmp, 32 + add vec_i, PS + %endif + pshufb xgft4_hi, x0 ;Lookup mul table of high nibble + pshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft4_hi, xgft4_lo ;GF add high and low partials + pxor xp4, xgft4_hi ;xp4 += partial + + cmp vec_i, vec + jl .next_vect + + SLDR dest1, dest1_m + SLDR dest2, dest2_m + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + SLDR dest3, dest3_m + XSTR [dest3+pos], xp3 + SLDR dest4, dest4_m + XSTR [dest4+pos], xp4 + + SLDR len, len_m + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_4VECT_DOT_PROD_SSE, 00, 05, 0064 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_avx.asm new file mode 100644 index 000000000..af35d6704 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_avx.asm @@ -0,0 +1,370 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_4vect_mad_avx(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_4VECT_MAD_AVX _gf_4vect_mad_avx +%else + %define GF_4VECT_MAD_AVX gf_4vect_mad_avx +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 + %define return rax + %define return.w eax + %define stack_size 16*10 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r15, 10*16 + 2*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r15, [rsp + 10*16 + 2*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%endif + +;;; gf_4vect_mad_avx(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 mul_array +%define dest3 tmp2 +%define dest4 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft3_hi xmm14 +%define xgft4_hi xmm13 +%define xgft4_lo xmm12 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xtmph3 xmm6 +%define xtmpl3 xmm7 +%define xtmph4 xmm8 +%define xtmpl4 xmm9 +%define xd1 xmm10 +%define xd2 xmm11 +%define xd3 xtmph1 +%define xd4 xtmpl1 + +align 16 +global GF_4VECT_MAD_AVX:function +func(GF_4VECT_MAD_AVX) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + + mov tmp, vec + + sal vec_i, 5 ;Multiply by 32 + lea tmp3, [mul_array + vec_i] + + sal tmp, 6 ;Multiply by 64 + vmovdqu xgft3_hi, [tmp3+tmp+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + sal vec, 5 ;Multiply by 32 + add tmp, vec + vmovdqu xgft4_lo, [tmp3+tmp] ;Load array Dx{00}, Dx{01}, Dx{02}, ... + vmovdqu xgft4_hi, [tmp3+tmp+16] ; " Dx{00}, Dx{10}, Dx{20}, ... , Dx{f0} + + mov dest2, [dest1+PS] ; reuse mul_array + mov dest3, [dest1+2*PS] + mov dest4, [dest1+3*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop16: + XLDR x0, [src+pos] ;Get next source vector + vmovdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + vmovdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + vmovdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ; dest1 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xtmpl1, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpxor xd1, xd1, xtmph1 + + XLDR xd3, [dest3+pos] ;Reuse xtmph1, Get next dest vector + XLDR xd4, [dest4+pos] ;Reuse xtmpl1, Get next dest vector + + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xtmpl2, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl2 ;GF add high and low partials + vpxor xd2, xd2, xtmph2 + + ; dest3 + vpshufb xtmph3, xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xtmpl3, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmph3, xtmpl3 ;GF add high and low partials + vpxor xd3, xd3, xtmph3 + + ; dest4 + vpshufb xtmph4, xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl4, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph4, xtmph4, xtmpl4 ;GF add high and low partials + vpxor xd4, xd4, xtmph4 + + XSTR [dest1+pos], xd1 ;Store result + XSTR [dest2+pos], xd2 ;Store result + XSTR [dest3+pos], xd3 ;Store result + XSTR [dest4+pos], xd4 ;Store result + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + +.lessthan16: + ;; Tail len + ;; Do one more overlap pass + + mov tmp, len ;Overlapped offset length-16 + + XLDR x0, [src+tmp] ;Get next source vector + + vmovdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + vmovdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + vmovdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;Get next dest vector + XLDR xtmph4, [dest3+tmp] ;Get next dest vector + + sub len, pos + + vmovdqa xtmpl4, [constip16] ;Load const of i + 16 + vpinsrb xtmph3, xtmph3, len.w, 15 + vpshufb xtmph3, xtmph3, xmask0f ;Broadcast len to all bytes + vpcmpgtb xtmph3, xtmph3, xtmpl4 + + XLDR xtmpl4, [dest4+tmp] ;Get next dest vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ; dest1 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xtmpl1, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpand xtmph1, xtmph1, xtmph3 + vpxor xd1, xd1, xtmph1 + + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xtmpl2, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl2 ;GF add high and low partials + vpand xtmph2, xtmph2, xtmph3 + vpxor xd2, xd2, xtmph2 + + ; dest3 + vpshufb xgft3_hi, xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xtmpl3, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_hi, xtmpl3 ;GF add high and low partials + vpand xgft3_hi, xgft3_hi, xtmph3 + vpxor xtmph4, xtmph4, xgft3_hi + + ; dest4 + vpshufb xgft4_hi, xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft4_hi, xgft4_hi, xgft4_lo ;GF add high and low partials + vpand xgft4_hi, xgft4_hi, xtmph3 + vpxor xtmpl4, xtmpl4, xgft4_hi + + XSTR [dest1+tmp], xd1 ;Store result + XSTR [dest2+tmp], xd2 ;Store result + XSTR [dest3+tmp], xtmph4 ;Store result + XSTR [dest4+tmp], xtmpl4 ;Store result + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +constip16: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_4VECT_MAD_AVX, 02, 00, 020a diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_avx2.asm new file mode 100644 index 000000000..8ea779af2 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_avx2.asm @@ -0,0 +1,371 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_4vect_mad_avx2(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_4VECT_MAD_AVX2 _gf_4vect_mad_avx2 +%else + %define GF_4VECT_MAD_AVX2 gf_4vect_mad_avx2 +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + %define stack_size 16*10 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r15, 10*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r15, [rsp + 10*16 + 1*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + + +;;; gf_4vect_mad_avx2(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 mul_array +%define dest3 vec +%define dest4 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f ymm15 +%define xmask0fx xmm15 +%define xgft1_lo ymm14 +%define xgft2_lo ymm13 +%define xgft3_lo ymm12 +%define xgft4_lo ymm11 + +%define x0 ymm0 +%define xtmpa ymm1 +%define xtmpl ymm2 +%define xtmplx xmm2 +%define xtmph1 ymm3 +%define xtmph1x xmm3 +%define xtmph2 ymm4 +%define xtmph3 ymm5 +%define xtmph4 ymm6 +%define xd1 ymm7 +%define xd2 ymm8 +%define xd3 ymm9 +%define xd4 ymm10 + +align 16 +global GF_4VECT_MAD_AVX2:function +func(GF_4VECT_MAD_AVX2) + FUNC_SAVE + sub len, 32 + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 ;Multiply by 32 + lea tmp, [mul_array + vec_i] + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xgft3_lo, [tmp+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + add tmp, vec + vmovdqu xgft4_lo, [tmp+2*vec] ;Load array Dx{00}, Dx{01}, Dx{02}, ... + ; " Dx{00}, Dx{10}, Dx{20}, ... , Dx{f0} + + mov dest2, [dest1+PS] ; reuse mul_array + mov dest3, [dest1+2*PS] ; reuse vec + mov dest4, [dest1+3*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop32: + XLDR x0, [src+pos] ;Get next source vector + + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector + XLDR xd3, [dest3+pos] ;Get next dest vector + XLDR xd4, [dest4+pos] ;reuse xtmpl1. Get next dest vector + + vpand xtmpl, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vperm2i128 xtmpa, xtmpl, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xtmpl, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + vperm2i128 xtmph1, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vperm2i128 xtmph2, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + vperm2i128 xtmph3, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + vperm2i128 xtmph4, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + + ; dest1 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl ;GF add high and low partials + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl ;GF add high and low partials + vpxor xd2, xd2, xtmph2 ;xd2 += partial + + ; dest3 + vpshufb xtmph3, xtmph3, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmph3, xtmpl ;GF add high and low partials + vpxor xd3, xd3, xtmph3 ;xd3 += partial + + ; dest4 + vpshufb xtmph4, xtmph4, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph4, xtmph4, xtmpl ;GF add high and low partials + vpxor xd4, xd4, xtmph4 ;xd4 += partial + + XSTR [dest1+pos], xd1 + XSTR [dest2+pos], xd2 + XSTR [dest3+pos], xd3 + XSTR [dest4+pos], xd4 + + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + +.lessthan32: + ;; Tail len + ;; Do one more overlap pass + mov tmp.b, 0x1f + vpinsrb xtmph1x, xtmph1x, tmp.w, 0 + vpbroadcastb xtmph1, xtmph1x ;Construct mask 0x1f1f1f... + + mov tmp, len ;Overlapped offset length-32 + + XLDR x0, [src+tmp] ;Get next source vector + + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;Get next dest vector + XLDR xd3, [dest3+tmp] ;Get next dest vector + XLDR xd4, [dest4+tmp] ;Get next dest vector + + sub len, pos + + vmovdqa xtmph2, [constip32] ;Load const of i + 32 + vpinsrb xtmplx, xtmplx, len.w, 15 + vinserti128 xtmpl, xtmpl, xtmplx, 1 ;swapped to xtmplx | xtmplx + vpshufb xtmpl, xtmpl, xtmph1 ;Broadcast len to all bytes. xtmph1=0x1f1f1f... + vpcmpgtb xtmpl, xtmpl, xtmph2 + + vpand xtmph1, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vperm2i128 xtmpa, xtmph1, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xtmph1, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + vperm2i128 xtmph1, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vperm2i128 xtmph2, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + vperm2i128 xtmph3, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + vperm2i128 xtmph4, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + + ; dest1 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xgft1_lo ;GF add high and low partials + vpand xtmph1, xtmph1, xtmpl + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xgft2_lo ;GF add high and low partials + vpand xtmph2, xtmph2, xtmpl + vpxor xd2, xd2, xtmph2 ;xd2 += partial + + ; dest3 + vpshufb xtmph3, xtmph3, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmph3, xgft3_lo ;GF add high and low partials + vpand xtmph3, xtmph3, xtmpl + vpxor xd3, xd3, xtmph3 ;xd3 += partial + + ; dest4 + vpshufb xtmph4, xtmph4, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph4, xtmph4, xgft4_lo ;GF add high and low partials + vpand xtmph4, xtmph4, xtmpl + vpxor xd4, xd4, xtmph4 ;xd4 += partial + + XSTR [dest1+tmp], xd1 + XSTR [dest2+tmp], xd2 + XSTR [dest3+tmp], xd3 + XSTR [dest4+tmp], xd4 + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data +align 32 +constip32: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + ddq 0xe0e1e2e3e4e5e6e7e8e9eaebecedeeef + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_4VECT_MAD_AVX2, 04, 00, 020b diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_sse.asm new file mode 100644 index 000000000..9f0bc4165 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_4vect_mad_sse.asm @@ -0,0 +1,375 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_4vect_mad_sse(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_4VECT_MAD_SSE _gf_4vect_mad_sse +%else + %define GF_4VECT_MAD_SSE gf_4vect_mad_sse +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 + %define return rax + %define return.w eax + %define stack_size 16*10 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r15, 10*16 + 2*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r15, [rsp + 10*16 + 2*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%endif + +;;; gf_4vect_mad_sse(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 mul_array +%define dest3 tmp2 +%define dest4 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft3_hi xmm14 +%define xgft4_hi xmm13 +%define xgft4_lo xmm12 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xtmph3 xmm6 +%define xtmpl3 xmm7 +%define xtmph4 xmm8 +%define xtmpl4 xmm9 +%define xd1 xmm10 +%define xd2 xmm11 +%define xd3 xtmph1 +%define xd4 xtmpl1 + +align 16 +global GF_4VECT_MAD_SSE:function +func(GF_4VECT_MAD_SSE) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov tmp, vec + + sal vec_i, 5 ;Multiply by 32 + lea tmp3, [mul_array + vec_i] + + sal tmp, 6 ;Multiply by 64 + + movdqu xgft3_hi, [tmp3+tmp+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + sal vec, 5 ;Multiply by 32 + add tmp, vec + movdqu xgft4_lo, [tmp3+tmp] ;Load array Dx{00}, Dx{01}, Dx{02}, ... + movdqu xgft4_hi, [tmp3+tmp+16] ; " Dx{00}, Dx{10}, Dx{20}, ... , Dx{f0} + + mov dest2, [dest1+PS] ; reuse mul_array + mov dest3, [dest1+2*PS] + mov dest4, [dest1+3*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop16: + XLDR x0, [src+pos] ;Get next source vector + movdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + movdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + movdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + movdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + movdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + + movdqa xtmph3, xgft3_hi + movdqa xtmpl4, xgft4_lo + movdqa xtmph4, xgft4_hi + + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + ; dest1 + pshufb xtmph1, x0 ;Lookup mul table of high nibble + pshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + pxor xtmph1, xtmpl1 ;GF add high and low partials + pxor xd1, xtmph1 + + XLDR xd3, [dest3+pos] ;Reuse xtmph1, Get next dest vector + XLDR xd4, [dest4+pos] ;Reuse xtmpl1, Get next dest vector + + ; dest2 + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl2 ;GF add high and low partials + pxor xd2, xtmph2 + + ; dest3 + pshufb xtmph3, x0 ;Lookup mul table of high nibble + pshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + pxor xtmph3, xtmpl3 ;GF add high and low partials + pxor xd3, xtmph3 + + ; dest4 + pshufb xtmph4, x0 ;Lookup mul table of high nibble + pshufb xtmpl4, xtmpa ;Lookup mul table of low nibble + pxor xtmph4, xtmpl4 ;GF add high and low partials + pxor xd4, xtmph4 + + XSTR [dest1+pos], xd1 ;Store result + XSTR [dest2+pos], xd2 ;Store result + XSTR [dest3+pos], xd3 ;Store result + XSTR [dest4+pos], xd4 ;Store result + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + +.lessthan16: + ;; Tail len + ;; Do one more overlap pass + mov tmp, len ;Overlapped offset length-16 + + XLDR x0, [src+tmp] ;Get next source vector + + movdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + movdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + movdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + movdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + movdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;Get next dest vector + XLDR xtmph4, [dest3+tmp] ;Reuse xtmph1. Get next dest vector + + sub len, pos + + movdqa xtmpl4, [constip16] ;Load const of i + 16 + pinsrb xtmph3, len.w, 15 + pshufb xtmph3, xmask0f ;Broadcast len to all bytes + pcmpgtb xtmph3, xtmpl4 + + XLDR xtmpl4, [dest4+tmp] ;Get next dest vector + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + ; dest1 + pshufb xtmph1, x0 ;Lookup mul table of high nibble + pshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + pxor xtmph1, xtmpl1 ;GF add high and low partials + pand xtmph1, xtmph3 + pxor xd1, xtmph1 + + ; dest2 + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl2 ;GF add high and low partials + pand xtmph2, xtmph3 + pxor xd2, xtmph2 + + ; dest3 + pshufb xgft3_hi, x0 ;Lookup mul table of high nibble + pshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + pxor xgft3_hi, xtmpl3 ;GF add high and low partials + pand xgft3_hi, xtmph3 + pxor xtmph4, xgft3_hi + + ; dest4 + pshufb xgft4_hi, x0 ;Lookup mul table of high nibble + pshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft4_hi, xgft4_lo ;GF add high and low partials + pand xgft4_hi, xtmph3 + pxor xtmpl4, xgft4_hi + + XSTR [dest1+tmp], xd1 ;Store result + XSTR [dest2+tmp], xd2 ;Store result + XSTR [dest3+tmp], xtmph4 ;Store result + XSTR [dest4+tmp], xtmpl4 ;Store result + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 + +mask0f: + ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +constip16: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_4VECT_MAD_SSE, 00, 00, 0209 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_avx.asm new file mode 100644 index 000000000..4291b8ea5 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_avx.asm @@ -0,0 +1,348 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_5vect_dot_prod_avx(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_5VECT_DOT_PROD_AVX _gf_5vect_dot_prod_avx +%else + %define GF_5VECT_DOT_PROD_AVX gf_5vect_dot_prod_avx +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + %define stack_size 10*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_xmm128 xmm9, 3*16 + save_xmm128 xmm10, 4*16 + save_xmm128 xmm11, 5*16 + save_xmm128 xmm12, 6*16 + save_xmm128 xmm13, 7*16 + save_xmm128 xmm14, 8*16 + save_xmm128 xmm15, 9*16 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + save_reg rdi, 10*16 + 4*8 + save_reg rsi, 10*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + vmovdqa xmm9, [rsp + 3*16] + vmovdqa xmm10, [rsp + 4*16] + vmovdqa xmm11, [rsp + 5*16] + vmovdqa xmm12, [rsp + 6*16] + vmovdqa xmm13, [rsp + 7*16] + vmovdqa xmm14, [rsp + 8*16] + vmovdqa xmm15, [rsp + 9*16] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + mov rdi, [rsp + 10*16 + 4*8] + mov rsi, [rsp + 10*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest1 tmp3 +%define dest2 tmp4 +%define vskip1 tmp5 +%define vskip3 tmp6 +%define pos return + + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft1_lo xmm14 +%define xgft1_hi xmm13 +%define xgft2_lo xmm12 +%define xgft2_hi xmm11 +%define xgft3_lo xmm10 +%define xgft3_hi xmm9 +%define xgft4_lo xmm8 +%define xgft4_hi xmm7 + + +%define x0 xmm0 +%define xtmpa xmm1 +%define xp1 xmm2 +%define xp2 xmm3 +%define xp3 xmm4 +%define xp4 xmm5 +%define xp5 xmm6 + +align 16 +global GF_5VECT_DOT_PROD_AVX:function +func(GF_5VECT_DOT_PROD_AVX) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov vskip1, vec + imul vskip1, 32 + mov vskip3, vec + imul vskip3, 96 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + mov dest1, [dest] + mov dest2, [dest+PS] + + +.loop16: + mov tmp, mul_array + xor vec_i, vec_i + vpxor xp1, xp1 + vpxor xp2, xp2 + vpxor xp3, xp3 + vpxor xp4, xp4 + vpxor xp5, xp5 + + +.next_vect: + mov ptr, [src+vec_i] + add vec_i, PS + XLDR x0, [ptr+pos] ;Get next source vector + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + vmovdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vskip1*1] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + vmovdqu xgft2_hi, [tmp+vskip1*1+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+vskip1*2] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + vmovdqu xgft3_hi, [tmp+vskip1*2+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + vmovdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + vmovdqu xgft4_hi, [tmp+vskip3+16] ; " Dx{00}, Dx{10}, ..., Dx{f0} + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + vmovdqu xgft1_lo, [tmp+vskip1*4] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + vmovdqu xgft1_hi, [tmp+vskip1*4+16] ; " Ex{00}, Ex{10}, ..., Ex{f0} + add tmp, 32 + + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp3, xgft3_hi ;xp3 += partial + + vpshufb xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft4_hi, xgft4_lo ;GF add high and low partials + vpxor xp4, xgft4_hi ;xp4 += partial + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp5, xgft1_hi ;xp5 += partial + + cmp vec_i, vec + jl .next_vect + + mov tmp, [dest+2*PS] + mov ptr, [dest+3*PS] + mov vec_i, [dest+4*PS] + + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + XSTR [tmp+pos], xp3 + XSTR [ptr+pos], xp4 + XSTR [vec_i+pos], xp5 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_5VECT_DOT_PROD_AVX, 02, 03, 0194 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_avx2.asm new file mode 100644 index 000000000..5dcbd3740 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_avx2.asm @@ -0,0 +1,362 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_5vect_dot_prod_avx2(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_5VECT_DOT_PROD_AVX2 _gf_5vect_dot_prod_avx2 +%else + %define GF_5VECT_DOT_PROD_AVX2 gf_5vect_dot_prod_avx2 +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + %define stack_size 10*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + vmovdqa [rsp + 0*16], xmm6 + vmovdqa [rsp + 1*16], xmm7 + vmovdqa [rsp + 2*16], xmm8 + vmovdqa [rsp + 3*16], xmm9 + vmovdqa [rsp + 4*16], xmm10 + vmovdqa [rsp + 5*16], xmm11 + vmovdqa [rsp + 6*16], xmm12 + vmovdqa [rsp + 7*16], xmm13 + vmovdqa [rsp + 8*16], xmm14 + vmovdqa [rsp + 9*16], xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + save_reg rdi, 10*16 + 4*8 + save_reg rsi, 10*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + vmovdqa xmm9, [rsp + 3*16] + vmovdqa xmm10, [rsp + 4*16] + vmovdqa xmm11, [rsp + 5*16] + vmovdqa xmm12, [rsp + 6*16] + vmovdqa xmm13, [rsp + 7*16] + vmovdqa xmm14, [rsp + 8*16] + vmovdqa xmm15, [rsp + 9*16] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + mov rdi, [rsp + 10*16 + 4*8] + mov rsi, [rsp + 10*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest1 tmp3 +%define dest2 tmp4 +%define vskip1 tmp5 +%define vskip3 tmp6 +%define pos return + + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f ymm15 +%define xmask0fx xmm15 +%define xgft1_lo ymm14 +%define xgft1_hi ymm13 +%define xgft2_lo ymm12 +%define xgft2_hi ymm11 +%define xgft3_lo ymm10 +%define xgft3_hi ymm9 +%define xgft4_lo ymm8 +%define xgft4_hi ymm7 + + +%define x0 ymm0 +%define xtmpa ymm1 +%define xp1 ymm2 +%define xp2 ymm3 +%define xp3 ymm4 +%define xp4 ymm5 +%define xp5 ymm6 + +align 16 +global GF_5VECT_DOT_PROD_AVX2:function +func(GF_5VECT_DOT_PROD_AVX2) + FUNC_SAVE + sub len, 32 + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + mov vskip1, vec + imul vskip1, 32 + mov vskip3, vec + imul vskip3, 96 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + mov dest1, [dest] + mov dest2, [dest+PS] + + +.loop32: + mov tmp, mul_array + xor vec_i, vec_i + vpxor xp1, xp1 + vpxor xp2, xp2 + vpxor xp3, xp3 + vpxor xp4, xp4 + vpxor xp5, xp5 + + +.next_vect: + mov ptr, [src+vec_i] + XLDR x0, [ptr+pos] ;Get next source vector + add vec_i, PS + + vpand xgft4_lo, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vperm2i128 xtmpa, xgft4_lo, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xgft4_lo, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vskip1*1] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+vskip1*2] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + ; " Cx{00}, Cx{10}, ..., Cx{f0} + vmovdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + ; " Dx{00}, Dx{10}, ..., Dx{f0} + + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft3_hi, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft4_hi, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + vmovdqu xgft1_lo, [tmp+vskip1*4] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + ; " Ex{00}, Ex{10}, ..., Ex{f0} + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + add tmp, 32 + + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp3, xgft3_hi ;xp3 += partial + + vpshufb xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft4_hi, xgft4_lo ;GF add high and low partials + vpxor xp4, xgft4_hi ;xp4 += partial + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp5, xgft1_hi ;xp5 += partial + + cmp vec_i, vec + jl .next_vect + + mov tmp, [dest+2*PS] + mov ptr, [dest+3*PS] + mov vec_i, [dest+4*PS] + + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + XSTR [tmp+pos], xp3 + XSTR [ptr+pos], xp4 + XSTR [vec_i+pos], xp5 + + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop32 ;Do one more overlap pass + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_5VECT_DOT_PROD_AVX2, 04, 03, 0199 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_sse.asm new file mode 100644 index 000000000..ac3f65f28 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_dot_prod_sse.asm @@ -0,0 +1,349 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_5vect_dot_prod_sse(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_5VECT_DOT_PROD_SSE _gf_5vect_dot_prod_sse +%else + %define GF_5VECT_DOT_PROD_SSE gf_5vect_dot_prod_sse +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + %define stack_size 10*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_xmm128 xmm9, 3*16 + save_xmm128 xmm10, 4*16 + save_xmm128 xmm11, 5*16 + save_xmm128 xmm12, 6*16 + save_xmm128 xmm13, 7*16 + save_xmm128 xmm14, 8*16 + save_xmm128 xmm15, 9*16 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + save_reg rdi, 10*16 + 4*8 + save_reg rsi, 10*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + movdqa xmm6, [rsp + 0*16] + movdqa xmm7, [rsp + 1*16] + movdqa xmm8, [rsp + 2*16] + movdqa xmm9, [rsp + 3*16] + movdqa xmm10, [rsp + 4*16] + movdqa xmm11, [rsp + 5*16] + movdqa xmm12, [rsp + 6*16] + movdqa xmm13, [rsp + 7*16] + movdqa xmm14, [rsp + 8*16] + movdqa xmm15, [rsp + 9*16] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + mov rdi, [rsp + 10*16 + 4*8] + mov rsi, [rsp + 10*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest1 tmp3 +%define dest2 tmp4 +%define vskip1 tmp5 +%define vskip3 tmp6 +%define pos return + + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft1_lo xmm2 +%define xgft1_hi xmm3 +%define xgft2_lo xmm4 +%define xgft2_hi xmm5 +%define xgft3_lo xmm10 +%define xgft3_hi xmm6 +%define xgft4_lo xmm8 +%define xgft4_hi xmm7 + + +%define x0 xmm0 +%define xtmpa xmm1 +%define xp1 xmm9 +%define xp2 xmm11 +%define xp3 xmm12 +%define xp4 xmm13 +%define xp5 xmm14 + +align 16 +global GF_5VECT_DOT_PROD_SSE:function +func(GF_5VECT_DOT_PROD_SSE) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov vskip1, vec + imul vskip1, 32 + mov vskip3, vec + imul vskip3, 96 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + mov dest1, [dest] + mov dest2, [dest+PS] + + +.loop16: + mov tmp, mul_array + xor vec_i, vec_i + pxor xp1, xp1 + pxor xp2, xp2 + pxor xp3, xp3 + pxor xp4, xp4 + pxor xp5, xp5 + + +.next_vect: + mov ptr, [src+vec_i] + add vec_i, PS + XLDR x0, [ptr+pos] ;Get next source vector + + movdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + movdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + movdqu xgft2_lo, [tmp+vskip1*1] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + movdqu xgft2_hi, [tmp+vskip1*1+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + movdqu xgft3_lo, [tmp+vskip1*2] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + movdqu xgft3_hi, [tmp+vskip1*2+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + movdqu xgft4_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + movdqu xgft4_hi, [tmp+vskip3+16] ; " Dx{00}, Dx{10}, ..., Dx{f0} + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + pshufb xgft1_hi, x0 ;Lookup mul table of high nibble + pshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft1_hi, xgft1_lo ;GF add high and low partials + pxor xp1, xgft1_hi ;xp1 += partial + + pshufb xgft2_hi, x0 ;Lookup mul table of high nibble + pshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft2_hi, xgft2_lo ;GF add high and low partials + pxor xp2, xgft2_hi ;xp2 += partial + + movdqu xgft1_lo, [tmp+vskip1*4] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + movdqu xgft1_hi, [tmp+vskip1*4+16] ; " Ex{00}, Ex{10}, ..., Ex{f0} + add tmp, 32 + + pshufb xgft3_hi, x0 ;Lookup mul table of high nibble + pshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft3_hi, xgft3_lo ;GF add high and low partials + pxor xp3, xgft3_hi ;xp3 += partial + + pshufb xgft4_hi, x0 ;Lookup mul table of high nibble + pshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft4_hi, xgft4_lo ;GF add high and low partials + pxor xp4, xgft4_hi ;xp4 += partial + + pshufb xgft1_hi, x0 ;Lookup mul table of high nibble + pshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft1_hi, xgft1_lo ;GF add high and low partials + pxor xp5, xgft1_hi ;xp5 += partial + + cmp vec_i, vec + jl .next_vect + + mov tmp, [dest+2*PS] + mov ptr, [dest+3*PS] + mov vec_i, [dest+4*PS] + + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + XSTR [tmp+pos], xp3 + XSTR [ptr+pos], xp4 + XSTR [vec_i+pos], xp5 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_5VECT_DOT_PROD_SSE, 00, 04, 0065 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_avx.asm new file mode 100644 index 000000000..427662d8d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_avx.asm @@ -0,0 +1,401 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_5vect_mad_avx(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_5VECT_MAD_AVX _gf_5vect_mad_avx +%else + %define GF_5VECT_MAD_AVX gf_5vect_mad_avx +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 + %define tmp4 r14 + %define return rax + %define return.w eax + %define stack_size 16*10 + 5*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define tmp4 r13 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define tmp4 r13 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +;;; gf_5vect_mad_avx(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 tmp4 +%define dest3 mul_array +%define dest4 tmp2 +%define dest5 vec_i + + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft5_hi xmm14 +%define xgft4_lo xmm13 +%define xgft4_hi xmm12 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xtmph3 xmm6 +%define xtmpl3 xmm7 +%define xtmph5 xmm8 +%define xtmpl5 xmm9 +%define xd1 xmm10 +%define xd2 xmm11 +%define xd3 xtmpl1 +%define xd4 xtmph1 +%define xd5 xtmpl2 + + +align 16 +global GF_5VECT_MAD_AVX:function +func(GF_5VECT_MAD_AVX) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov tmp, vec + sal vec_i, 5 ;Multiply by 32 + lea tmp3, [mul_array + vec_i] + sal tmp, 6 ;Multiply by 64 + vmovdqu xgft5_hi, [tmp3+2*tmp+16] ; " Ex{00}, Ex{10}, ..., Ex{f0} + sal vec, 5 ;Multiply by 32 + add tmp, vec + vmovdqu xgft4_hi, [tmp3+tmp+16] ; " Dx{00}, Dx{10}, Dx{20}, ... , Dx{f0} + vmovdqu xgft4_lo, [tmp3+tmp] ;Load array Dx{00}, Dx{01}, Dx{02}, ... + + mov dest3, [dest1+2*PS] ; reuse mul_array + mov dest4, [dest1+3*PS] + mov dest5, [dest1+4*PS] ; reuse vec_i + mov dest2, [dest1+PS] + mov dest1, [dest1] + +.loop16: + XLDR x0, [src+pos] ;Get next source vector + + vmovdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + vmovdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + vmovdqu xtmph3, [tmp3+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + vmovdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + vmovdqu xtmpl5, [tmp3+4*vec] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ; dest1 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xtmpl1, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpxor xd1, xd1, xtmph1 + + XLDR xd3, [dest3+pos] ;Reuse xtmpl1, Get next dest vector + XLDR xd4, [dest4+pos] ;Reuse xtmph1, Get next dest vector + + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xtmpl2, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl2 ;GF add high and low partials + vpxor xd2, xd2, xtmph2 + + XLDR xd5, [dest5+pos] ;Reuse xtmpl2. Get next dest vector + + ; dest3 + vpshufb xtmph3, xtmph3, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xtmpl3, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmph3, xtmpl3 ;GF add high and low partials + vpxor xd3, xd3, xtmph3 + + ; dest4 + vpshufb xtmph2, xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl3 ;GF add high and low partials + vpxor xd4, xd4, xtmph2 + + ; dest5 + vpshufb xtmph5, xgft5_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl5, xtmpl5, xtmpa ;Lookup mul table of low nibble + vpxor xtmph5, xtmph5, xtmpl5 ;GF add high and low partials + vpxor xd5, xd5, xtmph5 + + XSTR [dest1+pos], xd1 ;Store result into dest1 + XSTR [dest2+pos], xd2 ;Store result into dest2 + XSTR [dest3+pos], xd3 ;Store result into dest3 + XSTR [dest4+pos], xd4 ;Store result into dest4 + XSTR [dest5+pos], xd5 ;Store result into dest5 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + +.lessthan16: + ;; Tail len + ;; Do one more overlap pass + mov tmp, len ;Overlapped offset length-16 + XLDR x0, [src+tmp] ;Get next source vector + + sub len, pos + + vmovdqa xtmph1, [constip16] ;Load const of i + 16 + vpinsrb xtmph5, len.w, 15 + vpshufb xtmph5, xmask0f ;Broadcast len to all bytes + vpcmpgtb xtmph5, xtmph5, xtmph1 + + vmovdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + vmovdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + vmovdqu xtmph3, [tmp3+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + vmovdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + vmovdqu xtmpl5, [tmp3+4*vec] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;Get next dest vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ; dest1 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xtmpl1, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpand xtmph1, xtmph1, xtmph5 + vpxor xd1, xd1, xtmph1 + + XLDR xd3, [dest3+tmp] ;Reuse xtmpl1, Get next dest vector + XLDR xd4, [dest4+tmp] ;Reuse xtmph1, Get next dest vector + + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xtmpl2, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl2 ;GF add high and low partials + vpand xtmph2, xtmph2, xtmph5 + vpxor xd2, xd2, xtmph2 + + XLDR xd5, [dest5+tmp] ;Reuse xtmpl2. Get next dest vector + + ; dest3 + vpshufb xtmph3, xtmph3, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xtmpl3, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmph3, xtmpl3 ;GF add high and low partials + vpand xtmph3, xtmph3, xtmph5 + vpxor xd3, xd3, xtmph3 + + ; dest4 + vpshufb xgft4_hi, xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft4_hi, xgft4_hi, xgft4_lo ;GF add high and low partials + vpand xgft4_hi, xgft4_hi, xtmph5 + vpxor xd4, xd4, xgft4_hi + + ; dest5 + vpshufb xgft5_hi, xgft5_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl5, xtmpl5, xtmpa ;Lookup mul table of low nibble + vpxor xgft5_hi, xgft5_hi, xtmpl5 ;GF add high and low partials + vpand xgft5_hi, xgft5_hi, xtmph5 + vpxor xd5, xd5, xgft5_hi + + XSTR [dest1+tmp], xd1 ;Store result into dest1 + XSTR [dest2+tmp], xd2 ;Store result into dest2 + XSTR [dest3+tmp], xd3 ;Store result into dest3 + XSTR [dest4+tmp], xd4 ;Store result into dest4 + XSTR [dest5+tmp], xd5 ;Store result into dest5 + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +constip16: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_5VECT_MAD_AVX, 02, 00, 020d diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_avx2.asm new file mode 100644 index 000000000..1b236e9a7 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_avx2.asm @@ -0,0 +1,393 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_5vect_mad_avx2(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_5VECT_MAD_AVX2 _gf_5vect_mad_avx2 +%else + %define GF_5VECT_MAD_AVX2 gf_5vect_mad_avx2 +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define return rax + %define return.w eax + %define stack_size 16*10 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r15, 10*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r15, [rsp + 10*16 + 1*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_5vect_mad_avx2(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 tmp2 +%define dest3 mul_array +%define dest4 vec +%define dest5 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f ymm15 +%define xmask0fx xmm15 +%define xgft1_lo ymm14 +%define xgft2_lo ymm13 +%define xgft3_lo ymm12 +%define xgft4_lo ymm11 +%define xgft5_lo ymm10 + +%define x0 ymm0 +%define xtmpa ymm1 +%define xtmpl ymm2 +%define xtmplx xmm2 +%define xtmph1 ymm3 +%define xtmph1x xmm3 +%define xtmph2 ymm4 +%define xd1 ymm5 +%define xd2 ymm6 +%define xd3 ymm7 +%define xd4 ymm8 +%define xd5 ymm9 + +align 16 +global GF_5VECT_MAD_AVX2:function +func(GF_5VECT_MAD_AVX2) + FUNC_SAVE + sub len, 32 + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 ;Multiply by 32 + lea tmp, [mul_array + vec_i] + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+2*vec] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + ; " Cx{00}, Cx{10}, ..., Cx{f0} + vmovdqu xgft5_lo, [tmp+4*vec] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + ; " Ex{00}, Ex{10}, ..., Ex{f0} + add tmp, vec + vmovdqu xgft4_lo, [tmp+2*vec] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + ; " Dx{00}, Dx{10}, ..., Dx{f0} + + mov dest3, [dest1+2*PS] ; reuse mul_array + mov dest4, [dest1+3*PS] ; reuse vec + mov dest5, [dest1+4*PS] ; reuse vec_i + mov dest2, [dest1+PS] + mov dest1, [dest1] + +.loop32: + XLDR x0, [src+pos] ;Get next source vector + + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector + XLDR xd3, [dest3+pos] ;Get next dest vector + XLDR xd4, [dest4+pos] ;Get next dest vector + XLDR xd5, [dest5+pos] ;Get next dest vector + + vpand xtmpl, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vperm2i128 xtmpa, xtmpl, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xtmpl, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + vperm2i128 xtmph1, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vperm2i128 xtmph2, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + + ; dest1 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl ;GF add high and low partials + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + vperm2i128 xtmph1, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl ;GF add high and low partials + vpxor xd2, xd2, xtmph2 ;xd2 += partial + + vperm2i128 xtmph2, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + ; dest3 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl ;GF add high and low partials + vpxor xd3, xd3, xtmph1 ;xd3 += partial + + vperm2i128 xtmph1, xgft5_lo, xgft5_lo, 0x01 ; swapped to hi | lo + ; dest4 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl ;GF add high and low partials + vpxor xd4, xd4, xtmph2 ;xd4 += partial + + ; dest5 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft5_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl ;GF add high and low partials + vpxor xd5, xd5, xtmph1 ;xd5 += partial + + XSTR [dest1+pos], xd1 + XSTR [dest2+pos], xd2 + XSTR [dest3+pos], xd3 + XSTR [dest4+pos], xd4 + XSTR [dest5+pos], xd5 + + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + +.lessthan32: + ;; Tail len + ;; Do one more overlap pass + mov tmp.b, 0x1f + vpinsrb xtmph1x, xtmph1x, tmp.w, 0 + vpbroadcastb xtmph1, xtmph1x ;Construct mask 0x1f1f1f... + + mov tmp, len ;Overlapped offset length-32 + + XLDR x0, [src+tmp] ;Get next source vector + + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;Get next dest vector + XLDR xd3, [dest3+tmp] ;Get next dest vector + XLDR xd4, [dest4+tmp] ;Get next dest vector + XLDR xd5, [dest5+tmp] ;Get next dest vector + + sub len, pos + + vmovdqa xtmph2, [constip32] ;Load const of i + 32 + vpinsrb xtmplx, xtmplx, len.w, 15 + vinserti128 xtmpl, xtmpl, xtmplx, 1 ;swapped to xtmplx | xtmplx + vpshufb xtmpl, xtmpl, xtmph1 ;Broadcast len to all bytes. xtmph1=0x1f1f1f... + vpcmpgtb xtmpl, xtmpl, xtmph2 + + vpand xtmph1, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vperm2i128 xtmpa, xtmph1, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xtmph1, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + vperm2i128 xtmph1, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vperm2i128 xtmph2, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + + ; dest1 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xgft1_lo ;GF add high and low partials + vpand xtmph1, xtmph1, xtmpl + vpxor xd1, xd1, xtmph1 ;xd1 += partial + + vperm2i128 xtmph1, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + ; dest2 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xgft2_lo ;GF add high and low partials + vpand xtmph2, xtmph2, xtmpl + vpxor xd2, xd2, xtmph2 ;xd2 += partial + + vperm2i128 xtmph2, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + ; dest3 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xgft3_lo ;GF add high and low partials + vpand xtmph1, xtmph1, xtmpl + vpxor xd3, xd3, xtmph1 ;xd3 += partial + + vperm2i128 xtmph1, xgft5_lo, xgft5_lo, 0x01 ; swapped to hi | lo + ; dest4 + vpshufb xtmph2, xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xgft4_lo ;GF add high and low partials + vpand xtmph2, xtmph2, xtmpl + vpxor xd4, xd4, xtmph2 ;xd4 += partial + + ; dest5 + vpshufb xtmph1, xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xgft5_lo, xgft5_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xgft5_lo ;GF add high and low partials + vpand xtmph1, xtmph1, xtmpl + vpxor xd5, xd5, xtmph1 ;xd5 += partial + + XSTR [dest1+tmp], xd1 + XSTR [dest2+tmp], xd2 + XSTR [dest3+tmp], xd3 + XSTR [dest4+tmp], xd4 + XSTR [dest5+tmp], xd5 + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data +align 32 +constip32: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + ddq 0xe0e1e2e3e4e5e6e7e8e9eaebecedeeef + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_5VECT_MAD_AVX2, 04, 00, 020e diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_sse.asm new file mode 100644 index 000000000..3137f9e55 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_5vect_mad_sse.asm @@ -0,0 +1,409 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_5vect_mad_sse(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_5VECT_MAD_SSE _gf_5vect_mad_sse +%else + %define GF_5VECT_MAD_SSE gf_5vect_mad_sse +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 + %define tmp4 r14 + %define return rax + %define return.w eax + %define stack_size 16*10 + 5*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define tmp4 r13 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define tmp4 r13 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + %endmacro + %macro FUNC_RESTORE 0 + pop r13 + pop r12 + %endmacro +%endif + +;;; gf_5vect_mad_sse(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 tmp4 +%define dest3 mul_array +%define dest4 tmp2 +%define dest5 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft5_hi xmm14 +%define xgft4_lo xmm13 +%define xgft4_hi xmm12 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xtmph3 xmm6 +%define xtmpl3 xmm7 +%define xtmph5 xmm8 +%define xtmpl5 xmm9 +%define xd1 xmm10 +%define xd2 xmm11 +%define xd3 xtmpl1 +%define xd4 xtmph1 +%define xd5 xtmpl2 + + +align 16 +global GF_5VECT_MAD_SSE:function +func(GF_5VECT_MAD_SSE) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov tmp, vec + sal vec_i, 5 ;Multiply by 32 + lea tmp3, [mul_array + vec_i] + sal tmp, 6 ;Multiply by 64 + movdqu xgft5_hi, [tmp3+2*tmp+16] ; " Ex{00}, Ex{10}, ..., Ex{f0} + sal vec, 5 ;Multiply by 32 + add tmp, vec + movdqu xgft4_hi, [tmp3+tmp+16] ; " Dx{00}, Dx{10}, Dx{20}, ... , Dx{f0} + movdqu xgft4_lo, [tmp3+tmp] ;Load array Dx{00}, Dx{01}, Dx{02}, ... + + mov dest3, [dest1+2*PS] ; reuse mul_array + mov dest4, [dest1+3*PS] + mov dest5, [dest1+4*PS] ; reuse vec_i + mov dest2, [dest1+PS] + mov dest1, [dest1] + +.loop16: + XLDR x0, [src+pos] ;Get next source vector + + movdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + movdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + movdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + movdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + movdqu xtmph3, [tmp3+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + movdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + movdqu xtmpl5, [tmp3+4*vec] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + movdqa xtmph5, xgft5_hi ;Reload const array registers + + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + ; dest1 + pshufb xtmph1, x0 ;Lookup mul table of high nibble + pshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + pxor xtmph1, xtmpl1 ;GF add high and low partials + pxor xd1, xtmph1 + + XLDR xd3, [dest3+pos] ;Reuse xtmpl1, Get next dest vector + XLDR xd4, [dest4+pos] ;Reuse xtmph1. Get next dest vector + + ; dest2 + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl2 ;GF add high and low partials + pxor xd2, xtmph2 + + XLDR xd5, [dest5+pos] ;Reuse xtmpl2. Get next dest vector + + ; dest3 + pshufb xtmph3, x0 ;Lookup mul table of high nibble + pshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + pxor xtmph3, xtmpl3 ;GF add high and low partials + pxor xd3, xtmph3 + + movdqa xtmph2, xgft4_hi ;Reload const array registers + movdqa xtmpl3, xgft4_lo ;Reload const array registers + + ; dest5 + pshufb xtmph5, x0 ;Lookup mul table of high nibble + pshufb xtmpl5, xtmpa ;Lookup mul table of low nibble + pxor xtmph5, xtmpl5 ;GF add high and low partials + pxor xd5, xtmph5 + + ; dest4 + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl3 ;GF add high and low partials + pxor xd4, xtmph2 + + XSTR [dest1+pos], xd1 ;Store result into dest1 + XSTR [dest2+pos], xd2 ;Store result into dest2 + XSTR [dest3+pos], xd3 ;Store result into dest3 + XSTR [dest4+pos], xd4 ;Store result into dest4 + XSTR [dest5+pos], xd5 ;Store result into dest5 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + +.lessthan16: + ;; Tail len + ;; Do one more overlap pass + mov tmp, len ;Overlapped offset length-16 + XLDR x0, [src+tmp] ;Get next source vector + + sub len, pos + + movdqa xtmpl1, [constip16] ;Load const of i + 16 + pinsrb xtmph5, len.w, 15 + pshufb xtmph5, xmask0f ;Broadcast len to all bytes + pcmpgtb xtmph5, xtmpl1 + + movdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + movdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + movdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + movdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + movdqu xtmph3, [tmp3+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + movdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + movdqu xtmpl5, [tmp3+4*vec] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;Get next dest vector + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + ; dest1 + pshufb xtmph1, x0 ;Lookup mul table of high nibble + pshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + pxor xtmph1, xtmpl1 ;GF add high and low partials + pand xtmph1, xtmph5 + pxor xd1, xtmph1 + + XLDR xd3, [dest3+tmp] ;Reuse xtmpl1, Get next dest vector + XLDR xd4, [dest4+tmp] ;Reuse xtmph1. Get next dest vector + + ; dest2 + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl2 ;GF add high and low partials + pand xtmph2, xtmph5 + pxor xd2, xtmph2 + + XLDR xd5, [dest5+tmp] ;Reuse xtmpl2. Get next dest vector + + ; dest3 + pshufb xtmph3, x0 ;Lookup mul table of high nibble + pshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + pxor xtmph3, xtmpl3 ;GF add high and low partials + pand xtmph3, xtmph5 + pxor xd3, xtmph3 + + ; dest4 + pshufb xgft4_hi, x0 ;Lookup mul table of high nibble + pshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft4_hi, xgft4_lo ;GF add high and low partials + pand xgft4_hi, xtmph5 + pxor xd4, xgft4_hi + + ; dest5 + pshufb xgft5_hi, x0 ;Lookup mul table of high nibble + pshufb xtmpl5, xtmpa ;Lookup mul table of low nibble + pxor xgft5_hi, xtmpl5 ;GF add high and low partials + pand xgft5_hi, xtmph5 + pxor xd5, xgft5_hi + + XSTR [dest1+tmp], xd1 ;Store result into dest1 + XSTR [dest2+tmp], xd2 ;Store result into dest2 + XSTR [dest3+tmp], xd3 ;Store result into dest3 + XSTR [dest4+tmp], xd4 ;Store result into dest4 + XSTR [dest5+tmp], xd5 ;Store result into dest5 + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 + +mask0f: + ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +constip16: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_5VECT_MAD_SSE, 00, 00, 020c diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_avx.asm new file mode 100644 index 000000000..34c0bdafb --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_avx.asm @@ -0,0 +1,360 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_6vect_dot_prod_avx(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_6VECT_DOT_PROD_AVX _gf_6vect_dot_prod_avx +%else + %define GF_6VECT_DOT_PROD_AVX gf_6vect_dot_prod_avx +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + %define stack_size 10*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_xmm128 xmm9, 3*16 + save_xmm128 xmm10, 4*16 + save_xmm128 xmm11, 5*16 + save_xmm128 xmm12, 6*16 + save_xmm128 xmm13, 7*16 + save_xmm128 xmm14, 8*16 + save_xmm128 xmm15, 9*16 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + save_reg rdi, 10*16 + 4*8 + save_reg rsi, 10*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + vmovdqa xmm9, [rsp + 3*16] + vmovdqa xmm10, [rsp + 4*16] + vmovdqa xmm11, [rsp + 5*16] + vmovdqa xmm12, [rsp + 6*16] + vmovdqa xmm13, [rsp + 7*16] + vmovdqa xmm14, [rsp + 8*16] + vmovdqa xmm15, [rsp + 9*16] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + mov rdi, [rsp + 10*16 + 4*8] + mov rsi, [rsp + 10*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest1 tmp3 +%define dest2 tmp4 +%define vskip1 tmp5 +%define vskip3 tmp6 +%define pos return + + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft1_lo xmm14 +%define xgft1_hi xmm13 +%define xgft2_lo xmm12 +%define xgft2_hi xmm11 +%define xgft3_lo xmm10 +%define xgft3_hi xmm9 +%define x0 xmm0 +%define xtmpa xmm1 +%define xp1 xmm2 +%define xp2 xmm3 +%define xp3 xmm4 +%define xp4 xmm5 +%define xp5 xmm6 +%define xp6 xmm7 + +align 16 +global GF_6VECT_DOT_PROD_AVX:function +func(GF_6VECT_DOT_PROD_AVX) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov vskip1, vec + imul vskip1, 32 + mov vskip3, vec + imul vskip3, 96 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + mov dest1, [dest] + mov dest2, [dest+PS] + + +.loop16: + mov tmp, mul_array + xor vec_i, vec_i + vpxor xp1, xp1 + vpxor xp2, xp2 + vpxor xp3, xp3 + vpxor xp4, xp4 + vpxor xp5, xp5 + vpxor xp6, xp6 + +.next_vect: + mov ptr, [src+vec_i] + add vec_i, PS + XLDR x0, [ptr+pos] ;Get next source vector + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + vmovdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vskip1*1] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + vmovdqu xgft2_hi, [tmp+vskip1*1+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+vskip1*2] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + vmovdqu xgft3_hi, [tmp+vskip1*2+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + lea ptr, [vskip1 + vskip1*4] ;ptr = vskip5 + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp3, xgft3_hi ;xp3 += partial + + + vmovdqu xgft1_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + vmovdqu xgft1_hi, [tmp+vskip3+16] ; " Dx{00}, Dx{10}, ..., Dx{f0} + vmovdqu xgft2_lo, [tmp+vskip1*4] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + vmovdqu xgft2_hi, [tmp+vskip1*4+16] ; " Ex{00}, Ex{10}, ..., Ex{f0} + vmovdqu xgft3_lo, [tmp+ptr] ;Load array Fx{00}, Fx{01}, ..., Fx{0f} + vmovdqu xgft3_hi, [tmp+ptr+16] ; " Fx{00}, Fx{10}, ..., Fx{f0} + add tmp, 32 + + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp4, xgft1_hi ;xp4 += partial + + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp5, xgft2_hi ;xp5 += partial + + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp6, xgft3_hi ;xp6 += partial + + cmp vec_i, vec + jl .next_vect + + + mov tmp, [dest+2*PS] + mov ptr, [dest+3*PS] + mov vec_i, [dest+4*PS] + + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + XSTR [tmp+pos], xp3 + mov tmp, [dest+5*PS] + XSTR [ptr+pos], xp4 + XSTR [vec_i+pos], xp5 + XSTR [tmp+pos], xp6 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_6VECT_DOT_PROD_AVX, 02, 03, 0195 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_avx2.asm new file mode 100644 index 000000000..9a020f70f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_avx2.asm @@ -0,0 +1,373 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_6vect_dot_prod_avx2(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_6VECT_DOT_PROD_AVX2 _gf_6vect_dot_prod_avx2 +%else + %define GF_6VECT_DOT_PROD_AVX2 gf_6vect_dot_prod_avx2 +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + %define stack_size 10*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + vmovdqa [rsp + 0*16], xmm6 + vmovdqa [rsp + 1*16], xmm7 + vmovdqa [rsp + 2*16], xmm8 + vmovdqa [rsp + 3*16], xmm9 + vmovdqa [rsp + 4*16], xmm10 + vmovdqa [rsp + 5*16], xmm11 + vmovdqa [rsp + 6*16], xmm12 + vmovdqa [rsp + 7*16], xmm13 + vmovdqa [rsp + 8*16], xmm14 + vmovdqa [rsp + 9*16], xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + save_reg rdi, 10*16 + 4*8 + save_reg rsi, 10*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm8, [rsp + 2*16] + vmovdqa xmm9, [rsp + 3*16] + vmovdqa xmm10, [rsp + 4*16] + vmovdqa xmm11, [rsp + 5*16] + vmovdqa xmm12, [rsp + 6*16] + vmovdqa xmm13, [rsp + 7*16] + vmovdqa xmm14, [rsp + 8*16] + vmovdqa xmm15, [rsp + 9*16] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + mov rdi, [rsp + 10*16 + 4*8] + mov rsi, [rsp + 10*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest1 tmp3 +%define dest2 tmp4 +%define vskip1 tmp5 +%define vskip3 tmp6 +%define pos return + + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f ymm15 +%define xmask0fx xmm15 +%define xgft1_lo ymm14 +%define xgft1_hi ymm13 +%define xgft2_lo ymm12 +%define xgft2_hi ymm11 +%define xgft3_lo ymm10 +%define xgft3_hi ymm9 +%define x0 ymm0 +%define xtmpa ymm1 +%define xp1 ymm2 +%define xp2 ymm3 +%define xp3 ymm4 +%define xp4 ymm5 +%define xp5 ymm6 +%define xp6 ymm7 + +align 16 +global GF_6VECT_DOT_PROD_AVX2:function +func(GF_6VECT_DOT_PROD_AVX2) + FUNC_SAVE + sub len, 32 + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + mov vskip1, vec + imul vskip1, 32 + mov vskip3, vec + imul vskip3, 96 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + mov dest1, [dest] + mov dest2, [dest+PS] + + +.loop32: + mov tmp, mul_array + xor vec_i, vec_i + vpxor xp1, xp1 + vpxor xp2, xp2 + vpxor xp3, xp3 + vpxor xp4, xp4 + vpxor xp5, xp5 + vpxor xp6, xp6 + +.next_vect: + mov ptr, [src+vec_i] + XLDR x0, [ptr+pos] ;Get next source vector + add vec_i, PS + + vpand xgft3_lo, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vperm2i128 xtmpa, xgft3_lo, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xgft3_lo, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vskip1*1] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+vskip1*2] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + ; " Cx{00}, Cx{10}, ..., Cx{f0} + lea ptr, [vskip1 + vskip1*4] ;ptr = vskip5 + + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft3_hi, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp1, xgft1_hi ;xp1 += partial + + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp2, xgft2_hi ;xp2 += partial + + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp3, xgft3_hi ;xp3 += partial + + + vmovdqu xgft1_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + ; " Dx{00}, Dx{10}, ..., Dx{f0} + vmovdqu xgft2_lo, [tmp+vskip1*4] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + ; " Ex{00}, Ex{10}, ..., Ex{f0} + vmovdqu xgft3_lo, [tmp+ptr] ;Load array Fx{00}, Fx{01}, ..., Fx{0f} + ; " Fx{00}, Fx{10}, ..., Fx{f0} + add tmp, 32 + vperm2i128 xgft1_hi, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft2_hi, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + vperm2i128 xgft3_hi, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + + vpshufb xgft1_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft1_hi, xgft1_lo ;GF add high and low partials + vpxor xp4, xgft1_hi ;xp4 += partial + + vpshufb xgft2_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft2_hi, xgft2_lo ;GF add high and low partials + vpxor xp5, xgft2_hi ;xp5 += partial + + vpshufb xgft3_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft3_hi, xgft3_lo ;GF add high and low partials + vpxor xp6, xgft3_hi ;xp6 += partial + + cmp vec_i, vec + jl .next_vect + + + mov tmp, [dest+2*PS] + mov ptr, [dest+3*PS] + mov vec_i, [dest+4*PS] + + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + XSTR [tmp+pos], xp3 + mov tmp, [dest+5*PS] + XSTR [ptr+pos], xp4 + XSTR [vec_i+pos], xp5 + XSTR [tmp+pos], xp6 + + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop32 ;Do one more overlap pass + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_6VECT_DOT_PROD_AVX2, 04, 03, 019a diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_sse.asm new file mode 100644 index 000000000..b37480be9 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_dot_prod_sse.asm @@ -0,0 +1,360 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_6vect_dot_prod_sse(len, vec, *g_tbls, **buffs, **dests); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_6VECT_DOT_PROD_SSE _gf_6vect_dot_prod_sse +%else + %define GF_6VECT_DOT_PROD_SSE gf_6vect_dot_prod_sse +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r12 ; must be saved and restored + %define tmp5 r14 ; must be saved and restored + %define tmp6 r15 ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + push r15 + %endmacro + %macro FUNC_RESTORE 0 + pop r15 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved, loaded and restored + %define arg5 r15 ; must be saved and restored + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 ; must be saved and restored + %define tmp4 r14 ; must be saved and restored + %define tmp5 rdi ; must be saved and restored + %define tmp6 rsi ; must be saved and restored + %define return rax + %define PS 8 + %define LOG_PS 3 + %define stack_size 10*16 + 7*8 ; must be an odd multiple of 8 + %define arg(x) [rsp + stack_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm8, 2*16 + save_xmm128 xmm9, 3*16 + save_xmm128 xmm10, 4*16 + save_xmm128 xmm11, 5*16 + save_xmm128 xmm12, 6*16 + save_xmm128 xmm13, 7*16 + save_xmm128 xmm14, 8*16 + save_xmm128 xmm15, 9*16 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + save_reg rdi, 10*16 + 4*8 + save_reg rsi, 10*16 + 5*8 + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + movdqa xmm6, [rsp + 0*16] + movdqa xmm7, [rsp + 1*16] + movdqa xmm8, [rsp + 2*16] + movdqa xmm9, [rsp + 3*16] + movdqa xmm10, [rsp + 4*16] + movdqa xmm11, [rsp + 5*16] + movdqa xmm12, [rsp + 6*16] + movdqa xmm13, [rsp + 7*16] + movdqa xmm14, [rsp + 8*16] + movdqa xmm15, [rsp + 9*16] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + mov rdi, [rsp + 10*16 + 4*8] + mov rsi, [rsp + 10*16 + 5*8] + add rsp, stack_size + %endmacro +%endif + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 +%define ptr arg5 +%define vec_i tmp2 +%define dest1 tmp3 +%define dest2 tmp4 +%define vskip1 tmp5 +%define vskip3 tmp6 +%define pos return + + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft1_lo xmm2 +%define xgft1_hi xmm3 +%define xgft2_lo xmm4 +%define xgft2_hi xmm5 +%define xgft3_lo xmm6 +%define xgft3_hi xmm7 +%define x0 xmm0 +%define xtmpa xmm1 +%define xp1 xmm8 +%define xp2 xmm9 +%define xp3 xmm10 +%define xp4 xmm11 +%define xp5 xmm12 +%define xp6 xmm13 + +align 16 +global GF_6VECT_DOT_PROD_SSE:function +func(GF_6VECT_DOT_PROD_SSE) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov vskip1, vec + imul vskip1, 32 + mov vskip3, vec + imul vskip3, 96 + sal vec, LOG_PS ;vec *= PS. Make vec_i count by PS + mov dest1, [dest] + mov dest2, [dest+PS] + + +.loop16: + mov tmp, mul_array + xor vec_i, vec_i + pxor xp1, xp1 + pxor xp2, xp2 + pxor xp3, xp3 + pxor xp4, xp4 + pxor xp5, xp5 + pxor xp6, xp6 + +.next_vect: + mov ptr, [src+vec_i] + add vec_i, PS + XLDR x0, [ptr+pos] ;Get next source vector + + movdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + movdqu xgft1_hi, [tmp+16] ; " Ax{00}, Ax{10}, ..., Ax{f0} + movdqu xgft2_lo, [tmp+vskip1*1] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + movdqu xgft2_hi, [tmp+vskip1*1+16] ; " Bx{00}, Bx{10}, ..., Bx{f0} + movdqu xgft3_lo, [tmp+vskip1*2] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + movdqu xgft3_hi, [tmp+vskip1*2+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + lea ptr, [vskip1 + vskip1*4] ;ptr = vskip5 + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + pshufb xgft1_hi, x0 ;Lookup mul table of high nibble + pshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft1_hi, xgft1_lo ;GF add high and low partials + pxor xp1, xgft1_hi ;xp1 += partial + + pshufb xgft2_hi, x0 ;Lookup mul table of high nibble + pshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft2_hi, xgft2_lo ;GF add high and low partials + pxor xp2, xgft2_hi ;xp2 += partial + + pshufb xgft3_hi, x0 ;Lookup mul table of high nibble + pshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft3_hi, xgft3_lo ;GF add high and low partials + pxor xp3, xgft3_hi ;xp3 += partial + + + movdqu xgft1_lo, [tmp+vskip3] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + movdqu xgft1_hi, [tmp+vskip3+16] ; " Dx{00}, Dx{10}, ..., Dx{f0} + movdqu xgft2_lo, [tmp+vskip1*4] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + movdqu xgft2_hi, [tmp+vskip1*4+16] ; " Ex{00}, Ex{10}, ..., Ex{f0} + movdqu xgft3_lo, [tmp+ptr] ;Load array Fx{00}, Fx{01}, ..., Fx{0f} + movdqu xgft3_hi, [tmp+ptr+16] ; " Fx{00}, Fx{10}, ..., Fx{f0} + add tmp, 32 + + + pshufb xgft1_hi, x0 ;Lookup mul table of high nibble + pshufb xgft1_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft1_hi, xgft1_lo ;GF add high and low partials + pxor xp4, xgft1_hi ;xp4 += partial + + pshufb xgft2_hi, x0 ;Lookup mul table of high nibble + pshufb xgft2_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft2_hi, xgft2_lo ;GF add high and low partials + pxor xp5, xgft2_hi ;xp5 += partial + + pshufb xgft3_hi, x0 ;Lookup mul table of high nibble + pshufb xgft3_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft3_hi, xgft3_lo ;GF add high and low partials + pxor xp6, xgft3_hi ;xp6 += partial + + cmp vec_i, vec + jl .next_vect + + + mov tmp, [dest+2*PS] + mov ptr, [dest+3*PS] + mov vec_i, [dest+4*PS] + + XSTR [dest1+pos], xp1 + XSTR [dest2+pos], xp2 + XSTR [tmp+pos], xp3 + mov tmp, [dest+5*PS] + XSTR [ptr+pos], xp4 + XSTR [vec_i+pos], xp5 + XSTR [tmp+pos], xp6 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_6VECT_DOT_PROD_SSE, 00, 04, 0066 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_avx.asm new file mode 100644 index 000000000..f82b96736 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_avx.asm @@ -0,0 +1,433 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_6vect_mad_avx(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_6VECT_MAD_AVX _gf_6vect_mad_avx +%else + %define GF_6VECT_MAD_AVX gf_6vect_mad_avx +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r13 + %define tmp4 r14 + %define tmp5 rdi + %define return rax + %define return.w eax + %define stack_size 16*10 + 5*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + save_reg rdi, 10*16 + 4*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + mov rdi, [rsp + 10*16 + 4*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define tmp4 r13 + %define tmp5 r14 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + %endmacro + %macro FUNC_RESTORE 0 + pop r14 + pop r13 + pop r12 + %endmacro +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp2 r10 + %define tmp3 r12 + %define tmp4 r13 + %define tmp5 r14 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + %endmacro + %macro FUNC_RESTORE 0 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +;;; gf_6vect_mad_avx(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 tmp4 +%define dest3 tmp2 +%define dest4 mul_array +%define dest5 tmp5 +%define dest6 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft4_lo xmm14 +%define xgft4_hi xmm13 +%define xgft5_lo xmm12 +%define xgft5_hi xmm11 +%define xgft6_lo xmm10 +%define xgft6_hi xmm9 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xtmph3 xmm6 +%define xtmpl3 xmm7 +%define xd1 xmm8 +%define xd2 xtmpl1 +%define xd3 xtmph1 + + +align 16 +global GF_6VECT_MAD_AVX:function +func(GF_6VECT_MAD_AVX) + FUNC_SAVE + sub len, 16 + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + mov tmp, vec + sal vec_i, 5 ;Multiply by 32 + lea tmp3, [mul_array + vec_i] + sal tmp, 6 ;Multiply by 64 + + sal vec, 5 ;Multiply by 32 + lea vec_i, [tmp + vec] ;vec_i = vec*96 + lea mul_array, [tmp + vec_i] ;mul_array = vec*160 + + vmovdqu xgft5_lo, [tmp3+2*tmp] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + vmovdqu xgft5_hi, [tmp3+2*tmp+16] ; " Ex{00}, Ex{10}, ..., Ex{f0} + vmovdqu xgft4_lo, [tmp3+vec_i] ;Load array Dx{00}, Dx{01}, Dx{02}, ... + vmovdqu xgft4_hi, [tmp3+vec_i+16] ; " Dx{00}, Dx{10}, Dx{20}, ... , Dx{f0} + vmovdqu xgft6_lo, [tmp3+mul_array] ;Load array Fx{00}, Fx{01}, ..., Fx{0f} + vmovdqu xgft6_hi, [tmp3+mul_array+16] ; " Fx{00}, Fx{10}, ..., Fx{f0} + + mov dest2, [dest1+PS] + mov dest3, [dest1+2*PS] + mov dest4, [dest1+3*PS] ; reuse mul_array + mov dest5, [dest1+4*PS] + mov dest6, [dest1+5*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop16: + XLDR x0, [src+pos] ;Get next source vector + + vmovdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + vmovdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + vmovdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + vmovdqu xtmph3, [tmp3+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + XLDR xd1, [dest1+pos] ;Get next dest vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + + ;dest1 + vpshufb xtmph1, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmpl1 ;GF add high and low partials + vpxor xd1, xtmph1 + + XLDR xd2, [dest2+pos] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest3+pos] ;reuse xtmph1. Get next dest vector + + ;dest2 + vpshufb xtmph2, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmpl2 ;GF add high and low partials + vpxor xd2, xtmph2 + + ;dest3 + vpshufb xtmph3, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmpl3 ;GF add high and low partials + vpxor xd3, xtmph3 + + XSTR [dest1+pos], xd1 ;Store result into dest1 + XSTR [dest2+pos], xd2 ;Store result into dest2 + XSTR [dest3+pos], xd3 ;Store result into dest3 + + ;dest4 + XLDR xd1, [dest4+pos] ;Get next dest vector + vpshufb xtmph1, xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl1, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph1, xtmph1, xtmpl1 ;GF add high and low partials + vpxor xd1, xd1, xtmph1 + + XLDR xd2, [dest5+pos] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest6+pos] ;reuse xtmph1. Get next dest vector + + ;dest5 + vpshufb xtmph2, xgft5_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl2, xgft5_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph2, xtmph2, xtmpl2 ;GF add high and low partials + vpxor xd2, xd2, xtmph2 + + ;dest6 + vpshufb xtmph3, xgft6_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl3, xgft6_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph3, xtmph3, xtmpl3 ;GF add high and low partials + vpxor xd3, xd3, xtmph3 + + XSTR [dest4+pos], xd1 ;Store result into dest4 + XSTR [dest5+pos], xd2 ;Store result into dest5 + XSTR [dest6+pos], xd3 ;Store result into dest6 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + +.lessthan16: + ;; Tail len + ;; Do one more overlap pass + ;; Overlapped offset length-16 + mov tmp, len ;Backup len as len=rdi + + XLDR x0, [src+tmp] ;Get next source vector + XLDR xd1, [dest4+tmp] ;Get next dest vector + XLDR xd2, [dest5+tmp] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest6+tmp] ;reuse xtmph1. Get next dest vector + + sub len, pos + + vmovdqa xtmph3, [constip16] ;Load const of i + 16 + vpinsrb xtmpl3, len.w, 15 + vpshufb xtmpl3, xmask0f ;Broadcast len to all bytes + vpcmpgtb xtmpl3, xtmpl3, xtmph3 + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + ;dest4 + vpshufb xgft4_hi, xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft4_hi, xgft4_hi, xgft4_lo ;GF add high and low partials + vpand xgft4_hi, xgft4_hi, xtmpl3 + vpxor xd1, xd1, xgft4_hi + + ;dest5 + vpshufb xgft5_hi, xgft5_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft5_lo, xgft5_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft5_hi, xgft5_hi, xgft5_lo ;GF add high and low partials + vpand xgft5_hi, xgft5_hi, xtmpl3 + vpxor xd2, xd2, xgft5_hi + + ;dest6 + vpshufb xgft6_hi, xgft6_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft6_lo, xgft6_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft6_hi, xgft6_hi, xgft6_lo ;GF add high and low partials + vpand xgft6_hi, xgft6_hi, xtmpl3 + vpxor xd3, xd3, xgft6_hi + + XSTR [dest4+tmp], xd1 ;Store result into dest4 + XSTR [dest5+tmp], xd2 ;Store result into dest5 + XSTR [dest6+tmp], xd3 ;Store result into dest6 + + vmovdqu xgft4_lo, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + vmovdqu xgft4_hi, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + vmovdqu xgft5_lo, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + vmovdqu xgft5_hi, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + vmovdqu xgft6_lo, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + vmovdqu xgft6_hi, [tmp3+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest3+tmp] ;reuse xtmph1. Get next dest3 vector + + ;dest1 + vpshufb xgft4_hi, xgft4_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft4_hi, xgft4_hi, xgft4_lo ;GF add high and low partials + vpand xgft4_hi, xgft4_hi, xtmpl3 + vpxor xd1, xd1, xgft4_hi + + ;dest2 + vpshufb xgft5_hi, xgft5_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft5_lo, xgft5_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft5_hi, xgft5_hi, xgft5_lo ;GF add high and low partials + vpand xgft5_hi, xgft5_hi, xtmpl3 + vpxor xd2, xd2, xgft5_hi + + ;dest3 + vpshufb xgft6_hi, xgft6_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft6_lo, xgft6_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft6_hi, xgft6_hi, xgft6_lo ;GF add high and low partials + vpand xgft6_hi, xgft6_hi, xtmpl3 + vpxor xd3, xd3, xgft6_hi + + XSTR [dest1+tmp], xd1 ;Store result into dest1 + XSTR [dest2+tmp], xd2 ;Store result into dest2 + XSTR [dest3+tmp], xd3 ;Store result into dest3 + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +constip16: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_6VECT_MAD_AVX, 02, 00, 0210 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_avx2.asm new file mode 100644 index 000000000..86566b2a2 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_avx2.asm @@ -0,0 +1,435 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_6vect_mad_avx2(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_6VECT_MAD_AVX2 _gf_6vect_mad_avx2 +%else + %define GF_6VECT_MAD_AVX2 gf_6vect_mad_avx2 +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r13 + %define return rax + %define return.w eax + %define stack_size 16*10 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r15, 10*16 + 2*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r15, [rsp + 10*16 + 3*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r12 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r12 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + %endmacro + %macro FUNC_RESTORE 0 + pop r12 + %endmacro +%endif + +;;; gf_6vect_mad_avx2(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 tmp3 +%define dest3 tmp2 +%define dest4 mul_array +%define dest5 vec +%define dest6 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f ymm15 +%define xmask0fx xmm15 +%define xgft1_lo ymm14 +%define xgft2_lo ymm13 +%define xgft3_lo ymm12 +%define xgft4_lo ymm11 +%define xgft5_lo ymm10 +%define xgft6_lo ymm9 + +%define x0 ymm0 +%define xtmpa ymm1 +%define xtmpl ymm2 +%define xtmplx xmm2 +%define xtmph ymm3 +%define xtmphx xmm3 +%define xd1 ymm4 +%define xd2 ymm5 +%define xd3 ymm6 +%define xd4 ymm7 +%define xd5 ymm8 +%define xd6 xd1 + +align 16 +global GF_6VECT_MAD_AVX2:function +func(GF_6VECT_MAD_AVX2) + FUNC_SAVE + sub len, 32 + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + sal vec_i, 5 ;Multiply by 32 + sal vec, 5 ;Multiply by 32 + lea tmp, [mul_array + vec_i] + mov vec_i, vec + mov mul_array, vec + sal vec_i, 1 + sal mul_array, 1 + add vec_i, vec ;vec_i=vec*96 + add mul_array, vec_i ;vec_i=vec*160 + + vmovdqu xgft1_lo, [tmp] ;Load array Ax{00}, Ax{01}, ..., Ax{0f} + ; " Ax{00}, Ax{10}, ..., Ax{f0} + vmovdqu xgft2_lo, [tmp+vec] ;Load array Bx{00}, Bx{01}, ..., Bx{0f} + ; " Bx{00}, Bx{10}, ..., Bx{f0} + vmovdqu xgft3_lo, [tmp+2*vec] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + ; " Cx{00}, Cx{10}, ..., Cx{f0} + vmovdqu xgft4_lo, [tmp+vec_i] ;Load array Fx{00}, Fx{01}, ..., Fx{0f} + ; " Fx{00}, Fx{10}, ..., Fx{f0} + vmovdqu xgft5_lo, [tmp+4*vec] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + ; " Ex{00}, Ex{10}, ..., Ex{f0} + vmovdqu xgft6_lo, [tmp+mul_array] ;Load array Dx{00}, Dx{01}, ..., Dx{0f} + ; " Dx{00}, Dx{10}, ..., Dx{f0} + + mov dest2, [dest1+PS] ; reuse tmp3 + mov dest3, [dest1+2*PS] ; reuse tmp2 + mov dest4, [dest1+3*PS] ; reuse mul_array + mov dest5, [dest1+4*PS] ; reuse vec + mov dest6, [dest1+5*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop32: + XLDR x0, [src+pos] ;Get next source vector + XLDR xd1, [dest1+pos] ;Get next dest vector + XLDR xd2, [dest2+pos] ;Get next dest vector + XLDR xd3, [dest3+pos] ;Get next dest vector + XLDR xd4, [dest4+pos] ;Get next dest vector + XLDR xd5, [dest5+pos] ;Get next dest vector + + vpand xtmpl, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vperm2i128 xtmpa, xtmpl, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xtmpl, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + ;dest1 + vperm2i128 xtmph, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xtmpl ;GF add high and low partials + vpxor xd1, xd1, xtmph ;xd1 += partial + + XSTR [dest1+pos], xd1 ;Store result into dest1 + + ;dest2 + vperm2i128 xtmph, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xtmpl ;GF add high and low partials + vpxor xd2, xd2, xtmph ;xd2 += partial + + ;dest3 + vperm2i128 xtmph, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xtmpl ;GF add high and low partials + vpxor xd3, xd3, xtmph ;xd3 += partial + + XLDR xd6, [dest6+pos] ;reuse xd1. Get next dest vector + + ;dest4 + vperm2i128 xtmph, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xtmpl ;GF add high and low partials + vpxor xd4, xd4, xtmph ;xd4 += partial + + ;dest5 + vperm2i128 xtmph, xgft5_lo, xgft5_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft5_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xtmpl ;GF add high and low partials + vpxor xd5, xd5, xtmph ;xd5 += partial + + ;dest6 + vperm2i128 xtmph, xgft6_lo, xgft6_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft6_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xtmpl ;GF add high and low partials + vpxor xd6, xd6, xtmph ;xd6 += partial + + XSTR [dest2+pos], xd2 ;Store result into dest2 + XSTR [dest3+pos], xd3 ;Store result into dest3 + XSTR [dest4+pos], xd4 ;Store result into dest4 + XSTR [dest5+pos], xd5 ;Store result into dest5 + XSTR [dest6+pos], xd6 ;Store result into dest6 + + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + +.lessthan32: + ;; Tail len + ;; Do one more overlap pass + mov tmp.b, 0x1f + vpinsrb xtmphx, xtmphx, tmp.w, 0 + vpbroadcastb xtmph, xtmphx ;Construct mask 0x1f1f1f... + + mov tmp, len ;Overlapped offset length-32 + + XLDR x0, [src+tmp] ;Get next source vector + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;Get next dest vector + XLDR xd3, [dest3+tmp] ;Get next dest vector + XLDR xd4, [dest4+tmp] ;Get next dest vector + XLDR xd5, [dest5+tmp] ;Get next dest vector + + sub len, pos + + vpinsrb xtmplx, xtmplx, len.w, 15 + vinserti128 xtmpl, xtmpl, xtmplx, 1 ;swapped to xtmplx | xtmplx + vpshufb xtmpl, xtmpl, xtmph ;Broadcast len to all bytes. xtmph=0x1f1f1f... + vpcmpgtb xtmpl, xtmpl, [constip32] + + vpand xtmph, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vperm2i128 xtmpa, xtmph, x0, 0x30 ;swap xtmpa from 1lo|2lo to 1lo|2hi + vperm2i128 x0, xtmph, x0, 0x12 ;swap x0 from 1hi|2hi to 1hi|2lo + + ;dest1 + vperm2i128 xtmph, xgft1_lo, xgft1_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xgft1_lo, xgft1_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xgft1_lo ;GF add high and low partials + vpand xtmph, xtmph, xtmpl + vpxor xd1, xd1, xtmph ;xd1 += partial + + XSTR [dest1+tmp], xd1 ;Store result into dest1 + + ;dest2 + vperm2i128 xtmph, xgft2_lo, xgft2_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xgft2_lo, xgft2_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xgft2_lo ;GF add high and low partials + vpand xtmph, xtmph, xtmpl + vpxor xd2, xd2, xtmph ;xd2 += partial + + ;dest3 + vperm2i128 xtmph, xgft3_lo, xgft3_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xgft3_lo, xgft3_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xgft3_lo ;GF add high and low partials + vpand xtmph, xtmph, xtmpl + vpxor xd3, xd3, xtmph ;xd3 += partial + + XLDR xd6, [dest6+tmp] ;reuse xd1. Get next dest vector + + ;dest4 + vperm2i128 xtmph, xgft4_lo, xgft4_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xgft4_lo, xgft4_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xgft4_lo ;GF add high and low partials + vpand xtmph, xtmph, xtmpl + vpxor xd4, xd4, xtmph ;xd4 += partial + + ;dest5 + vperm2i128 xtmph, xgft5_lo, xgft5_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xgft5_lo, xgft5_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xgft5_lo ;GF add high and low partials + vpand xtmph, xtmph, xtmpl + vpxor xd5, xd5, xtmph ;xd5 += partial + + ;dest6 + vperm2i128 xtmph, xgft6_lo, xgft6_lo, 0x01 ; swapped to hi | lo + vpshufb xtmph, xtmph, x0 ;Lookup mul table of high nibble + vpshufb xgft6_lo, xgft6_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xgft6_lo ;GF add high and low partials + vpand xtmph, xtmph, xtmpl + vpxor xd6, xd6, xtmph ;xd6 += partial + + XSTR [dest2+tmp], xd2 ;Store result into dest2 + XSTR [dest3+tmp], xd3 ;Store result into dest3 + XSTR [dest4+tmp], xd4 ;Store result into dest4 + XSTR [dest5+tmp], xd5 ;Store result into dest5 + XSTR [dest6+tmp], xd6 ;Store result into dest6 + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data +align 32 +constip32: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + ddq 0xe0e1e2e3e4e5e6e7e8e9eaebecedeeef + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_6VECT_MAD_AVX2, 04, 00, 0211 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_sse.asm new file mode 100644 index 000000000..9d8374b29 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_6vect_mad_sse.asm @@ -0,0 +1,446 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_6vect_mad_sse(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_6VECT_MAD_SSE _gf_6vect_mad_sse +%else + %define GF_6VECT_MAD_SSE gf_6vect_mad_sse +%endif + +%define PS 8 + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define tmp.w r11d + %define tmp2 r10 + %define tmp3 r13 + %define tmp4 r14 + %define tmp5 rdi + %define return rax + %define return.w eax + %define stack_size 16*10 + 5*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + movdqa [rsp+16*3],xmm9 + movdqa [rsp+16*4],xmm10 + movdqa [rsp+16*5],xmm11 + movdqa [rsp+16*6],xmm12 + movdqa [rsp+16*7],xmm13 + movdqa [rsp+16*8],xmm14 + movdqa [rsp+16*9],xmm15 + save_reg r12, 10*16 + 0*8 + save_reg r13, 10*16 + 1*8 + save_reg r14, 10*16 + 2*8 + save_reg r15, 10*16 + 3*8 + save_reg rdi, 10*16 + 4*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + movdqa xmm9, [rsp+16*3] + movdqa xmm10, [rsp+16*4] + movdqa xmm11, [rsp+16*5] + movdqa xmm12, [rsp+16*6] + movdqa xmm13, [rsp+16*7] + movdqa xmm14, [rsp+16*8] + movdqa xmm15, [rsp+16*9] + mov r12, [rsp + 10*16 + 0*8] + mov r13, [rsp + 10*16 + 1*8] + mov r14, [rsp + 10*16 + 2*8] + mov r15, [rsp + 10*16 + 3*8] + mov rdi, [rsp + 10*16 + 4*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp.w r11d + %define tmp2 r10 + %define tmp3 r12 + %define tmp4 r13 + %define tmp5 r14 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + %endmacro + %macro FUNC_RESTORE 0 + pop r14 + pop r13 + pop r12 + %endmacro +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp.w r11d + %define tmp2 r10 + %define tmp3 r12 + %define tmp4 r13 + %define tmp5 r14 + %define return rax + %define return.w eax + + %define func(x) x: + %macro FUNC_SAVE 0 + push r12 + push r13 + push r14 + %endmacro + %macro FUNC_RESTORE 0 + pop r14 + pop r13 + pop r12 + %endmacro +%endif + +;;; gf_6vect_mad_sse(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest1 arg5 +%define pos return +%define pos.w return.w + +%define dest2 mul_array +%define dest3 tmp2 +%define dest4 tmp4 +%define dest5 tmp5 +%define dest6 vec_i + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft4_lo xmm14 +%define xgft4_hi xmm13 +%define xgft5_lo xmm12 +%define xgft5_hi xmm11 +%define xgft6_lo xmm10 +%define xgft6_hi xmm9 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph1 xmm2 +%define xtmpl1 xmm3 +%define xtmph2 xmm4 +%define xtmpl2 xmm5 +%define xtmph3 xmm6 +%define xtmpl3 xmm7 +%define xd1 xmm8 +%define xd2 xtmpl1 +%define xd3 xtmph1 + + +align 16 +global GF_6VECT_MAD_SSE:function +func(GF_6VECT_MAD_SSE) + FUNC_SAVE + sub len, 16 + jl .return_fail + + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + + mov tmp, vec + sal vec_i, 5 ;Multiply by 32 + lea tmp3, [mul_array + vec_i] + sal tmp, 6 ;Multiply by 64 + + sal vec, 5 ;Multiply by 32 + lea vec_i, [tmp + vec] ;vec_i = 96 + lea mul_array, [tmp + vec_i] ;mul_array = 160 + + movdqu xgft5_lo, [tmp3+2*tmp] ;Load array Ex{00}, Ex{01}, ..., Ex{0f} + movdqu xgft5_hi, [tmp3+2*tmp+16] ; " Ex{00}, Ex{10}, ..., Ex{f0} + movdqu xgft4_lo, [tmp3+vec_i] ;Load array Dx{00}, Dx{01}, Dx{02}, ... + movdqu xgft4_hi, [tmp3+vec_i+16] ; " Dx{00}, Dx{10}, Dx{20}, ... , Dx{f0} + movdqu xgft6_lo, [tmp3+mul_array] ;Load array Fx{00}, Fx{01}, ..., Fx{0f} + movdqu xgft6_hi, [tmp3+mul_array+16] ; " Fx{00}, Fx{10}, ..., Fx{f0} + + mov dest2, [dest1+PS] + mov dest3, [dest1+2*PS] + mov dest4, [dest1+3*PS] ; reuse mul_array + mov dest5, [dest1+4*PS] + mov dest6, [dest1+5*PS] ; reuse vec_i + mov dest1, [dest1] + +.loop16: + XLDR x0, [src+pos] ;Get next source vector + + movdqu xtmpl1, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + movdqu xtmph1, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + movdqu xtmpl2, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + movdqu xtmph2, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + movdqu xtmpl3, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + movdqu xtmph3, [tmp3+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + XLDR xd1, [dest1+pos] ;Get next dest vector + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + ;dest1 + pshufb xtmph1, x0 ;Lookup mul table of high nibble + pshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + pxor xtmph1, xtmpl1 ;GF add high and low partials + pxor xd1, xtmph1 + + XLDR xd2, [dest2+pos] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest3+pos] ;reuse xtmph1. Get next dest3 vector + + ;dest2 + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl2 ;GF add high and low partials + pxor xd2, xtmph2 + + ;dest3 + pshufb xtmph3, x0 ;Lookup mul table of high nibble + pshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + pxor xtmph3, xtmpl3 ;GF add high and low partials + pxor xd3, xtmph3 + + XSTR [dest1+pos], xd1 ;Store result into dest1 + XSTR [dest2+pos], xd2 ;Store result into dest2 + XSTR [dest3+pos], xd3 ;Store result into dest3 + + movdqa xtmph1, xgft4_hi ;Reload const array registers + movdqa xtmpl1, xgft4_lo ;Reload const array registers + movdqa xtmph2, xgft5_hi ;Reload const array registers + movdqa xtmpl2, xgft5_lo ;Reload const array registers + movdqa xtmph3, xgft6_hi ;Reload const array registers + movdqa xtmpl3, xgft6_lo ;Reload const array registers + + ;dest4 + XLDR xd1, [dest4+pos] ;Get next dest vector + pshufb xtmph1, x0 ;Lookup mul table of high nibble + pshufb xtmpl1, xtmpa ;Lookup mul table of low nibble + pxor xtmph1, xtmpl1 ;GF add high and low partials + pxor xd1, xtmph1 + + XLDR xd2, [dest5+pos] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest6+pos] ;reuse xtmph1. Get next dest vector + + ;dest5 + pshufb xtmph2, x0 ;Lookup mul table of high nibble + pshufb xtmpl2, xtmpa ;Lookup mul table of low nibble + pxor xtmph2, xtmpl2 ;GF add high and low partials + pxor xd2, xtmph2 + + ;dest6 + pshufb xtmph3, x0 ;Lookup mul table of high nibble + pshufb xtmpl3, xtmpa ;Lookup mul table of low nibble + pxor xtmph3, xtmpl3 ;GF add high and low partials + pxor xd3, xtmph3 + + XSTR [dest4+pos], xd1 ;Store result into dest4 + XSTR [dest5+pos], xd2 ;Store result into dest5 + XSTR [dest6+pos], xd3 ;Store result into dest6 + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + +.lessthan16: + ;; Tail len + ;; Do one more overlap pass + ;; Overlapped offset length-16 + mov tmp, len ;Backup len as len=rdi + + XLDR x0, [src+tmp] ;Get next source vector + XLDR xd1, [dest4+tmp] ;Get next dest vector + XLDR xd2, [dest5+tmp] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest6+tmp] ;reuse xtmph1. Get next dest vector + + sub len, pos + + movdqa xtmph3, [constip16] ;Load const of i + 16 + pinsrb xtmpl3, len.w, 15 + pshufb xtmpl3, xmask0f ;Broadcast len to all bytes + pcmpgtb xtmpl3, xtmph3 + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + ;dest4 + pshufb xgft4_hi, x0 ;Lookup mul table of high nibble + pshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft4_hi, xgft4_lo ;GF add high and low partials + pand xgft4_hi, xtmpl3 + pxor xd1, xgft4_hi + + ;dest5 + pshufb xgft5_hi, x0 ;Lookup mul table of high nibble + pshufb xgft5_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft5_hi, xgft5_lo ;GF add high and low partials + pand xgft5_hi, xtmpl3 + pxor xd2, xgft5_hi + + ;dest6 + pshufb xgft6_hi, x0 ;Lookup mul table of high nibble + pshufb xgft6_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft6_hi, xgft6_lo ;GF add high and low partials + pand xgft6_hi, xtmpl3 + pxor xd3, xgft6_hi + + XSTR [dest4+tmp], xd1 ;Store result into dest4 + XSTR [dest5+tmp], xd2 ;Store result into dest5 + XSTR [dest6+tmp], xd3 ;Store result into dest6 + + movdqu xgft4_lo, [tmp3] ;Load array Ax{00}, Ax{01}, Ax{02}, ... + movdqu xgft4_hi, [tmp3+16] ; " Ax{00}, Ax{10}, Ax{20}, ... , Ax{f0} + movdqu xgft5_lo, [tmp3+vec] ;Load array Bx{00}, Bx{01}, Bx{02}, ... + movdqu xgft5_hi, [tmp3+vec+16] ; " Bx{00}, Bx{10}, Bx{20}, ... , Bx{f0} + movdqu xgft6_lo, [tmp3+2*vec] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + movdqu xgft6_hi, [tmp3+2*vec+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + XLDR xd1, [dest1+tmp] ;Get next dest vector + XLDR xd2, [dest2+tmp] ;reuse xtmpl1. Get next dest vector + XLDR xd3, [dest3+tmp] ;reuse xtmph1. Get next dest3 vector + + ;dest1 + pshufb xgft4_hi, x0 ;Lookup mul table of high nibble + pshufb xgft4_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft4_hi, xgft4_lo ;GF add high and low partials + pand xgft4_hi, xtmpl3 + pxor xd1, xgft4_hi + + ;dest2 + pshufb xgft5_hi, x0 ;Lookup mul table of high nibble + pshufb xgft5_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft5_hi, xgft5_lo ;GF add high and low partials + pand xgft5_hi, xtmpl3 + pxor xd2, xgft5_hi + + ;dest3 + pshufb xgft6_hi, x0 ;Lookup mul table of high nibble + pshufb xgft6_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft6_hi, xgft6_lo ;GF add high and low partials + pand xgft6_hi, xtmpl3 + pxor xd3, xgft6_hi + + XSTR [dest1+tmp], xd1 ;Store result into dest1 + XSTR [dest2+tmp], xd2 ;Store result into dest2 + XSTR [dest3+tmp], xd3 ;Store result into dest3 + +.return_pass: + FUNC_RESTORE + mov return, 0 + ret + +.return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 + +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +constip16: + ddq 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_6VECT_MAD_SSE, 00, 00, 020f diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_avx.asm new file mode 100644 index 000000000..dfe0e1f95 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_avx.asm @@ -0,0 +1,303 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_vect_dot_prod_avx(len, vec, *g_tbls, **buffs, *dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_VECT_DOT_PROD_AVX _gf_vect_dot_prod_avx +%else + %define GF_VECT_DOT_PROD_AVX gf_vect_dot_prod_avx +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r9 + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r9 + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved and loaded + %define tmp r11 + %define tmp2 r10 + %define tmp3 rdi ; must be saved and loaded + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define frame_size 2*8 + %define arg(x) [rsp + frame_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + rex_push_reg r12 + push_reg rdi + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + pop rdi + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + + %define trans ecx ;trans is for the variables in stack + %define arg0 trans + %define arg0_m arg(0) + %define arg1 trans + %define arg1_m arg(1) + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 ebx + %define arg4 trans + %define arg4_m arg(4) + %define tmp edx + %define tmp2 edi + %define tmp3 esi + %define return eax + %macro SLDR 2 ;; stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + push esi + push edi + push ebx + mov arg3, arg(3) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + mov esp, ebp + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 + +%define vec_i tmp2 +%define ptr tmp3 +%define pos return + + %ifidn PS,4 ;32-bit code + %define vec_m arg1_m + %define len_m arg0_m + %define dest_m arg4_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +%ifidn PS,8 ; 64-bit code + default rel + [bits 64] +%endif + +section .text + +%define xmask0f xmm5 +%define xgft_lo xmm4 +%define xgft_hi xmm3 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xp xmm2 + +align 16 +global GF_VECT_DOT_PROD_AVX:function +func(GF_VECT_DOT_PROD_AVX) + FUNC_SAVE + SLDR len, len_m + sub len, 16 + SSTR len_m, len + jl .return_fail + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + +.loop16: + vpxor xp, xp + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + + mov ptr, [src+vec_i*PS] + vmovdqu xgft_lo, [tmp] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + vmovdqu xgft_hi, [tmp+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + XLDR x0, [ptr+pos] ;Get next source vector + + add tmp, 32 + add vec_i, 1 + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xgft_hi, xgft_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft_lo, xgft_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft_hi, xgft_hi, xgft_lo ;GF add high and low partials + vpxor xp, xp, xgft_hi ;xp += partial + + SLDR vec, vec_m + cmp vec_i, vec + jl .next_vect + + SLDR dest, dest_m + XSTR [dest+pos], xp + + add pos, 16 ;Loop on 16 bytes at a time + SLDR len, len_m + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 + +mask0f: +ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_VECT_DOT_PROD_AVX, 02, 04, 0061 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_avx2.asm new file mode 100644 index 000000000..8744318f5 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_avx2.asm @@ -0,0 +1,315 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_vect_dot_prod_avx2(len, vec, *g_tbls, **buffs, *dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_VECT_DOT_PROD_AVX2 _gf_vect_dot_prod_avx2 +%else + %define GF_VECT_DOT_PROD_AVX2 gf_vect_dot_prod_avx2 +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r9 + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 r9 + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved and loaded + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define tmp2 r10 + %define tmp3 rdi ; must be saved and loaded + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define frame_size 2*8 + %define arg(x) [rsp + frame_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + rex_push_reg r12 + push_reg rdi + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + pop rdi + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + + %define trans ecx ;trans is for the variables in stack + %define arg0 trans + %define arg0_m arg(0) + %define arg1 trans + %define arg1_m arg(1) + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 ebx + %define arg4 trans + %define arg4_m arg(4) + %define tmp edx + %define tmp.w edx + %define tmp.b dl + %define tmp2 edi + %define tmp3 esi + %define return eax + %macro SLDR 2 ;stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + push esi + push edi + push ebx + mov arg3, arg(3) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + mov esp, ebp + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 + +%define vec_i tmp2 +%define ptr tmp3 +%define pos return + +%ifidn PS,4 ;32-bit code + %define vec_m arg1_m + %define len_m arg0_m + %define dest_m arg4_m +%endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + +%ifidn PS,8 ;64-bit code + default rel + [bits 64] +%endif + +section .text + +%define xmask0f ymm3 +%define xmask0fx xmm3 +%define xgft_lo ymm4 +%define xgft_hi ymm5 + +%define x0 ymm0 +%define xtmpa ymm1 +%define xp ymm2 + +align 16 +global GF_VECT_DOT_PROD_AVX2:function +func(GF_VECT_DOT_PROD_AVX2) + FUNC_SAVE + SLDR len, len_m + sub len, 32 + SSTR len_m, len + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + +.loop32: + vpxor xp, xp + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + + mov ptr, [src+vec_i*PS] + + vmovdqu xgft_lo, [tmp] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + vperm2i128 xgft_hi, xgft_lo, xgft_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft_lo, xgft_lo, xgft_lo, 0x00 ; swapped to lo | lo + + XLDR x0, [ptr+pos] ;Get next source vector + + add tmp, 32 + add vec_i, 1 + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xgft_hi, xgft_hi, x0 ;Lookup mul table of high nibble + vpshufb xgft_lo, xgft_lo, xtmpa ;Lookup mul table of low nibble + vpxor xgft_hi, xgft_hi, xgft_lo ;GF add high and low partials + vpxor xp, xp, xgft_hi ;xp += partial + + SLDR vec, vec_m + cmp vec_i, vec + jl .next_vect + + SLDR dest, dest_m + XSTR [dest+pos], xp + + add pos, 32 ;Loop on 32 bytes at a time + SLDR len, len_m + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-32 + jmp .loop32 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_VECT_DOT_PROD_AVX2, 04, 04, 0190 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_sse.asm new file mode 100644 index 000000000..9045fd826 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_dot_prod_sse.asm @@ -0,0 +1,303 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_vect_dot_prod_sse(len, vec, *g_tbls, **buffs, *dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_VECT_DOT_PROD_SSE _gf_vect_dot_prod_sse +%else + %define GF_VECT_DOT_PROD_SSE gf_vect_dot_prod_sse +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r9 + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +%ifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + + %define tmp r11 + %define tmp2 r10 + %define tmp3 r9 + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + + %define arg4 r12 ; must be saved and loaded + %define tmp r11 + %define tmp2 r10 + %define tmp3 rdi ; must be saved and loaded + %define return rax + %macro SLDR 2 + %endmacro + %define SSTR SLDR + %define PS 8 + %define frame_size 2*8 + %define arg(x) [rsp + frame_size + PS + PS*x] + + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + rex_push_reg r12 + push_reg rdi + end_prolog + mov arg4, arg(4) + %endmacro + + %macro FUNC_RESTORE 0 + pop rdi + pop r12 + %endmacro +%endif + +%ifidn __OUTPUT_FORMAT__, elf32 + +;;;================== High Address; +;;; arg4 +;;; arg3 +;;; arg2 +;;; arg1 +;;; arg0 +;;; return +;;;<================= esp of caller +;;; ebp +;;;<================= ebp = esp +;;; esi +;;; edi +;;; ebx +;;;<================= esp of callee +;;; +;;;================== Low Address; + + %define PS 4 + %define LOG_PS 2 + %define func(x) x: + %define arg(x) [ebp + PS*2 + PS*x] + + %define trans ecx ;trans is for the variables in stack + %define arg0 trans + %define arg0_m arg(0) + %define arg1 trans + %define arg1_m arg(1) + %define arg2 arg2_m + %define arg2_m arg(2) + %define arg3 ebx + %define arg4 trans + %define arg4_m arg(4) + %define tmp edx + %define tmp2 edi + %define tmp3 esi + %define return eax + %macro SLDR 2 ;; stack load/restore + mov %1, %2 + %endmacro + %define SSTR SLDR + + %macro FUNC_SAVE 0 + push ebp + mov ebp, esp + push esi + push edi + push ebx + mov arg3, arg(3) + %endmacro + + %macro FUNC_RESTORE 0 + pop ebx + pop edi + pop esi + mov esp, ebp + pop ebp + %endmacro + +%endif ; output formats + +%define len arg0 +%define vec arg1 +%define mul_array arg2 +%define src arg3 +%define dest arg4 + +%define vec_i tmp2 +%define ptr tmp3 +%define pos return + + %ifidn PS,4 ;32-bit code + %define vec_m arg1_m + %define len_m arg0_m + %define dest_m arg4_m + %endif + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +%ifidn PS,8 ;64-bit code + default rel + [bits 64] +%endif + +section .text + +%define xmask0f xmm5 +%define xgft_lo xmm4 +%define xgft_hi xmm3 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xp xmm2 + +align 16 +global GF_VECT_DOT_PROD_SSE:function +func(GF_VECT_DOT_PROD_SSE) + FUNC_SAVE + SLDR len, len_m + sub len, 16 + SSTR len_m, len + jl .return_fail + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + +.loop16: + pxor xp, xp + mov tmp, mul_array + xor vec_i, vec_i + +.next_vect: + + mov ptr, [src+vec_i*PS] + movdqu xgft_lo, [tmp] ;Load array Cx{00}, Cx{01}, ..., Cx{0f} + movdqu xgft_hi, [tmp+16] ; " Cx{00}, Cx{10}, ..., Cx{f0} + XLDR x0, [ptr+pos] ;Get next source vector + + add tmp, 32 + add vec_i, 1 + + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + + pshufb xgft_hi, x0 ;Lookup mul table of high nibble + pshufb xgft_lo, xtmpa ;Lookup mul table of low nibble + pxor xgft_hi, xgft_lo ;GF add high and low partials + pxor xp, xgft_hi ;xp += partial + + SLDR vec, vec_m + cmp vec_i, vec + jl .next_vect + + SLDR dest, dest_m + XSTR [dest+pos], xp + + add pos, 16 ;Loop on 16 bytes at a time + SLDR len, len_m + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + jmp .loop16 ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 + +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_VECT_DOT_PROD_SSE, 00, 04, 0060 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_avx.asm new file mode 100644 index 000000000..531701a2a --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_avx.asm @@ -0,0 +1,223 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_vect_mad_avx(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_VECT_MAD_AVX _gf_vect_mad_avx +%else + %define GF_VECT_MAD_AVX gf_vect_mad_avx +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define return rax + %define return.w eax + %define PS 8 + %define stack_size 16*3 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + vmovdqa [rsp+16*0],xmm6 + vmovdqa [rsp+16*1],xmm7 + vmovdqa [rsp+16*2],xmm8 + save_reg r12, 3*16 + 0*8 + save_reg r15, 3*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp+16*0] + vmovdqa xmm7, [rsp+16*1] + vmovdqa xmm8, [rsp+16*2] + mov r12, [rsp + 3*16 + 0*8] + mov r15, [rsp + 3*16 + 1*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_vect_mad_avx(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest arg5 +%define pos return +%define pos.w return.w + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f xmm8 +%define xgft_lo xmm7 +%define xgft_hi xmm6 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph xmm2 +%define xtmpl xmm3 +%define xd xmm4 +%define xtmpd xmm5 + +align 16 +global GF_VECT_MAD_AVX:function +func(GF_VECT_MAD_AVX) + FUNC_SAVE + sub len, 16 + jl .return_fail + + xor pos, pos + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + + sal vec_i, 5 ;Multiply by 32 + vmovdqu xgft_lo, [vec_i+mul_array] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + vmovdqu xgft_hi, [vec_i+mul_array+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + + XLDR xtmpd, [dest+len] ;backup the last 16 bytes in dest + +.loop16: + XLDR xd, [dest+pos] ;Get next dest vector +.loop16_overlap: + XLDR x0, [src+pos] ;Get next source vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xtmph, xgft_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xtmpl ;GF add high and low partials + vpxor xd, xd, xtmph ;xd += partial + + XSTR [dest+pos], xd + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + vmovdqa xd, xtmpd ;Restore xd + jmp .loop16_overlap ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 + +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_VECT_MAD_AVX, 02, 00, 0201 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_avx2.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_avx2.asm new file mode 100644 index 000000000..81b10175d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_avx2.asm @@ -0,0 +1,233 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_vect_mad_avx2(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_VECT_MAD_AVX2 _gf_vect_mad_avx2 +%else + %define GF_VECT_MAD_AVX2 gf_vect_mad_avx2 +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 ; must be saved and loaded + %define arg5 r15 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + %define PS 8 + %define stack_size 16*3 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + + %macro FUNC_SAVE 0 + sub rsp, stack_size + vmovdqa [rsp+16*0],xmm6 + vmovdqa [rsp+16*1],xmm7 + vmovdqa [rsp+16*2],xmm8 + save_reg r12, 3*16 + 0*8 + save_reg r15, 3*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp+16*0] + vmovdqa xmm7, [rsp+16*1] + vmovdqa xmm8, [rsp+16*2] + mov r12, [rsp + 3*16 + 0*8] + mov r15, [rsp + 3*16 + 1*8] + add rsp, stack_size + %endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + + %define tmp r11 + %define tmp.w r11d + %define tmp.b r11b + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + + +;;; gf_vect_mad_avx2(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest arg5 +%define pos return +%define pos.w return.w + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR vmovdqu + %define XSTR vmovdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa + %else + %define XLDR vmovntdqa + %define XSTR vmovntdq + %endif +%endif + + +default rel + +[bits 64] +section .text + +%define xmask0f ymm8 +%define xmask0fx xmm8 +%define xgft_lo ymm7 +%define xgft_hi ymm6 + +%define x0 ymm0 +%define xtmpa ymm1 +%define xtmph ymm2 +%define xtmpl ymm3 +%define xd ymm4 +%define xtmpd ymm5 + +align 16 +global GF_VECT_MAD_AVX2:function +func(GF_VECT_MAD_AVX2) + FUNC_SAVE + sub len, 32 + jl .return_fail + xor pos, pos + mov tmp.b, 0x0f + vpinsrb xmask0fx, xmask0fx, tmp.w, 0 + vpbroadcastb xmask0f, xmask0fx ;Construct mask 0x0f0f0f... + + sal vec_i, 5 ;Multiply by 32 + vmovdqu xgft_lo, [vec_i+mul_array] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + vperm2i128 xgft_hi, xgft_lo, xgft_lo, 0x11 ; swapped to hi | hi + vperm2i128 xgft_lo, xgft_lo, xgft_lo, 0x00 ; swapped to lo | lo + + XLDR xtmpd, [dest+len] ;backup the last 32 bytes in dest + +.loop32: + XLDR xd, [dest+pos] ;Get next dest vector +.loop32_overlap: + XLDR x0, [src+pos] ;Get next source vector + + vpand xtmpa, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + + vpshufb xtmph, xgft_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmpl, xgft_lo, xtmpa ;Lookup mul table of low nibble + vpxor xtmph, xtmph, xtmpl ;GF add high and low partials + vpxor xd, xd, xtmph ;xd += partial + + XSTR [dest+pos], xd + add pos, 32 ;Loop on 32 bytes at a time + cmp pos, len + jle .loop32 + + lea tmp, [len + 32] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-32 + vmovdqa xd, xtmpd ;Restore xd + jmp .loop32_overlap ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_VECT_MAD_AVX2, 04, 00, 0202 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_sse.asm new file mode 100644 index 000000000..d9484d2d9 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mad_sse.asm @@ -0,0 +1,224 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_vect_mad_sse(len, vec, vec_i, mul_array, src, dest); +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_VECT_MAD_SSE _gf_vect_mad_sse +%else + %define GF_VECT_MAD_SSE gf_vect_mad_sse +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg0.w ecx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define arg4 r12 + %define arg5 r15 + %define tmp r11 + %define return rax + %define return.w eax + %define PS 8 + %define stack_size 16*3 + 3*8 + %define arg(x) [rsp + stack_size + PS + PS*x] + %define func(x) proc_frame x + +%macro FUNC_SAVE 0 + sub rsp, stack_size + movdqa [rsp+16*0],xmm6 + movdqa [rsp+16*1],xmm7 + movdqa [rsp+16*2],xmm8 + save_reg r12, 3*16 + 0*8 + save_reg r15, 3*16 + 1*8 + end_prolog + mov arg4, arg(4) + mov arg5, arg(5) +%endmacro + +%macro FUNC_RESTORE 0 + movdqa xmm6, [rsp+16*0] + movdqa xmm7, [rsp+16*1] + movdqa xmm8, [rsp+16*2] + mov r12, [rsp + 3*16 + 0*8] + mov r15, [rsp + 3*16 + 1*8] + add rsp, stack_size +%endmacro + +%elifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg0.w edi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define return.w eax + + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +;;; gf_vect_mad_sse(len, vec, vec_i, mul_array, src, dest) +%define len arg0 +%define len.w arg0.w +%define vec arg1 +%define vec_i arg2 +%define mul_array arg3 +%define src arg4 +%define dest arg5 +%define pos return +%define pos.w return.w + +%ifndef EC_ALIGNED_ADDR +;;; Use Un-aligned load/store + %define XLDR movdqu + %define XSTR movdqu +%else +;;; Use Non-temporal load/stor + %ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa + %else + %define XLDR movntdqa + %define XSTR movntdq + %endif +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm8 +%define xgft_lo xmm7 +%define xgft_hi xmm6 + +%define x0 xmm0 +%define xtmpa xmm1 +%define xtmph xmm2 +%define xtmpl xmm3 +%define xd xmm4 +%define xtmpd xmm5 + + +align 16 +global GF_VECT_MAD_SSE:function +func(GF_VECT_MAD_SSE) + FUNC_SAVE + sub len, 16 + jl .return_fail + + xor pos, pos + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + sal vec_i, 5 ;Multiply by 32 + movdqu xgft_lo, [vec_i+mul_array] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + movdqu xgft_hi, [vec_i+mul_array+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + + XLDR xtmpd, [dest+len] ;backup the last 16 bytes in dest + +.loop16: + XLDR xd, [dest+pos] ;Get next dest vector +.loop16_overlap: + XLDR x0, [src+pos] ;Get next source vector + movdqa xtmph, xgft_hi ;Reload const array registers + movdqa xtmpl, xgft_lo + movdqa xtmpa, x0 ;Keep unshifted copy of src + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand xtmpa, xmask0f ;Mask low src nibble in bits 4-0 + pshufb xtmph, x0 ;Lookup mul table of high nibble + pshufb xtmpl, xtmpa ;Lookup mul table of low nibble + pxor xtmph, xtmpl ;GF add high and low partials + + pxor xd, xtmph + XSTR [dest+pos], xd ;Store result + + add pos, 16 ;Loop on 16 bytes at a time + cmp pos, len + jle .loop16 + + lea tmp, [len + 16] + cmp pos, tmp + je .return_pass + + ;; Tail len + mov pos, len ;Overlapped offset length-16 + movdqa xd, xtmpd ;Restore xd + jmp .loop16_overlap ;Do one more overlap pass + +.return_pass: + mov return, 0 + FUNC_RESTORE + ret + +.return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 + +mask0f: ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_VECT_MAD_SSE, 00, 00, 0200 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul.h b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul.h new file mode 100644 index 000000000..42aa0a456 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul.h @@ -0,0 +1,148 @@ +/********************************************************************** + Copyright(c) 2011-2015 Intel Corporation All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**********************************************************************/ + + +#ifndef _GF_VECT_MUL_H +#define _GF_VECT_MUL_H + +/** + * @file gf_vect_mul.h + * @brief Interface to functions for vector (block) multiplication in GF(2^8). + * + * This file defines the interface to routines used in fast RAID rebuild and + * erasure codes. + */ + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @brief GF(2^8) vector multiply by constant. + * + * Does a GF(2^8) vector multiply b = Ca where a and b are arrays and C + * is a single field element in GF(2^8). Can be used for RAID6 rebuild + * and partial write functions. Function requires pre-calculation of a + * 32-element constant array based on constant C. gftbl(C) = {C{00}, + * C{01}, C{02}, ... , C{0f} }, {C{00}, C{10}, C{20}, ... , C{f0} }. Len + * and src must be aligned to 32B. + * @requires SSE4.1 + * + * @param len Length of vector in bytes. Must be aligned to 32B. + * @param gftbl Pointer to 32-byte array of pre-calculated constants based on C. + * @param src Pointer to src data array. Must be aligned to 32B. + * @param dest Pointer to destination data array. Must be aligned to 32B. + * @returns 0 pass, other fail + */ + +int gf_vect_mul_sse(int len, unsigned char *gftbl, void *src, void *dest); + + + /** + * @brief GF(2^8) vector multiply by constant. + * + * Does a GF(2^8) vector multiply b = Ca where a and b are arrays and C + * is a single field element in GF(2^8). Can be used for RAID6 rebuild + * and partial write functions. Function requires pre-calculation of a + * 32-element constant array based on constant C. gftbl(C) = {C{00}, + * C{01}, C{02}, ... , C{0f} }, {C{00}, C{10}, C{20}, ... , C{f0} }. Len + * and src must be aligned to 32B. + * @requires AVX + * + * @param len Length of vector in bytes. Must be aligned to 32B. + * @param gftbl Pointer to 32-byte array of pre-calculated constants based on C. + * @param src Pointer to src data array. Must be aligned to 32B. + * @param dest Pointer to destination data array. Must be aligned to 32B. + * @returns 0 pass, other fail + */ + +int gf_vect_mul_avx(int len, unsigned char *gftbl, void *src, void *dest); + + +/** + * @brief GF(2^8) vector multiply by constant, runs appropriate version. + * + * Does a GF(2^8) vector multiply b = Ca where a and b are arrays and C + * is a single field element in GF(2^8). Can be used for RAID6 rebuild + * and partial write functions. Function requires pre-calculation of a + * 32-element constant array based on constant C. gftbl(C) = {C{00}, + * C{01}, C{02}, ... , C{0f} }, {C{00}, C{10}, C{20}, ... , C{f0} }. + * Len and src must be aligned to 32B. + * + * This function determines what instruction sets are enabled + * and selects the appropriate version at runtime. + * + * @param len Length of vector in bytes. Must be aligned to 32B. + * @param gftbl Pointer to 32-byte array of pre-calculated constants based on C. + * @param src Pointer to src data array. Must be aligned to 32B. + * @param dest Pointer to destination data array. Must be aligned to 32B. + * @returns 0 pass, other fail + */ + +int gf_vect_mul(int len, unsigned char *gftbl, void *src, void *dest); + + +/** + * @brief Initialize 32-byte constant array for GF(2^8) vector multiply + * + * Calculates array {C{00}, C{01}, C{02}, ... , C{0f} }, {C{00}, C{10}, + * C{20}, ... , C{f0} } as required by other fast vector multiply + * functions. + * @param c Constant input. + * @param gftbl Table output. + */ + +void gf_vect_mul_init(unsigned char c, unsigned char* gftbl); + + +/** + * @brief GF(2^8) vector multiply by constant, runs baseline version. + * + * Does a GF(2^8) vector multiply b = Ca where a and b are arrays and C + * is a single field element in GF(2^8). Can be used for RAID6 rebuild + * and partial write functions. Function requires pre-calculation of a + * 32-element constant array based on constant C. gftbl(C) = {C{00}, + * C{01}, C{02}, ... , C{0f} }, {C{00}, C{10}, C{20}, ... , C{f0} }. Len + * and src must be aligned to 32B. + * + * @param len Length of vector in bytes. Must be aligned to 32B. + * @param a Pointer to 32-byte array of pre-calculated constants based on C. + * only use 2nd element is used. + * @param src Pointer to src data array. Must be aligned to 32B. + * @param dest Pointer to destination data array. Must be aligned to 32B. + */ + +void gf_vect_mul_base(int len, unsigned char *a, unsigned char *src, + unsigned char *dest); + +#ifdef __cplusplus +} +#endif + +#endif //_GF_VECT_MUL_H diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul_avx.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul_avx.asm new file mode 100644 index 000000000..80155ba0e --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul_avx.asm @@ -0,0 +1,189 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_vect_mul_avx(len, mul_array, src, dest) +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_VECT_MUL_AVX _gf_vect_mul_avx +%else + %define GF_VECT_MUL_AVX gf_vect_mul_avx +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE + +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE + +%elifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define return rax + %define stack_size 5*16 + 8 ; must be an odd multiple of 8 + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm13, 2*16 + save_xmm128 xmm14, 3*16 + save_xmm128 xmm15, 4*16 + end_prolog + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + vmovdqa xmm13, [rsp + 2*16] + vmovdqa xmm14, [rsp + 3*16] + vmovdqa xmm15, [rsp + 4*16] + add rsp, stack_size + %endmacro + +%endif + + +%define len arg0 +%define mul_array arg1 +%define src arg2 +%define dest arg3 +%define pos return + + +;;; Use Non-temporal load/stor +%ifdef NO_NT_LDST + %define XLDR vmovdqa + %define XSTR vmovdqa +%else + %define XLDR vmovntdqa + %define XSTR vmovntdq +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft_lo xmm14 +%define xgft_hi xmm13 + +%define x0 xmm0 +%define xtmp1a xmm1 +%define xtmp1b xmm2 +%define xtmp1c xmm3 +%define x1 xmm4 +%define xtmp2a xmm5 +%define xtmp2b xmm6 +%define xtmp2c xmm7 + +align 16 +global GF_VECT_MUL_AVX:function +func(GF_VECT_MUL_AVX) + FUNC_SAVE + mov pos, 0 + vmovdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + vmovdqu xgft_lo, [mul_array] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + vmovdqu xgft_hi, [mul_array+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + +loop32: + XLDR x0, [src+pos] ;Get next source vector + XLDR x1, [src+pos+16] ;Get next source vector + 16B ahead + add pos, 32 ;Loop on 16 bytes at a time + cmp pos, len + vpand xtmp1a, x0, xmask0f ;Mask low src nibble in bits 4-0 + vpand xtmp2a, x1, xmask0f + vpsraw x0, x0, 4 ;Shift to put high nibble into bits 4-0 + vpsraw x1, x1, 4 + vpand x0, x0, xmask0f ;Mask high src nibble in bits 4-0 + vpand x1, x1, xmask0f + vpshufb xtmp1b, xgft_hi, x0 ;Lookup mul table of high nibble + vpshufb xtmp1c, xgft_lo, xtmp1a ;Lookup mul table of low nibble + vpshufb xtmp2b, xgft_hi, x1 ;Lookup mul table of high nibble + vpshufb xtmp2c, xgft_lo, xtmp2a ;Lookup mul table of low nibble + vpxor xtmp1b, xtmp1b, xtmp1c ;GF add high and low partials + vpxor xtmp2b, xtmp2b, xtmp2c + XSTR [dest+pos-32], xtmp1b ;Store result + XSTR [dest+pos-16], xtmp2b ;Store +16B result + jl loop32 + + +return_pass: + FUNC_RESTORE + sub pos, len + ret + +return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +section .data + +align 16 + +mask0f: +ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_VECT_MUL_AVX, 01, 02, 0036 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul_sse.asm b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul_sse.asm new file mode 100644 index 000000000..30d9acea7 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/gf_vect_mul_sse.asm @@ -0,0 +1,195 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2015 Intel Corporation All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; * Neither the name of Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; +;;; gf_vect_mul_sse(len, mul_array, src, dest) +;;; + +%ifidn __OUTPUT_FORMAT__, macho64 + %define GF_VECT_MUL_SSE _gf_vect_mul_sse +%else + %define GF_VECT_MUL_SSE gf_vect_mul_sse +%endif + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE + +%elifidn __OUTPUT_FORMAT__, macho64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define return rax + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE + +%elifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define return rax + %define stack_size 5*16 + 8 ; must be an odd multiple of 8 + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + save_xmm128 xmm6, 0*16 + save_xmm128 xmm7, 1*16 + save_xmm128 xmm13, 2*16 + save_xmm128 xmm14, 3*16 + save_xmm128 xmm15, 4*16 + end_prolog + %endmacro + + %macro FUNC_RESTORE 0 + movdqa xmm6, [rsp + 0*16] + movdqa xmm7, [rsp + 1*16] + movdqa xmm13, [rsp + 2*16] + movdqa xmm14, [rsp + 3*16] + movdqa xmm15, [rsp + 4*16] + add rsp, stack_size + %endmacro + +%endif + + +%define len arg0 +%define mul_array arg1 +%define src arg2 +%define dest arg3 +%define pos return + + +;;; Use Non-temporal load/stor +%ifdef NO_NT_LDST + %define XLDR movdqa + %define XSTR movdqa +%else + %define XLDR movntdqa + %define XSTR movntdq +%endif + +default rel + +[bits 64] +section .text + +%define xmask0f xmm15 +%define xgft_lo xmm14 +%define xgft_hi xmm13 + +%define x0 xmm0 +%define xtmp1a xmm1 +%define xtmp1b xmm2 +%define xtmp1c xmm3 +%define x1 xmm4 +%define xtmp2a xmm5 +%define xtmp2b xmm6 +%define xtmp2c xmm7 + + +align 16 +global GF_VECT_MUL_SSE:function +func(GF_VECT_MUL_SSE) + FUNC_SAVE + mov pos, 0 + movdqa xmask0f, [mask0f] ;Load mask of lower nibble in each byte + movdqu xgft_lo, [mul_array] ;Load array Cx{00}, Cx{01}, Cx{02}, ... + movdqu xgft_hi, [mul_array+16] ; " Cx{00}, Cx{10}, Cx{20}, ... , Cx{f0} + +loop32: + XLDR x0, [src+pos] ;Get next source vector + XLDR x1, [src+pos+16] ;Get next source vector + 16B ahead + movdqa xtmp1b, xgft_hi ;Reload const array registers + movdqa xtmp1c, xgft_lo + movdqa xtmp2b, xgft_hi + movdqa xtmp2c, xgft_lo + movdqa xtmp1a, x0 ;Keep unshifted copy of src + movdqa xtmp2a, x1 + psraw x0, 4 ;Shift to put high nibble into bits 4-0 + psraw x1, 4 + pand xtmp1a, xmask0f ;Mask low src nibble in bits 4-0 + pand xtmp2a, xmask0f + pand x0, xmask0f ;Mask high src nibble in bits 4-0 + pand x1, xmask0f + pshufb xtmp1b, x0 ;Lookup mul table of high nibble + pshufb xtmp1c, xtmp1a ;Lookup mul table of low nibble + pshufb xtmp2b, x1 + pshufb xtmp2c, xtmp2a + pxor xtmp1b, xtmp1c ;GF add high and low partials + pxor xtmp2b, xtmp2c + XSTR [dest+pos], xtmp1b ;Store result + XSTR [dest+pos+16], xtmp2b ;Store +16B result + add pos, 32 ;Loop on 32 bytes at at time + cmp pos, len + jl loop32 + + +return_pass: + sub pos, len + FUNC_RESTORE + ret + +return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +section .data + +align 16 +mask0f: +ddq 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f + +%macro slversion 4 +global %1_slver_%2%3%4 +global %1_slver +%1_slver: +%1_slver_%2%3%4: + dw 0x%4 + db 0x%3, 0x%2 +%endmacro +;;; func core, ver, snum +slversion GF_VECT_MUL_SSE, 00, 02, 0034 diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/stdint.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/stdint.go new file mode 100644 index 000000000..72f6e86ae --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/stdint.go @@ -0,0 +1,38 @@ +/* + * Minimalist Object Storage, (C) 2014 Minio, Inc. + * + * 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 erasure + +// +// int sizeInt() +// { +// return sizeof(int); +// } +import "C" +import "unsafe" + +var ( + // See http://golang.org/ref/spec#Numeric_types + sizeInt = int(C.sizeInt()) + // SizeInt8 is the byte size of a int8. + sizeInt8 = int(unsafe.Sizeof(int8(0))) + // SizeInt16 is the byte size of a int16. + sizeInt16 = int(unsafe.Sizeof(int16(0))) + // SizeInt32 is the byte size of a int32. + sizeInt32 = int(unsafe.Sizeof(int32(0))) + // SizeInt64 is the byte size of a int64. + sizeInt64 = int(unsafe.Sizeof(int64(0))) +) diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/vandermonde_test.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/vandermonde_test.go new file mode 100644 index 000000000..490830557 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/erasure/vandermonde_test.go @@ -0,0 +1,66 @@ +/* + * Minimalist Object Storage, (C) 2014 Minio, Inc. + * + * 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 erasure + +import ( + "bytes" + + . "gopkg.in/check.v1" +) + +func corruptChunks(chunks [][]byte, errorIndex []int) [][]byte { + for _, err := range errorIndex { + chunks[err] = nil + } + return chunks +} + +func (s *MySuite) TestVanderMondeEncodeDecodeFailure(c *C) { + ep, _ := ValidateParams(k, m, Vandermonde) + + data := []byte("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.") + + e := NewErasure(ep) + chunks, err := e.Encode(data) + c.Assert(err, IsNil) + + errorIndex := []int{0, 3, 5, 9, 11, 13} + chunks = corruptChunks(chunks, errorIndex) + + _, err = e.Decode(chunks, len(data)) + c.Assert(err, Not(IsNil)) +} + +func (s *MySuite) TestVanderMondeEncodeDecodeSuccess(c *C) { + ep, _ := ValidateParams(k, m, Vandermonde) + + data := []byte("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.") + + e := NewErasure(ep) + chunks, err := e.Encode(data) + c.Assert(err, IsNil) + + errorIndex := []int{0, 3, 5, 9, 13} + chunks = corruptChunks(chunks, errorIndex) + + recoveredData, err := e.Decode(chunks, len(data)) + c.Assert(err, IsNil) + + if !bytes.Equal(recoveredData, data) { + c.Fatalf("Recovered data mismatches with original data") + } +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/.gitignore b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/.gitignore new file mode 100644 index 000000000..daf913b1b --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/LICENSE b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/LICENSE new file mode 100644 index 000000000..e06d20818 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/LICENSE @@ -0,0 +1,202 @@ +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/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/README.md b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/README.md new file mode 100644 index 000000000..d7391ea49 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/README.md @@ -0,0 +1,2 @@ +# iodine +Iodine is an error logging framework for tracing errors. diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/iodine.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/iodine.go new file mode 100644 index 000000000..f1eead9f6 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/iodine.go @@ -0,0 +1,201 @@ +/* + * Iodine, (C) 2015 Minio, Inc. + * + * 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 iodine + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "path" + "reflect" + "runtime" + "strconv" + "strings" + "sync" +) + +// WrappedError is the iodine error which contains a pointer to the original error +// and stack traces. +type Error struct { + EmbeddedError error `json:"-"` + ErrorMessage string + ErrorType string + + Stack []StackEntry +} + +// StackEntry contains the entry in the stack trace +type StackEntry struct { + Host string + File string + Line int + Data map[string]string +} + +var gopath string + +var globalState = struct { + sync.RWMutex + m map[string]string +}{m: make(map[string]string)} + +// SetGlobalState - set global state +func SetGlobalState(key, value string) { + globalState.Lock() + globalState.m[key] = value + globalState.Unlock() +} + +// ClearGlobalState - clear info in globalState struct +func ClearGlobalState() { + globalState.Lock() + for k := range globalState.m { + delete(globalState.m, k) + } + globalState.Unlock() +} + +// GetGlobalState - get map from globalState struct +func GetGlobalState() map[string]string { + result := make(map[string]string) + globalState.RLock() + for k, v := range globalState.m { + result[k] = v + } + globalState.RUnlock() + return result +} + +// GetGlobalStateKey - get value for key from globalState struct +func GetGlobalStateKey(k string) string { + result, ok := globalState.m[k] + if !ok { + return "" + } + return result +} + +// Error - instantiate an error, turning it into an iodine error. +// Adds an initial stack trace. +func New(err error, data map[string]string) error { + if err != nil { + entry := createStackEntry() + var newErr Error + + // check if error is wrapped + switch typedError := err.(type) { + case Error: + { + newErr = typedError + } + default: + { + newErr = Error{ + EmbeddedError: err, + ErrorMessage: err.Error(), + ErrorType: reflect.TypeOf(err).String(), + Stack: []StackEntry{}, + } + } + } + for k, v := range data { + entry.Data[k] = v + } + newErr.Stack = append(newErr.Stack, entry) + return newErr + } + return nil +} + +// createStackEntry - create stack entries +func createStackEntry() StackEntry { + host, _ := os.Hostname() + _, file, line, _ := runtime.Caller(2) + file = strings.TrimPrefix(file, gopath) // trim gopath from file + + data := GetGlobalState() + for k, v := range getSystemData() { + data[k] = v + } + + entry := StackEntry{ + Host: host, + File: file, + Line: line, + Data: data, + } + return entry +} + +func getSystemData() map[string]string { + host, err := os.Hostname() + if err != nil { + host = "" + } + memstats := &runtime.MemStats{} + runtime.ReadMemStats(memstats) + return map[string]string{ + "sys.host": host, + "sys.os": runtime.GOOS, + "sys.arch": runtime.GOARCH, + "sys.go": runtime.Version(), + "sys.cpus": strconv.Itoa(runtime.NumCPU()), + "sys.mem.used": strconv.FormatUint(memstats.Alloc, 10), + "sys.mem.allocated": strconv.FormatUint(memstats.TotalAlloc, 10), + "sys.mem.heap.used": strconv.FormatUint(memstats.HeapAlloc, 10), + "sys.mem.heap.allocated": strconv.FormatUint(memstats.HeapSys, 10), + } +} + +// Annotate an error with a stack entry and returns itself +//func (err *WrappedError) Annotate(info map[string]string) *WrappedError { +// entry := createStackEntry() +// for k, v := range info { +// entry.Data[k] = v +// } +// err.Stack = append(err.Stack, entry) +// return err +//} + +// EmitJSON writes JSON output for the error +func (err Error) EmitJSON() ([]byte, error) { + return json.Marshal(err) +} + +// EmitHumanReadable returns a human readable error message +func (err Error) EmitHumanReadable() string { + var errorBuffer bytes.Buffer + fmt.Fprintln(&errorBuffer, err.ErrorMessage) + for i, entry := range err.Stack { + fmt.Fprintln(&errorBuffer, "-", i, entry.Host+":"+entry.File+":"+strconv.Itoa(entry.Line), entry.Data) + } + return string(errorBuffer.Bytes()) +} + +// Emits the original error message +func (err Error) Error() string { + return err.EmitHumanReadable() +} + +func init() { + _, iodineFile, _, _ := runtime.Caller(0) + iodineFile = path.Dir(iodineFile) // trim iodine.go + iodineFile = path.Dir(iodineFile) // trim iodine + iodineFile = path.Dir(iodineFile) // trim minio-io + gopath = path.Dir(iodineFile) + "/" // trim github.com +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/iodine_test.go b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/iodine_test.go new file mode 100644 index 000000000..9b8ddc0c5 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/minio-io/iodine/iodine_test.go @@ -0,0 +1,97 @@ +/* + * Iodine, (C) 2015 Minio, Inc. + * + * 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 iodine + +import ( + "encoding/json" + "errors" + "testing" +) + +func TestIodine(t *testing.T) { + iodineError := New(errors.New("Hello"), nil) + iodineError = New(iodineError, nil) + iodineError = New(iodineError, nil) + iodineError = New(iodineError, nil) + switch typedError := iodineError.(type) { + case Error: + { + if len(typedError.Stack) != 4 { + t.Fail() + } + _, err := json.MarshalIndent(typedError, "", " ") + if err != nil { + t.Fail() + } + } + default: + { + t.Fail() + } + } +} + +func TestState(t *testing.T) { + SetGlobalState("hello", "world") + result := GetGlobalStateKey("hello") + if result != "world" { + t.Error("global state not set: hello->world") + t.Fail() + } + ClearGlobalState() + if len(GetGlobalState()) != 0 { + t.Fail() + } + SetGlobalState("foo", "bar") + err := New(errors.New("a simple error"), nil) + switch typedError := err.(type) { + case Error: + { + if res, ok := typedError.Stack[0].Data["foo"]; ok { + if res != "bar" { + t.Error("global state not set: foo->bar") + } + } else { + t.Fail() + } + typedError = New(typedError, map[string]string{"foo2": "bar2"}).(Error) + if res, ok := typedError.Stack[0].Data["foo"]; ok { + if res != "bar" { + t.Error("annotate should not modify previous data entries") + } + } else { + t.Error("annotate should not remove previous data entries") + } + if res, ok := typedError.Stack[1].Data["foo"]; ok { + if res != "bar" { + t.Error("global state should set value properly in annotate") + } + } else { + t.Error("global state should set key properly in annotate") + } + if res, ok := typedError.Stack[1].Data["foo2"]; ok { + if res != "bar2" { + // typedError = Error(typedError, nil).(WrappedError) + t.Error("foo2 -> bar should be set") + } + } else { + // typedError = Error(typedError, nil).(WrappedError) + t.Error("foo2 should be set") + } + } + } +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/.gitignore b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/.gitignore new file mode 100644 index 000000000..00268614f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/LICENSE.md b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/LICENSE.md new file mode 100644 index 000000000..219994581 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/LICENSE.md @@ -0,0 +1,23 @@ +objx - by Mat Ryer and Tyler Bunnell + +The MIT License (MIT) + +Copyright (c) 2014 Stretchr, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/README.md b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/README.md new file mode 100644 index 000000000..4aa180687 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/README.md @@ -0,0 +1,3 @@ +# objx + + * Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx) diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/accessors.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/accessors.go new file mode 100644 index 000000000..721bcac79 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/accessors.go @@ -0,0 +1,179 @@ +package objx + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +// arrayAccesRegexString is the regex used to extract the array number +// from the access path +const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$` + +// arrayAccesRegex is the compiled arrayAccesRegexString +var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString) + +// Get gets the value using the specified selector and +// returns it inside a new Obj object. +// +// If it cannot find the value, Get will return a nil +// value inside an instance of Obj. +// +// Get can only operate directly on map[string]interface{} and []interface. +// +// Example +// +// To access the title of the third chapter of the second book, do: +// +// o.Get("books[1].chapters[2].title") +func (m Map) Get(selector string) *Value { + rawObj := access(m, selector, nil, false, false) + return &Value{data: rawObj} +} + +// Set sets the value using the specified selector and +// returns the object on which Set was called. +// +// Set can only operate directly on map[string]interface{} and []interface +// +// Example +// +// To set the title of the third chapter of the second book, do: +// +// o.Set("books[1].chapters[2].title","Time to Go") +func (m Map) Set(selector string, value interface{}) Map { + access(m, selector, value, true, false) + return m +} + +// access accesses the object using the selector and performs the +// appropriate action. +func access(current, selector, value interface{}, isSet, panics bool) interface{} { + + switch selector.(type) { + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: + + if array, ok := current.([]interface{}); ok { + index := intFromInterface(selector) + + if index >= len(array) { + if panics { + panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array))) + } + return nil + } + + return array[index] + } + + return nil + + case string: + + selStr := selector.(string) + selSegs := strings.SplitN(selStr, PathSeparator, 2) + thisSel := selSegs[0] + index := -1 + var err error + + // https://github.com/stretchr/objx/issues/12 + if strings.Contains(thisSel, "[") { + + arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel) + + if len(arrayMatches) > 0 { + + // Get the key into the map + thisSel = arrayMatches[1] + + // Get the index into the array at the key + index, err = strconv.Atoi(arrayMatches[2]) + + if err != nil { + // This should never happen. If it does, something has gone + // seriously wrong. Panic. + panic("objx: Array index is not an integer. Must use array[int].") + } + + } + } + + if curMap, ok := current.(Map); ok { + current = map[string]interface{}(curMap) + } + + // get the object in question + switch current.(type) { + case map[string]interface{}: + curMSI := current.(map[string]interface{}) + if len(selSegs) <= 1 && isSet { + curMSI[thisSel] = value + return nil + } else { + current = curMSI[thisSel] + } + default: + current = nil + } + + if current == nil && panics { + panic(fmt.Sprintf("objx: '%v' invalid on object.", selector)) + } + + // do we need to access the item of an array? + if index > -1 { + if array, ok := current.([]interface{}); ok { + if index < len(array) { + current = array[index] + } else { + if panics { + panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array))) + } + current = nil + } + } + } + + if len(selSegs) > 1 { + current = access(current, selSegs[1], value, isSet, panics) + } + + } + + return current + +} + +// intFromInterface converts an interface object to the largest +// representation of an unsigned integer using a type switch and +// assertions +func intFromInterface(selector interface{}) int { + var value int + switch selector.(type) { + case int: + value = selector.(int) + case int8: + value = int(selector.(int8)) + case int16: + value = int(selector.(int16)) + case int32: + value = int(selector.(int32)) + case int64: + value = int(selector.(int64)) + case uint: + value = int(selector.(uint)) + case uint8: + value = int(selector.(uint8)) + case uint16: + value = int(selector.(uint16)) + case uint32: + value = int(selector.(uint32)) + case uint64: + value = int(selector.(uint64)) + default: + panic("objx: array access argument is not an integer type (this should never happen)") + } + + return value +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/accessors_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/accessors_test.go new file mode 100644 index 000000000..ce5d8e4aa --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/accessors_test.go @@ -0,0 +1,145 @@ +package objx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAccessorsAccessGetSingleField(t *testing.T) { + + current := map[string]interface{}{"name": "Tyler"} + assert.Equal(t, "Tyler", access(current, "name", nil, false, true)) + +} +func TestAccessorsAccessGetDeep(t *testing.T) { + + current := map[string]interface{}{"name": map[string]interface{}{"first": "Tyler", "last": "Bunnell"}} + assert.Equal(t, "Tyler", access(current, "name.first", nil, false, true)) + assert.Equal(t, "Bunnell", access(current, "name.last", nil, false, true)) + +} +func TestAccessorsAccessGetDeepDeep(t *testing.T) { + + current := map[string]interface{}{"one": map[string]interface{}{"two": map[string]interface{}{"three": map[string]interface{}{"four": 4}}}} + assert.Equal(t, 4, access(current, "one.two.three.four", nil, false, true)) + +} +func TestAccessorsAccessGetInsideArray(t *testing.T) { + + current := map[string]interface{}{"names": []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}} + assert.Equal(t, "Tyler", access(current, "names[0].first", nil, false, true)) + assert.Equal(t, "Bunnell", access(current, "names[0].last", nil, false, true)) + assert.Equal(t, "Capitol", access(current, "names[1].first", nil, false, true)) + assert.Equal(t, "Bollocks", access(current, "names[1].last", nil, false, true)) + + assert.Panics(t, func() { + access(current, "names[2]", nil, false, true) + }) + assert.Nil(t, access(current, "names[2]", nil, false, false)) + +} + +func TestAccessorsAccessGetFromArrayWithInt(t *testing.T) { + + current := []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}} + one := access(current, 0, nil, false, false) + two := access(current, 1, nil, false, false) + three := access(current, 2, nil, false, false) + + assert.Equal(t, "Tyler", one.(map[string]interface{})["first"]) + assert.Equal(t, "Capitol", two.(map[string]interface{})["first"]) + assert.Nil(t, three) + +} + +func TestAccessorsGet(t *testing.T) { + + current := New(map[string]interface{}{"name": "Tyler"}) + assert.Equal(t, "Tyler", current.Get("name").data) + +} + +func TestAccessorsAccessSetSingleField(t *testing.T) { + + current := map[string]interface{}{"name": "Tyler"} + access(current, "name", "Mat", true, false) + assert.Equal(t, current["name"], "Mat") + + access(current, "age", 29, true, true) + assert.Equal(t, current["age"], 29) + +} + +func TestAccessorsAccessSetSingleFieldNotExisting(t *testing.T) { + + current := map[string]interface{}{} + access(current, "name", "Mat", true, false) + assert.Equal(t, current["name"], "Mat") + +} + +func TestAccessorsAccessSetDeep(t *testing.T) { + + current := map[string]interface{}{"name": map[string]interface{}{"first": "Tyler", "last": "Bunnell"}} + + access(current, "name.first", "Mat", true, true) + access(current, "name.last", "Ryer", true, true) + + assert.Equal(t, "Mat", access(current, "name.first", nil, false, true)) + assert.Equal(t, "Ryer", access(current, "name.last", nil, false, true)) + +} +func TestAccessorsAccessSetDeepDeep(t *testing.T) { + + current := map[string]interface{}{"one": map[string]interface{}{"two": map[string]interface{}{"three": map[string]interface{}{"four": 4}}}} + + access(current, "one.two.three.four", 5, true, true) + + assert.Equal(t, 5, access(current, "one.two.three.four", nil, false, true)) + +} +func TestAccessorsAccessSetArray(t *testing.T) { + + current := map[string]interface{}{"names": []interface{}{"Tyler"}} + + access(current, "names[0]", "Mat", true, true) + + assert.Equal(t, "Mat", access(current, "names[0]", nil, false, true)) + +} +func TestAccessorsAccessSetInsideArray(t *testing.T) { + + current := map[string]interface{}{"names": []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}} + + access(current, "names[0].first", "Mat", true, true) + access(current, "names[0].last", "Ryer", true, true) + access(current, "names[1].first", "Captain", true, true) + access(current, "names[1].last", "Underpants", true, true) + + assert.Equal(t, "Mat", access(current, "names[0].first", nil, false, true)) + assert.Equal(t, "Ryer", access(current, "names[0].last", nil, false, true)) + assert.Equal(t, "Captain", access(current, "names[1].first", nil, false, true)) + assert.Equal(t, "Underpants", access(current, "names[1].last", nil, false, true)) + +} + +func TestAccessorsAccessSetFromArrayWithInt(t *testing.T) { + + current := []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}} + one := access(current, 0, nil, false, false) + two := access(current, 1, nil, false, false) + three := access(current, 2, nil, false, false) + + assert.Equal(t, "Tyler", one.(map[string]interface{})["first"]) + assert.Equal(t, "Capitol", two.(map[string]interface{})["first"]) + assert.Nil(t, three) + +} + +func TestAccessorsSet(t *testing.T) { + + current := New(map[string]interface{}{"name": "Tyler"}) + current.Set("name", "Mat") + assert.Equal(t, "Mat", current.Get("name").data) + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/array-access.txt b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/array-access.txt new file mode 100644 index 000000000..306023475 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/array-access.txt @@ -0,0 +1,14 @@ + case []{1}: + a := object.([]{1}) + if isSet { + a[index] = value.({1}) + } else { + if index >= len(a) { + if panics { + panic(fmt.Sprintf("objx: Index %d is out of range because the []{1} only contains %d items.", index, len(a))) + } + return nil + } else { + return a[index] + } + } diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/index.html b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/index.html new file mode 100644 index 000000000..379ffc3c0 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/index.html @@ -0,0 +1,86 @@ + + + + Codegen + + + + + +

+ Template +

+

+ Use {x} as a placeholder for each argument. +

+ + +

+ Arguments (comma separated) +

+

+ One block per line +

+ + +

+ Output +

+ + + + + + + + diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/template.txt b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/template.txt new file mode 100644 index 000000000..b396900b8 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/template.txt @@ -0,0 +1,286 @@ +/* + {4} ({1} and []{1}) + -------------------------------------------------- +*/ + +// {4} gets the value as a {1}, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) {4}(optionalDefault ...{1}) {1} { + if s, ok := v.data.({1}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return {3} +} + +// Must{4} gets the value as a {1}. +// +// Panics if the object is not a {1}. +func (v *Value) Must{4}() {1} { + return v.data.({1}) +} + +// {4}Slice gets the value as a []{1}, returns the optionalDefault +// value or nil if the value is not a []{1}. +func (v *Value) {4}Slice(optionalDefault ...[]{1}) []{1} { + if s, ok := v.data.([]{1}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// Must{4}Slice gets the value as a []{1}. +// +// Panics if the object is not a []{1}. +func (v *Value) Must{4}Slice() []{1} { + return v.data.([]{1}) +} + +// Is{4} gets whether the object contained is a {1} or not. +func (v *Value) Is{4}() bool { + _, ok := v.data.({1}) + return ok +} + +// Is{4}Slice gets whether the object contained is a []{1} or not. +func (v *Value) Is{4}Slice() bool { + _, ok := v.data.([]{1}) + return ok +} + +// Each{4} calls the specified callback for each object +// in the []{1}. +// +// Panics if the object is the wrong type. +func (v *Value) Each{4}(callback func(int, {1}) bool) *Value { + + for index, val := range v.Must{4}Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// Where{4} uses the specified decider function to select items +// from the []{1}. The object contained in the result will contain +// only the selected items. +func (v *Value) Where{4}(decider func(int, {1}) bool) *Value { + + var selected []{1} + + v.Each{4}(func(index int, val {1}) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data:selected} + +} + +// Group{4} uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]{1}. +func (v *Value) Group{4}(grouper func(int, {1}) string) *Value { + + groups := make(map[string][]{1}) + + v.Each{4}(func(index int, val {1}) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]{1}, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data:groups} + +} + +// Replace{4} uses the specified function to replace each {1}s +// by iterating each item. The data in the returned result will be a +// []{1} containing the replaced items. +func (v *Value) Replace{4}(replacer func(int, {1}) {1}) *Value { + + arr := v.Must{4}Slice() + replaced := make([]{1}, len(arr)) + + v.Each{4}(func(index int, val {1}) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data:replaced} + +} + +// Collect{4} uses the specified collector function to collect a value +// for each of the {1}s in the slice. The data returned will be a +// []interface{}. +func (v *Value) Collect{4}(collector func(int, {1}) interface{}) *Value { + + arr := v.Must{4}Slice() + collected := make([]interface{}, len(arr)) + + v.Each{4}(func(index int, val {1}) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data:collected} +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func Test{4}(t *testing.T) { + + val := {1}( {2} ) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").{4}()) + assert.Equal(t, val, New(m).Get("value").Must{4}()) + assert.Equal(t, {1}({3}), New(m).Get("nothing").{4}()) + assert.Equal(t, val, New(m).Get("nothing").{4}({2})) + + assert.Panics(t, func() { + New(m).Get("age").Must{4}() + }) + +} + +func Test{4}Slice(t *testing.T) { + + val := {1}( {2} ) + m := map[string]interface{}{"value": []{1}{ val }, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").{4}Slice()[0]) + assert.Equal(t, val, New(m).Get("value").Must{4}Slice()[0]) + assert.Equal(t, []{1}(nil), New(m).Get("nothing").{4}Slice()) + assert.Equal(t, val, New(m).Get("nothing").{4}Slice( []{1}{ {1}({2}) } )[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").Must{4}Slice() + }) + +} + +func TestIs{4}(t *testing.T) { + + var v *Value + + v = &Value{data: {1}({2})} + assert.True(t, v.Is{4}()) + + v = &Value{data: []{1}{ {1}({2}) }} + assert.True(t, v.Is{4}Slice()) + +} + +func TestEach{4}(t *testing.T) { + + v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }} + count := 0 + replacedVals := make([]{1}, 0) + assert.Equal(t, v, v.Each{4}(func(i int, val {1}) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.Must{4}Slice()[0]) + assert.Equal(t, replacedVals[1], v.Must{4}Slice()[1]) + assert.Equal(t, replacedVals[2], v.Must{4}Slice()[2]) + +} + +func TestWhere{4}(t *testing.T) { + + v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }} + + selected := v.Where{4}(func(i int, val {1}) bool { + return i%2==0 + }).Must{4}Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroup{4}(t *testing.T) { + + v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }} + + grouped := v.Group{4}(func(i int, val {1}) string { + return fmt.Sprintf("%v", i%2==0) + }).data.(map[string][]{1}) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplace{4}(t *testing.T) { + + v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }} + + rawArr := v.Must{4}Slice() + + replaced := v.Replace{4}(func(index int, val {1}) {1} { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.Must{4}Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollect{4}(t *testing.T) { + + v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }} + + collected := v.Collect{4}(func(index int, val {1}) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/types_list.txt b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/types_list.txt new file mode 100644 index 000000000..069d43d8e --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/codegen/types_list.txt @@ -0,0 +1,20 @@ +Interface,interface{},"something",nil,Inter +Map,map[string]interface{},map[string]interface{}{"name":"Tyler"},nil,MSI +ObjxMap,(Map),New(1),New(nil),ObjxMap +Bool,bool,true,false,Bool +String,string,"hello","",Str +Int,int,1,0,Int +Int8,int8,1,0,Int8 +Int16,int16,1,0,Int16 +Int32,int32,1,0,Int32 +Int64,int64,1,0,Int64 +Uint,uint,1,0,Uint +Uint8,uint8,1,0,Uint8 +Uint16,uint16,1,0,Uint16 +Uint32,uint32,1,0,Uint32 +Uint64,uint64,1,0,Uint64 +Uintptr,uintptr,1,0,Uintptr +Float32,float32,1,0,Float32 +Float64,float64,1,0,Float64 +Complex64,complex64,1,0,Complex64 +Complex128,complex128,1,0,Complex128 diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/constants.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/constants.go new file mode 100644 index 000000000..f9eb42a25 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/constants.go @@ -0,0 +1,13 @@ +package objx + +const ( + // PathSeparator is the character used to separate the elements + // of the keypath. + // + // For example, `location.address.city` + PathSeparator string = "." + + // SignatureSeparator is the character that is used to + // separate the Base64 string from the security signature. + SignatureSeparator = "_" +) diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/conversions.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/conversions.go new file mode 100644 index 000000000..9cdfa9f9f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/conversions.go @@ -0,0 +1,117 @@ +package objx + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "net/url" +) + +// JSON converts the contained object to a JSON string +// representation +func (m Map) JSON() (string, error) { + + result, err := json.Marshal(m) + + if err != nil { + err = errors.New("objx: JSON encode failed with: " + err.Error()) + } + + return string(result), err + +} + +// MustJSON converts the contained object to a JSON string +// representation and panics if there is an error +func (m Map) MustJSON() string { + result, err := m.JSON() + if err != nil { + panic(err.Error()) + } + return result +} + +// Base64 converts the contained object to a Base64 string +// representation of the JSON string representation +func (m Map) Base64() (string, error) { + + var buf bytes.Buffer + + jsonData, err := m.JSON() + if err != nil { + return "", err + } + + encoder := base64.NewEncoder(base64.StdEncoding, &buf) + encoder.Write([]byte(jsonData)) + encoder.Close() + + return buf.String(), nil + +} + +// MustBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and panics +// if there is an error +func (m Map) MustBase64() string { + result, err := m.Base64() + if err != nil { + panic(err.Error()) + } + return result +} + +// SignedBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and signs it +// using the provided key. +func (m Map) SignedBase64(key string) (string, error) { + + base64, err := m.Base64() + if err != nil { + return "", err + } + + sig := HashWithKey(base64, key) + + return base64 + SignatureSeparator + sig, nil + +} + +// MustSignedBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and signs it +// using the provided key and panics if there is an error +func (m Map) MustSignedBase64(key string) string { + result, err := m.SignedBase64(key) + if err != nil { + panic(err.Error()) + } + return result +} + +/* + URL Query + ------------------------------------------------ +*/ + +// URLValues creates a url.Values object from an Obj. This +// function requires that the wrapped object be a map[string]interface{} +func (m Map) URLValues() url.Values { + + vals := make(url.Values) + + for k, v := range m { + //TODO: can this be done without sprintf? + vals.Set(k, fmt.Sprintf("%v", v)) + } + + return vals +} + +// URLQuery gets an encoded URL query representing the given +// Obj. This function requires that the wrapped object be a +// map[string]interface{} +func (m Map) URLQuery() (string, error) { + return m.URLValues().Encode(), nil +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/conversions_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/conversions_test.go new file mode 100644 index 000000000..e9ccd2987 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/conversions_test.go @@ -0,0 +1,94 @@ +package objx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestConversionJSON(t *testing.T) { + + jsonString := `{"name":"Mat"}` + o := MustFromJSON(jsonString) + + result, err := o.JSON() + + if assert.NoError(t, err) { + assert.Equal(t, jsonString, result) + } + + assert.Equal(t, jsonString, o.MustJSON()) + +} + +func TestConversionJSONWithError(t *testing.T) { + + o := MSI() + o["test"] = func() {} + + assert.Panics(t, func() { + o.MustJSON() + }) + + _, err := o.JSON() + + assert.Error(t, err) + +} + +func TestConversionBase64(t *testing.T) { + + o := New(map[string]interface{}{"name": "Mat"}) + + result, err := o.Base64() + + if assert.NoError(t, err) { + assert.Equal(t, "eyJuYW1lIjoiTWF0In0=", result) + } + + assert.Equal(t, "eyJuYW1lIjoiTWF0In0=", o.MustBase64()) + +} + +func TestConversionBase64WithError(t *testing.T) { + + o := MSI() + o["test"] = func() {} + + assert.Panics(t, func() { + o.MustBase64() + }) + + _, err := o.Base64() + + assert.Error(t, err) + +} + +func TestConversionSignedBase64(t *testing.T) { + + o := New(map[string]interface{}{"name": "Mat"}) + + result, err := o.SignedBase64("key") + + if assert.NoError(t, err) { + assert.Equal(t, "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6", result) + } + + assert.Equal(t, "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6", o.MustSignedBase64("key")) + +} + +func TestConversionSignedBase64WithError(t *testing.T) { + + o := MSI() + o["test"] = func() {} + + assert.Panics(t, func() { + o.MustSignedBase64("key") + }) + + _, err := o.SignedBase64("key") + + assert.Error(t, err) + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/doc.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/doc.go new file mode 100644 index 000000000..47bf85e46 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/doc.go @@ -0,0 +1,72 @@ +// objx - Go package for dealing with maps, slices, JSON and other data. +// +// Overview +// +// Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes +// a powerful `Get` method (among others) that allows you to easily and quickly get +// access to data within the map, without having to worry too much about type assertions, +// missing data, default values etc. +// +// Pattern +// +// Objx uses a preditable pattern to make access data from within `map[string]interface{}'s +// easy. +// +// Call one of the `objx.` functions to create your `objx.Map` to get going: +// +// m, err := objx.FromJSON(json) +// +// NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, +// the rest will be optimistic and try to figure things out without panicking. +// +// Use `Get` to access the value you're interested in. You can use dot and array +// notation too: +// +// m.Get("places[0].latlng") +// +// Once you have saught the `Value` you're interested in, you can use the `Is*` methods +// to determine its type. +// +// if m.Get("code").IsStr() { /* ... */ } +// +// Or you can just assume the type, and use one of the strong type methods to +// extract the real value: +// +// m.Get("code").Int() +// +// If there's no value there (or if it's the wrong type) then a default value +// will be returned, or you can be explicit about the default value. +// +// Get("code").Int(-1) +// +// If you're dealing with a slice of data as a value, Objx provides many useful +// methods for iterating, manipulating and selecting that data. You can find out more +// by exploring the index below. +// +// Reading data +// +// A simple example of how to use Objx: +// +// // use MustFromJSON to make an objx.Map from some JSON +// m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) +// +// // get the details +// name := m.Get("name").Str() +// age := m.Get("age").Int() +// +// // get their nickname (or use their name if they +// // don't have one) +// nickname := m.Get("nickname").Str(name) +// +// Ranging +// +// Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For +// example, to `range` the data, do what you would expect: +// +// m := objx.MustFromJSON(json) +// for key, value := range m { +// +// /* ... do your magic ... */ +// +// } +package objx diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/fixture_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/fixture_test.go new file mode 100644 index 000000000..27f7d9049 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/fixture_test.go @@ -0,0 +1,98 @@ +package objx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +var fixtures = []struct { + // name is the name of the fixture (used for reporting + // failures) + name string + // data is the JSON data to be worked on + data string + // get is the argument(s) to pass to Get + get interface{} + // output is the expected output + output interface{} +}{ + { + name: "Simple get", + data: `{"name": "Mat"}`, + get: "name", + output: "Mat", + }, + { + name: "Get with dot notation", + data: `{"address": {"city": "Boulder"}}`, + get: "address.city", + output: "Boulder", + }, + { + name: "Deep get with dot notation", + data: `{"one": {"two": {"three": {"four": "hello"}}}}`, + get: "one.two.three.four", + output: "hello", + }, + { + name: "Get missing with dot notation", + data: `{"one": {"two": {"three": {"four": "hello"}}}}`, + get: "one.ten", + output: nil, + }, + { + name: "Get with array notation", + data: `{"tags": ["one", "two", "three"]}`, + get: "tags[1]", + output: "two", + }, + { + name: "Get with array and dot notation", + data: `{"types": { "tags": ["one", "two", "three"]}}`, + get: "types.tags[1]", + output: "two", + }, + { + name: "Get with array and dot notation - field after array", + data: `{"tags": [{"name":"one"}, {"name":"two"}, {"name":"three"}]}`, + get: "tags[1].name", + output: "two", + }, + { + name: "Complex get with array and dot notation", + data: `{"tags": [{"list": [{"one":"pizza"}]}]}`, + get: "tags[0].list[0].one", + output: "pizza", + }, + { + name: "Get field from within string should be nil", + data: `{"name":"Tyler"}`, + get: "name.something", + output: nil, + }, + { + name: "Get field from within string (using array accessor) should be nil", + data: `{"numbers":["one", "two", "three"]}`, + get: "numbers[0].nope", + output: nil, + }, +} + +func TestFixtures(t *testing.T) { + + for _, fixture := range fixtures { + + m := MustFromJSON(fixture.data) + + // get the value + t.Logf("Running get fixture: \"%s\" (%v)", fixture.name, fixture) + value := m.Get(fixture.get.(string)) + + // make sure it matches + assert.Equal(t, fixture.output, value.data, + "Get fixture \"%s\" failed: %v", fixture.name, fixture, + ) + + } + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map.go new file mode 100644 index 000000000..eb6ed8e28 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map.go @@ -0,0 +1,222 @@ +package objx + +import ( + "encoding/base64" + "encoding/json" + "errors" + "io/ioutil" + "net/url" + "strings" +) + +// MSIConvertable is an interface that defines methods for converting your +// custom types to a map[string]interface{} representation. +type MSIConvertable interface { + // MSI gets a map[string]interface{} (msi) representing the + // object. + MSI() map[string]interface{} +} + +// Map provides extended functionality for working with +// untyped data, in particular map[string]interface (msi). +type Map map[string]interface{} + +// Value returns the internal value instance +func (m Map) Value() *Value { + return &Value{data: m} +} + +// Nil represents a nil Map. +var Nil Map = New(nil) + +// New creates a new Map containing the map[string]interface{} in the data argument. +// If the data argument is not a map[string]interface, New attempts to call the +// MSI() method on the MSIConvertable interface to create one. +func New(data interface{}) Map { + if _, ok := data.(map[string]interface{}); !ok { + if converter, ok := data.(MSIConvertable); ok { + data = converter.MSI() + } else { + return nil + } + } + return Map(data.(map[string]interface{})) +} + +// MSI creates a map[string]interface{} and puts it inside a new Map. +// +// The arguments follow a key, value pattern. +// +// Panics +// +// Panics if any key arugment is non-string or if there are an odd number of arguments. +// +// Example +// +// To easily create Maps: +// +// m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true)) +// +// // creates an Map equivalent to +// m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}}) +func MSI(keyAndValuePairs ...interface{}) Map { + + newMap := make(map[string]interface{}) + keyAndValuePairsLen := len(keyAndValuePairs) + + if keyAndValuePairsLen%2 != 0 { + panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.") + } + + for i := 0; i < keyAndValuePairsLen; i = i + 2 { + + key := keyAndValuePairs[i] + value := keyAndValuePairs[i+1] + + // make sure the key is a string + keyString, keyStringOK := key.(string) + if !keyStringOK { + panic("objx: MSI must follow 'string, interface{}' pattern. " + keyString + " is not a valid key.") + } + + newMap[keyString] = value + + } + + return New(newMap) +} + +// ****** Conversion Constructors + +// MustFromJSON creates a new Map containing the data specified in the +// jsonString. +// +// Panics if the JSON is invalid. +func MustFromJSON(jsonString string) Map { + o, err := FromJSON(jsonString) + + if err != nil { + panic("objx: MustFromJSON failed with error: " + err.Error()) + } + + return o +} + +// FromJSON creates a new Map containing the data specified in the +// jsonString. +// +// Returns an error if the JSON is invalid. +func FromJSON(jsonString string) (Map, error) { + + var data interface{} + err := json.Unmarshal([]byte(jsonString), &data) + + if err != nil { + return Nil, err + } + + return New(data), nil + +} + +// FromBase64 creates a new Obj containing the data specified +// in the Base64 string. +// +// The string is an encoded JSON string returned by Base64 +func FromBase64(base64String string) (Map, error) { + + decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String)) + + decoded, err := ioutil.ReadAll(decoder) + if err != nil { + return nil, err + } + + return FromJSON(string(decoded)) +} + +// MustFromBase64 creates a new Obj containing the data specified +// in the Base64 string and panics if there is an error. +// +// The string is an encoded JSON string returned by Base64 +func MustFromBase64(base64String string) Map { + + result, err := FromBase64(base64String) + + if err != nil { + panic("objx: MustFromBase64 failed with error: " + err.Error()) + } + + return result +} + +// FromSignedBase64 creates a new Obj containing the data specified +// in the Base64 string. +// +// The string is an encoded JSON string returned by SignedBase64 +func FromSignedBase64(base64String, key string) (Map, error) { + parts := strings.Split(base64String, SignatureSeparator) + if len(parts) != 2 { + return nil, errors.New("objx: Signed base64 string is malformed.") + } + + sig := HashWithKey(parts[0], key) + if parts[1] != sig { + return nil, errors.New("objx: Signature for base64 data does not match.") + } + + return FromBase64(parts[0]) +} + +// MustFromSignedBase64 creates a new Obj containing the data specified +// in the Base64 string and panics if there is an error. +// +// The string is an encoded JSON string returned by Base64 +func MustFromSignedBase64(base64String, key string) Map { + + result, err := FromSignedBase64(base64String, key) + + if err != nil { + panic("objx: MustFromSignedBase64 failed with error: " + err.Error()) + } + + return result +} + +// FromURLQuery generates a new Obj by parsing the specified +// query. +// +// For queries with multiple values, the first value is selected. +func FromURLQuery(query string) (Map, error) { + + vals, err := url.ParseQuery(query) + + if err != nil { + return nil, err + } + + m := make(map[string]interface{}) + for k, vals := range vals { + m[k] = vals[0] + } + + return New(m), nil +} + +// MustFromURLQuery generates a new Obj by parsing the specified +// query. +// +// For queries with multiple values, the first value is selected. +// +// Panics if it encounters an error +func MustFromURLQuery(query string) Map { + + o, err := FromURLQuery(query) + + if err != nil { + panic("objx: MustFromURLQuery failed with error: " + err.Error()) + } + + return o + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map_for_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map_for_test.go new file mode 100644 index 000000000..6beb50675 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map_for_test.go @@ -0,0 +1,10 @@ +package objx + +var TestMap map[string]interface{} = map[string]interface{}{ + "name": "Tyler", + "address": map[string]interface{}{ + "city": "Salt Lake City", + "state": "UT", + }, + "numbers": []interface{}{"one", "two", "three", "four", "five"}, +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map_test.go new file mode 100644 index 000000000..1f8b45c61 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/map_test.go @@ -0,0 +1,147 @@ +package objx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +type Convertable struct { + name string +} + +func (c *Convertable) MSI() map[string]interface{} { + return map[string]interface{}{"name": c.name} +} + +type Unconvertable struct { + name string +} + +func TestMapCreation(t *testing.T) { + + o := New(nil) + assert.Nil(t, o) + + o = New("Tyler") + assert.Nil(t, o) + + unconvertable := &Unconvertable{name: "Tyler"} + o = New(unconvertable) + assert.Nil(t, o) + + convertable := &Convertable{name: "Tyler"} + o = New(convertable) + if assert.NotNil(t, convertable) { + assert.Equal(t, "Tyler", o["name"], "Tyler") + } + + o = MSI() + if assert.NotNil(t, o) { + assert.NotNil(t, o) + } + + o = MSI("name", "Tyler") + if assert.NotNil(t, o) { + if assert.NotNil(t, o) { + assert.Equal(t, o["name"], "Tyler") + } + } + +} + +func TestMapMustFromJSONWithError(t *testing.T) { + + _, err := FromJSON(`"name":"Mat"}`) + assert.Error(t, err) + +} + +func TestMapFromJSON(t *testing.T) { + + o := MustFromJSON(`{"name":"Mat"}`) + + if assert.NotNil(t, o) { + if assert.NotNil(t, o) { + assert.Equal(t, "Mat", o["name"]) + } + } + +} + +func TestMapFromJSONWithError(t *testing.T) { + + var m Map + + assert.Panics(t, func() { + m = MustFromJSON(`"name":"Mat"}`) + }) + + assert.Nil(t, m) + +} + +func TestMapFromBase64String(t *testing.T) { + + base64String := "eyJuYW1lIjoiTWF0In0=" + + o, err := FromBase64(base64String) + + if assert.NoError(t, err) { + assert.Equal(t, o.Get("name").Str(), "Mat") + } + + assert.Equal(t, MustFromBase64(base64String).Get("name").Str(), "Mat") + +} + +func TestMapFromBase64StringWithError(t *testing.T) { + + base64String := "eyJuYW1lIjoiTWFasd0In0=" + + _, err := FromBase64(base64String) + + assert.Error(t, err) + + assert.Panics(t, func() { + MustFromBase64(base64String) + }) + +} + +func TestMapFromSignedBase64String(t *testing.T) { + + base64String := "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6" + + o, err := FromSignedBase64(base64String, "key") + + if assert.NoError(t, err) { + assert.Equal(t, o.Get("name").Str(), "Mat") + } + + assert.Equal(t, MustFromSignedBase64(base64String, "key").Get("name").Str(), "Mat") + +} + +func TestMapFromSignedBase64StringWithError(t *testing.T) { + + base64String := "eyJuYW1lasdIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6" + + _, err := FromSignedBase64(base64String, "key") + + assert.Error(t, err) + + assert.Panics(t, func() { + MustFromSignedBase64(base64String, "key") + }) + +} + +func TestMapFromURLQuery(t *testing.T) { + + m, err := FromURLQuery("name=tyler&state=UT") + if assert.NoError(t, err) && assert.NotNil(t, m) { + assert.Equal(t, "tyler", m.Get("name").Str()) + assert.Equal(t, "UT", m.Get("state").Str()) + } + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/mutations.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/mutations.go new file mode 100644 index 000000000..b35c86392 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/mutations.go @@ -0,0 +1,81 @@ +package objx + +// Exclude returns a new Map with the keys in the specified []string +// excluded. +func (d Map) Exclude(exclude []string) Map { + + excluded := make(Map) + for k, v := range d { + var shouldInclude bool = true + for _, toExclude := range exclude { + if k == toExclude { + shouldInclude = false + break + } + } + if shouldInclude { + excluded[k] = v + } + } + + return excluded +} + +// Copy creates a shallow copy of the Obj. +func (m Map) Copy() Map { + copied := make(map[string]interface{}) + for k, v := range m { + copied[k] = v + } + return New(copied) +} + +// Merge blends the specified map with a copy of this map and returns the result. +// +// Keys that appear in both will be selected from the specified map. +// This method requires that the wrapped object be a map[string]interface{} +func (m Map) Merge(merge Map) Map { + return m.Copy().MergeHere(merge) +} + +// Merge blends the specified map with this map and returns the current map. +// +// Keys that appear in both will be selected from the specified map. The original map +// will be modified. This method requires that +// the wrapped object be a map[string]interface{} +func (m Map) MergeHere(merge Map) Map { + + for k, v := range merge { + m[k] = v + } + + return m + +} + +// Transform builds a new Obj giving the transformer a chance +// to change the keys and values as it goes. This method requires that +// the wrapped object be a map[string]interface{} +func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map { + newMap := make(map[string]interface{}) + for k, v := range m { + modifiedKey, modifiedVal := transformer(k, v) + newMap[modifiedKey] = modifiedVal + } + return New(newMap) +} + +// TransformKeys builds a new map using the specified key mapping. +// +// Unspecified keys will be unaltered. +// This method requires that the wrapped object be a map[string]interface{} +func (m Map) TransformKeys(mapping map[string]string) Map { + return m.Transform(func(key string, value interface{}) (string, interface{}) { + + if newKey, ok := mapping[key]; ok { + return newKey, value + } + + return key, value + }) +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/mutations_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/mutations_test.go new file mode 100644 index 000000000..e20ee23bc --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/mutations_test.go @@ -0,0 +1,77 @@ +package objx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestExclude(t *testing.T) { + + d := make(Map) + d["name"] = "Mat" + d["age"] = 29 + d["secret"] = "ABC" + + excluded := d.Exclude([]string{"secret"}) + + assert.Equal(t, d["name"], excluded["name"]) + assert.Equal(t, d["age"], excluded["age"]) + assert.False(t, excluded.Has("secret"), "secret should be excluded") + +} + +func TestCopy(t *testing.T) { + + d1 := make(map[string]interface{}) + d1["name"] = "Tyler" + d1["location"] = "UT" + + d1Obj := New(d1) + d2Obj := d1Obj.Copy() + + d2Obj["name"] = "Mat" + + assert.Equal(t, d1Obj.Get("name").Str(), "Tyler") + assert.Equal(t, d2Obj.Get("name").Str(), "Mat") + +} + +func TestMerge(t *testing.T) { + + d := make(map[string]interface{}) + d["name"] = "Mat" + + d1 := make(map[string]interface{}) + d1["name"] = "Tyler" + d1["location"] = "UT" + + dObj := New(d) + d1Obj := New(d1) + + merged := dObj.Merge(d1Obj) + + assert.Equal(t, merged.Get("name").Str(), d1Obj.Get("name").Str()) + assert.Equal(t, merged.Get("location").Str(), d1Obj.Get("location").Str()) + assert.Empty(t, dObj.Get("location").Str()) + +} + +func TestMergeHere(t *testing.T) { + + d := make(map[string]interface{}) + d["name"] = "Mat" + + d1 := make(map[string]interface{}) + d1["name"] = "Tyler" + d1["location"] = "UT" + + dObj := New(d) + d1Obj := New(d1) + + merged := dObj.MergeHere(d1Obj) + + assert.Equal(t, dObj, merged, "With MergeHere, it should return the first modified map") + assert.Equal(t, merged.Get("name").Str(), d1Obj.Get("name").Str()) + assert.Equal(t, merged.Get("location").Str(), d1Obj.Get("location").Str()) + assert.Equal(t, merged.Get("location").Str(), dObj.Get("location").Str()) +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/security.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/security.go new file mode 100644 index 000000000..fdd6be9cf --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/security.go @@ -0,0 +1,14 @@ +package objx + +import ( + "crypto/sha1" + "encoding/hex" +) + +// HashWithKey hashes the specified string using the security +// key. +func HashWithKey(data, key string) string { + hash := sha1.New() + hash.Write([]byte(data + ":" + key)) + return hex.EncodeToString(hash.Sum(nil)) +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/security_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/security_test.go new file mode 100644 index 000000000..8f0898f62 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/security_test.go @@ -0,0 +1,12 @@ +package objx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestHashWithKey(t *testing.T) { + + assert.Equal(t, "0ce84d8d01f2c7b6e0882b784429c54d280ea2d9", HashWithKey("abc", "def")) + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/simple_example_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/simple_example_test.go new file mode 100644 index 000000000..5408c7fd3 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/simple_example_test.go @@ -0,0 +1,41 @@ +package objx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestSimpleExample(t *testing.T) { + + // build a map from a JSON object + o := MustFromJSON(`{"name":"Mat","foods":["indian","chinese"], "location":{"county":"hobbiton","city":"the shire"}}`) + + // Map can be used as a straight map[string]interface{} + assert.Equal(t, o["name"], "Mat") + + // Get an Value object + v := o.Get("name") + assert.Equal(t, v, &Value{data: "Mat"}) + + // Test the contained value + assert.False(t, v.IsInt()) + assert.False(t, v.IsBool()) + assert.True(t, v.IsStr()) + + // Get the contained value + assert.Equal(t, v.Str(), "Mat") + + // Get a default value if the contained value is not of the expected type or does not exist + assert.Equal(t, 1, v.Int(1)) + + // Get a value by using array notation + assert.Equal(t, "indian", o.Get("foods[0]").Data()) + + // Set a value by using array notation + o.Set("foods[0]", "italian") + assert.Equal(t, "italian", o.Get("foods[0]").Str()) + + // Get a value by using dot notation + assert.Equal(t, "hobbiton", o.Get("location.county").Str()) + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/tests.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/tests.go new file mode 100644 index 000000000..d9e0b479a --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/tests.go @@ -0,0 +1,17 @@ +package objx + +// Has gets whether there is something at the specified selector +// or not. +// +// If m is nil, Has will always return false. +func (m Map) Has(selector string) bool { + if m == nil { + return false + } + return !m.Get(selector).IsNil() +} + +// IsNil gets whether the data is nil or not. +func (v *Value) IsNil() bool { + return v == nil || v.data == nil +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/tests_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/tests_test.go new file mode 100644 index 000000000..bcc1eb03d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/tests_test.go @@ -0,0 +1,24 @@ +package objx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestHas(t *testing.T) { + + m := New(TestMap) + + assert.True(t, m.Has("name")) + assert.True(t, m.Has("address.state")) + assert.True(t, m.Has("numbers[4]")) + + assert.False(t, m.Has("address.state.nope")) + assert.False(t, m.Has("address.nope")) + assert.False(t, m.Has("nope")) + assert.False(t, m.Has("numbers[5]")) + + m = nil + assert.False(t, m.Has("nothing")) + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen.go new file mode 100644 index 000000000..f3ecb29b9 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen.go @@ -0,0 +1,2881 @@ +package objx + +/* + Inter (interface{} and []interface{}) + -------------------------------------------------- +*/ + +// Inter gets the value as a interface{}, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Inter(optionalDefault ...interface{}) interface{} { + if s, ok := v.data.(interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInter gets the value as a interface{}. +// +// Panics if the object is not a interface{}. +func (v *Value) MustInter() interface{} { + return v.data.(interface{}) +} + +// InterSlice gets the value as a []interface{}, returns the optionalDefault +// value or nil if the value is not a []interface{}. +func (v *Value) InterSlice(optionalDefault ...[]interface{}) []interface{} { + if s, ok := v.data.([]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInterSlice gets the value as a []interface{}. +// +// Panics if the object is not a []interface{}. +func (v *Value) MustInterSlice() []interface{} { + return v.data.([]interface{}) +} + +// IsInter gets whether the object contained is a interface{} or not. +func (v *Value) IsInter() bool { + _, ok := v.data.(interface{}) + return ok +} + +// IsInterSlice gets whether the object contained is a []interface{} or not. +func (v *Value) IsInterSlice() bool { + _, ok := v.data.([]interface{}) + return ok +} + +// EachInter calls the specified callback for each object +// in the []interface{}. +// +// Panics if the object is the wrong type. +func (v *Value) EachInter(callback func(int, interface{}) bool) *Value { + + for index, val := range v.MustInterSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInter uses the specified decider function to select items +// from the []interface{}. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInter(decider func(int, interface{}) bool) *Value { + + var selected []interface{} + + v.EachInter(func(index int, val interface{}) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInter uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]interface{}. +func (v *Value) GroupInter(grouper func(int, interface{}) string) *Value { + + groups := make(map[string][]interface{}) + + v.EachInter(func(index int, val interface{}) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]interface{}, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInter uses the specified function to replace each interface{}s +// by iterating each item. The data in the returned result will be a +// []interface{} containing the replaced items. +func (v *Value) ReplaceInter(replacer func(int, interface{}) interface{}) *Value { + + arr := v.MustInterSlice() + replaced := make([]interface{}, len(arr)) + + v.EachInter(func(index int, val interface{}) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInter uses the specified collector function to collect a value +// for each of the interface{}s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInter(collector func(int, interface{}) interface{}) *Value { + + arr := v.MustInterSlice() + collected := make([]interface{}, len(arr)) + + v.EachInter(func(index int, val interface{}) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + MSI (map[string]interface{} and []map[string]interface{}) + -------------------------------------------------- +*/ + +// MSI gets the value as a map[string]interface{}, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) MSI(optionalDefault ...map[string]interface{}) map[string]interface{} { + if s, ok := v.data.(map[string]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustMSI gets the value as a map[string]interface{}. +// +// Panics if the object is not a map[string]interface{}. +func (v *Value) MustMSI() map[string]interface{} { + return v.data.(map[string]interface{}) +} + +// MSISlice gets the value as a []map[string]interface{}, returns the optionalDefault +// value or nil if the value is not a []map[string]interface{}. +func (v *Value) MSISlice(optionalDefault ...[]map[string]interface{}) []map[string]interface{} { + if s, ok := v.data.([]map[string]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustMSISlice gets the value as a []map[string]interface{}. +// +// Panics if the object is not a []map[string]interface{}. +func (v *Value) MustMSISlice() []map[string]interface{} { + return v.data.([]map[string]interface{}) +} + +// IsMSI gets whether the object contained is a map[string]interface{} or not. +func (v *Value) IsMSI() bool { + _, ok := v.data.(map[string]interface{}) + return ok +} + +// IsMSISlice gets whether the object contained is a []map[string]interface{} or not. +func (v *Value) IsMSISlice() bool { + _, ok := v.data.([]map[string]interface{}) + return ok +} + +// EachMSI calls the specified callback for each object +// in the []map[string]interface{}. +// +// Panics if the object is the wrong type. +func (v *Value) EachMSI(callback func(int, map[string]interface{}) bool) *Value { + + for index, val := range v.MustMSISlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereMSI uses the specified decider function to select items +// from the []map[string]interface{}. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereMSI(decider func(int, map[string]interface{}) bool) *Value { + + var selected []map[string]interface{} + + v.EachMSI(func(index int, val map[string]interface{}) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupMSI uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]map[string]interface{}. +func (v *Value) GroupMSI(grouper func(int, map[string]interface{}) string) *Value { + + groups := make(map[string][]map[string]interface{}) + + v.EachMSI(func(index int, val map[string]interface{}) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]map[string]interface{}, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceMSI uses the specified function to replace each map[string]interface{}s +// by iterating each item. The data in the returned result will be a +// []map[string]interface{} containing the replaced items. +func (v *Value) ReplaceMSI(replacer func(int, map[string]interface{}) map[string]interface{}) *Value { + + arr := v.MustMSISlice() + replaced := make([]map[string]interface{}, len(arr)) + + v.EachMSI(func(index int, val map[string]interface{}) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectMSI uses the specified collector function to collect a value +// for each of the map[string]interface{}s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectMSI(collector func(int, map[string]interface{}) interface{}) *Value { + + arr := v.MustMSISlice() + collected := make([]interface{}, len(arr)) + + v.EachMSI(func(index int, val map[string]interface{}) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + ObjxMap ((Map) and [](Map)) + -------------------------------------------------- +*/ + +// ObjxMap gets the value as a (Map), returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) ObjxMap(optionalDefault ...(Map)) Map { + if s, ok := v.data.((Map)); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return New(nil) +} + +// MustObjxMap gets the value as a (Map). +// +// Panics if the object is not a (Map). +func (v *Value) MustObjxMap() Map { + return v.data.((Map)) +} + +// ObjxMapSlice gets the value as a [](Map), returns the optionalDefault +// value or nil if the value is not a [](Map). +func (v *Value) ObjxMapSlice(optionalDefault ...[](Map)) [](Map) { + if s, ok := v.data.([](Map)); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustObjxMapSlice gets the value as a [](Map). +// +// Panics if the object is not a [](Map). +func (v *Value) MustObjxMapSlice() [](Map) { + return v.data.([](Map)) +} + +// IsObjxMap gets whether the object contained is a (Map) or not. +func (v *Value) IsObjxMap() bool { + _, ok := v.data.((Map)) + return ok +} + +// IsObjxMapSlice gets whether the object contained is a [](Map) or not. +func (v *Value) IsObjxMapSlice() bool { + _, ok := v.data.([](Map)) + return ok +} + +// EachObjxMap calls the specified callback for each object +// in the [](Map). +// +// Panics if the object is the wrong type. +func (v *Value) EachObjxMap(callback func(int, Map) bool) *Value { + + for index, val := range v.MustObjxMapSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereObjxMap uses the specified decider function to select items +// from the [](Map). The object contained in the result will contain +// only the selected items. +func (v *Value) WhereObjxMap(decider func(int, Map) bool) *Value { + + var selected [](Map) + + v.EachObjxMap(func(index int, val Map) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupObjxMap uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][](Map). +func (v *Value) GroupObjxMap(grouper func(int, Map) string) *Value { + + groups := make(map[string][](Map)) + + v.EachObjxMap(func(index int, val Map) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([](Map), 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceObjxMap uses the specified function to replace each (Map)s +// by iterating each item. The data in the returned result will be a +// [](Map) containing the replaced items. +func (v *Value) ReplaceObjxMap(replacer func(int, Map) Map) *Value { + + arr := v.MustObjxMapSlice() + replaced := make([](Map), len(arr)) + + v.EachObjxMap(func(index int, val Map) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectObjxMap uses the specified collector function to collect a value +// for each of the (Map)s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectObjxMap(collector func(int, Map) interface{}) *Value { + + arr := v.MustObjxMapSlice() + collected := make([]interface{}, len(arr)) + + v.EachObjxMap(func(index int, val Map) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Bool (bool and []bool) + -------------------------------------------------- +*/ + +// Bool gets the value as a bool, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Bool(optionalDefault ...bool) bool { + if s, ok := v.data.(bool); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return false +} + +// MustBool gets the value as a bool. +// +// Panics if the object is not a bool. +func (v *Value) MustBool() bool { + return v.data.(bool) +} + +// BoolSlice gets the value as a []bool, returns the optionalDefault +// value or nil if the value is not a []bool. +func (v *Value) BoolSlice(optionalDefault ...[]bool) []bool { + if s, ok := v.data.([]bool); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustBoolSlice gets the value as a []bool. +// +// Panics if the object is not a []bool. +func (v *Value) MustBoolSlice() []bool { + return v.data.([]bool) +} + +// IsBool gets whether the object contained is a bool or not. +func (v *Value) IsBool() bool { + _, ok := v.data.(bool) + return ok +} + +// IsBoolSlice gets whether the object contained is a []bool or not. +func (v *Value) IsBoolSlice() bool { + _, ok := v.data.([]bool) + return ok +} + +// EachBool calls the specified callback for each object +// in the []bool. +// +// Panics if the object is the wrong type. +func (v *Value) EachBool(callback func(int, bool) bool) *Value { + + for index, val := range v.MustBoolSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereBool uses the specified decider function to select items +// from the []bool. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereBool(decider func(int, bool) bool) *Value { + + var selected []bool + + v.EachBool(func(index int, val bool) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupBool uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]bool. +func (v *Value) GroupBool(grouper func(int, bool) string) *Value { + + groups := make(map[string][]bool) + + v.EachBool(func(index int, val bool) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]bool, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceBool uses the specified function to replace each bools +// by iterating each item. The data in the returned result will be a +// []bool containing the replaced items. +func (v *Value) ReplaceBool(replacer func(int, bool) bool) *Value { + + arr := v.MustBoolSlice() + replaced := make([]bool, len(arr)) + + v.EachBool(func(index int, val bool) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectBool uses the specified collector function to collect a value +// for each of the bools in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectBool(collector func(int, bool) interface{}) *Value { + + arr := v.MustBoolSlice() + collected := make([]interface{}, len(arr)) + + v.EachBool(func(index int, val bool) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Str (string and []string) + -------------------------------------------------- +*/ + +// Str gets the value as a string, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Str(optionalDefault ...string) string { + if s, ok := v.data.(string); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return "" +} + +// MustStr gets the value as a string. +// +// Panics if the object is not a string. +func (v *Value) MustStr() string { + return v.data.(string) +} + +// StrSlice gets the value as a []string, returns the optionalDefault +// value or nil if the value is not a []string. +func (v *Value) StrSlice(optionalDefault ...[]string) []string { + if s, ok := v.data.([]string); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustStrSlice gets the value as a []string. +// +// Panics if the object is not a []string. +func (v *Value) MustStrSlice() []string { + return v.data.([]string) +} + +// IsStr gets whether the object contained is a string or not. +func (v *Value) IsStr() bool { + _, ok := v.data.(string) + return ok +} + +// IsStrSlice gets whether the object contained is a []string or not. +func (v *Value) IsStrSlice() bool { + _, ok := v.data.([]string) + return ok +} + +// EachStr calls the specified callback for each object +// in the []string. +// +// Panics if the object is the wrong type. +func (v *Value) EachStr(callback func(int, string) bool) *Value { + + for index, val := range v.MustStrSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereStr uses the specified decider function to select items +// from the []string. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereStr(decider func(int, string) bool) *Value { + + var selected []string + + v.EachStr(func(index int, val string) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupStr uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]string. +func (v *Value) GroupStr(grouper func(int, string) string) *Value { + + groups := make(map[string][]string) + + v.EachStr(func(index int, val string) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]string, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceStr uses the specified function to replace each strings +// by iterating each item. The data in the returned result will be a +// []string containing the replaced items. +func (v *Value) ReplaceStr(replacer func(int, string) string) *Value { + + arr := v.MustStrSlice() + replaced := make([]string, len(arr)) + + v.EachStr(func(index int, val string) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectStr uses the specified collector function to collect a value +// for each of the strings in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectStr(collector func(int, string) interface{}) *Value { + + arr := v.MustStrSlice() + collected := make([]interface{}, len(arr)) + + v.EachStr(func(index int, val string) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int (int and []int) + -------------------------------------------------- +*/ + +// Int gets the value as a int, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int(optionalDefault ...int) int { + if s, ok := v.data.(int); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt gets the value as a int. +// +// Panics if the object is not a int. +func (v *Value) MustInt() int { + return v.data.(int) +} + +// IntSlice gets the value as a []int, returns the optionalDefault +// value or nil if the value is not a []int. +func (v *Value) IntSlice(optionalDefault ...[]int) []int { + if s, ok := v.data.([]int); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustIntSlice gets the value as a []int. +// +// Panics if the object is not a []int. +func (v *Value) MustIntSlice() []int { + return v.data.([]int) +} + +// IsInt gets whether the object contained is a int or not. +func (v *Value) IsInt() bool { + _, ok := v.data.(int) + return ok +} + +// IsIntSlice gets whether the object contained is a []int or not. +func (v *Value) IsIntSlice() bool { + _, ok := v.data.([]int) + return ok +} + +// EachInt calls the specified callback for each object +// in the []int. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt(callback func(int, int) bool) *Value { + + for index, val := range v.MustIntSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt uses the specified decider function to select items +// from the []int. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt(decider func(int, int) bool) *Value { + + var selected []int + + v.EachInt(func(index int, val int) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int. +func (v *Value) GroupInt(grouper func(int, int) string) *Value { + + groups := make(map[string][]int) + + v.EachInt(func(index int, val int) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt uses the specified function to replace each ints +// by iterating each item. The data in the returned result will be a +// []int containing the replaced items. +func (v *Value) ReplaceInt(replacer func(int, int) int) *Value { + + arr := v.MustIntSlice() + replaced := make([]int, len(arr)) + + v.EachInt(func(index int, val int) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt uses the specified collector function to collect a value +// for each of the ints in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt(collector func(int, int) interface{}) *Value { + + arr := v.MustIntSlice() + collected := make([]interface{}, len(arr)) + + v.EachInt(func(index int, val int) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int8 (int8 and []int8) + -------------------------------------------------- +*/ + +// Int8 gets the value as a int8, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int8(optionalDefault ...int8) int8 { + if s, ok := v.data.(int8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt8 gets the value as a int8. +// +// Panics if the object is not a int8. +func (v *Value) MustInt8() int8 { + return v.data.(int8) +} + +// Int8Slice gets the value as a []int8, returns the optionalDefault +// value or nil if the value is not a []int8. +func (v *Value) Int8Slice(optionalDefault ...[]int8) []int8 { + if s, ok := v.data.([]int8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt8Slice gets the value as a []int8. +// +// Panics if the object is not a []int8. +func (v *Value) MustInt8Slice() []int8 { + return v.data.([]int8) +} + +// IsInt8 gets whether the object contained is a int8 or not. +func (v *Value) IsInt8() bool { + _, ok := v.data.(int8) + return ok +} + +// IsInt8Slice gets whether the object contained is a []int8 or not. +func (v *Value) IsInt8Slice() bool { + _, ok := v.data.([]int8) + return ok +} + +// EachInt8 calls the specified callback for each object +// in the []int8. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt8(callback func(int, int8) bool) *Value { + + for index, val := range v.MustInt8Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt8 uses the specified decider function to select items +// from the []int8. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt8(decider func(int, int8) bool) *Value { + + var selected []int8 + + v.EachInt8(func(index int, val int8) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt8 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int8. +func (v *Value) GroupInt8(grouper func(int, int8) string) *Value { + + groups := make(map[string][]int8) + + v.EachInt8(func(index int, val int8) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int8, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt8 uses the specified function to replace each int8s +// by iterating each item. The data in the returned result will be a +// []int8 containing the replaced items. +func (v *Value) ReplaceInt8(replacer func(int, int8) int8) *Value { + + arr := v.MustInt8Slice() + replaced := make([]int8, len(arr)) + + v.EachInt8(func(index int, val int8) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt8 uses the specified collector function to collect a value +// for each of the int8s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt8(collector func(int, int8) interface{}) *Value { + + arr := v.MustInt8Slice() + collected := make([]interface{}, len(arr)) + + v.EachInt8(func(index int, val int8) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int16 (int16 and []int16) + -------------------------------------------------- +*/ + +// Int16 gets the value as a int16, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int16(optionalDefault ...int16) int16 { + if s, ok := v.data.(int16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt16 gets the value as a int16. +// +// Panics if the object is not a int16. +func (v *Value) MustInt16() int16 { + return v.data.(int16) +} + +// Int16Slice gets the value as a []int16, returns the optionalDefault +// value or nil if the value is not a []int16. +func (v *Value) Int16Slice(optionalDefault ...[]int16) []int16 { + if s, ok := v.data.([]int16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt16Slice gets the value as a []int16. +// +// Panics if the object is not a []int16. +func (v *Value) MustInt16Slice() []int16 { + return v.data.([]int16) +} + +// IsInt16 gets whether the object contained is a int16 or not. +func (v *Value) IsInt16() bool { + _, ok := v.data.(int16) + return ok +} + +// IsInt16Slice gets whether the object contained is a []int16 or not. +func (v *Value) IsInt16Slice() bool { + _, ok := v.data.([]int16) + return ok +} + +// EachInt16 calls the specified callback for each object +// in the []int16. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt16(callback func(int, int16) bool) *Value { + + for index, val := range v.MustInt16Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt16 uses the specified decider function to select items +// from the []int16. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt16(decider func(int, int16) bool) *Value { + + var selected []int16 + + v.EachInt16(func(index int, val int16) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt16 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int16. +func (v *Value) GroupInt16(grouper func(int, int16) string) *Value { + + groups := make(map[string][]int16) + + v.EachInt16(func(index int, val int16) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int16, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt16 uses the specified function to replace each int16s +// by iterating each item. The data in the returned result will be a +// []int16 containing the replaced items. +func (v *Value) ReplaceInt16(replacer func(int, int16) int16) *Value { + + arr := v.MustInt16Slice() + replaced := make([]int16, len(arr)) + + v.EachInt16(func(index int, val int16) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt16 uses the specified collector function to collect a value +// for each of the int16s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt16(collector func(int, int16) interface{}) *Value { + + arr := v.MustInt16Slice() + collected := make([]interface{}, len(arr)) + + v.EachInt16(func(index int, val int16) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int32 (int32 and []int32) + -------------------------------------------------- +*/ + +// Int32 gets the value as a int32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int32(optionalDefault ...int32) int32 { + if s, ok := v.data.(int32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt32 gets the value as a int32. +// +// Panics if the object is not a int32. +func (v *Value) MustInt32() int32 { + return v.data.(int32) +} + +// Int32Slice gets the value as a []int32, returns the optionalDefault +// value or nil if the value is not a []int32. +func (v *Value) Int32Slice(optionalDefault ...[]int32) []int32 { + if s, ok := v.data.([]int32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt32Slice gets the value as a []int32. +// +// Panics if the object is not a []int32. +func (v *Value) MustInt32Slice() []int32 { + return v.data.([]int32) +} + +// IsInt32 gets whether the object contained is a int32 or not. +func (v *Value) IsInt32() bool { + _, ok := v.data.(int32) + return ok +} + +// IsInt32Slice gets whether the object contained is a []int32 or not. +func (v *Value) IsInt32Slice() bool { + _, ok := v.data.([]int32) + return ok +} + +// EachInt32 calls the specified callback for each object +// in the []int32. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt32(callback func(int, int32) bool) *Value { + + for index, val := range v.MustInt32Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt32 uses the specified decider function to select items +// from the []int32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt32(decider func(int, int32) bool) *Value { + + var selected []int32 + + v.EachInt32(func(index int, val int32) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int32. +func (v *Value) GroupInt32(grouper func(int, int32) string) *Value { + + groups := make(map[string][]int32) + + v.EachInt32(func(index int, val int32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt32 uses the specified function to replace each int32s +// by iterating each item. The data in the returned result will be a +// []int32 containing the replaced items. +func (v *Value) ReplaceInt32(replacer func(int, int32) int32) *Value { + + arr := v.MustInt32Slice() + replaced := make([]int32, len(arr)) + + v.EachInt32(func(index int, val int32) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt32 uses the specified collector function to collect a value +// for each of the int32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt32(collector func(int, int32) interface{}) *Value { + + arr := v.MustInt32Slice() + collected := make([]interface{}, len(arr)) + + v.EachInt32(func(index int, val int32) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int64 (int64 and []int64) + -------------------------------------------------- +*/ + +// Int64 gets the value as a int64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int64(optionalDefault ...int64) int64 { + if s, ok := v.data.(int64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt64 gets the value as a int64. +// +// Panics if the object is not a int64. +func (v *Value) MustInt64() int64 { + return v.data.(int64) +} + +// Int64Slice gets the value as a []int64, returns the optionalDefault +// value or nil if the value is not a []int64. +func (v *Value) Int64Slice(optionalDefault ...[]int64) []int64 { + if s, ok := v.data.([]int64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt64Slice gets the value as a []int64. +// +// Panics if the object is not a []int64. +func (v *Value) MustInt64Slice() []int64 { + return v.data.([]int64) +} + +// IsInt64 gets whether the object contained is a int64 or not. +func (v *Value) IsInt64() bool { + _, ok := v.data.(int64) + return ok +} + +// IsInt64Slice gets whether the object contained is a []int64 or not. +func (v *Value) IsInt64Slice() bool { + _, ok := v.data.([]int64) + return ok +} + +// EachInt64 calls the specified callback for each object +// in the []int64. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt64(callback func(int, int64) bool) *Value { + + for index, val := range v.MustInt64Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt64 uses the specified decider function to select items +// from the []int64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt64(decider func(int, int64) bool) *Value { + + var selected []int64 + + v.EachInt64(func(index int, val int64) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int64. +func (v *Value) GroupInt64(grouper func(int, int64) string) *Value { + + groups := make(map[string][]int64) + + v.EachInt64(func(index int, val int64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt64 uses the specified function to replace each int64s +// by iterating each item. The data in the returned result will be a +// []int64 containing the replaced items. +func (v *Value) ReplaceInt64(replacer func(int, int64) int64) *Value { + + arr := v.MustInt64Slice() + replaced := make([]int64, len(arr)) + + v.EachInt64(func(index int, val int64) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt64 uses the specified collector function to collect a value +// for each of the int64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt64(collector func(int, int64) interface{}) *Value { + + arr := v.MustInt64Slice() + collected := make([]interface{}, len(arr)) + + v.EachInt64(func(index int, val int64) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint (uint and []uint) + -------------------------------------------------- +*/ + +// Uint gets the value as a uint, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint(optionalDefault ...uint) uint { + if s, ok := v.data.(uint); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint gets the value as a uint. +// +// Panics if the object is not a uint. +func (v *Value) MustUint() uint { + return v.data.(uint) +} + +// UintSlice gets the value as a []uint, returns the optionalDefault +// value or nil if the value is not a []uint. +func (v *Value) UintSlice(optionalDefault ...[]uint) []uint { + if s, ok := v.data.([]uint); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUintSlice gets the value as a []uint. +// +// Panics if the object is not a []uint. +func (v *Value) MustUintSlice() []uint { + return v.data.([]uint) +} + +// IsUint gets whether the object contained is a uint or not. +func (v *Value) IsUint() bool { + _, ok := v.data.(uint) + return ok +} + +// IsUintSlice gets whether the object contained is a []uint or not. +func (v *Value) IsUintSlice() bool { + _, ok := v.data.([]uint) + return ok +} + +// EachUint calls the specified callback for each object +// in the []uint. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint(callback func(int, uint) bool) *Value { + + for index, val := range v.MustUintSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint uses the specified decider function to select items +// from the []uint. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint(decider func(int, uint) bool) *Value { + + var selected []uint + + v.EachUint(func(index int, val uint) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint. +func (v *Value) GroupUint(grouper func(int, uint) string) *Value { + + groups := make(map[string][]uint) + + v.EachUint(func(index int, val uint) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint uses the specified function to replace each uints +// by iterating each item. The data in the returned result will be a +// []uint containing the replaced items. +func (v *Value) ReplaceUint(replacer func(int, uint) uint) *Value { + + arr := v.MustUintSlice() + replaced := make([]uint, len(arr)) + + v.EachUint(func(index int, val uint) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint uses the specified collector function to collect a value +// for each of the uints in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint(collector func(int, uint) interface{}) *Value { + + arr := v.MustUintSlice() + collected := make([]interface{}, len(arr)) + + v.EachUint(func(index int, val uint) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint8 (uint8 and []uint8) + -------------------------------------------------- +*/ + +// Uint8 gets the value as a uint8, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint8(optionalDefault ...uint8) uint8 { + if s, ok := v.data.(uint8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint8 gets the value as a uint8. +// +// Panics if the object is not a uint8. +func (v *Value) MustUint8() uint8 { + return v.data.(uint8) +} + +// Uint8Slice gets the value as a []uint8, returns the optionalDefault +// value or nil if the value is not a []uint8. +func (v *Value) Uint8Slice(optionalDefault ...[]uint8) []uint8 { + if s, ok := v.data.([]uint8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint8Slice gets the value as a []uint8. +// +// Panics if the object is not a []uint8. +func (v *Value) MustUint8Slice() []uint8 { + return v.data.([]uint8) +} + +// IsUint8 gets whether the object contained is a uint8 or not. +func (v *Value) IsUint8() bool { + _, ok := v.data.(uint8) + return ok +} + +// IsUint8Slice gets whether the object contained is a []uint8 or not. +func (v *Value) IsUint8Slice() bool { + _, ok := v.data.([]uint8) + return ok +} + +// EachUint8 calls the specified callback for each object +// in the []uint8. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint8(callback func(int, uint8) bool) *Value { + + for index, val := range v.MustUint8Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint8 uses the specified decider function to select items +// from the []uint8. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint8(decider func(int, uint8) bool) *Value { + + var selected []uint8 + + v.EachUint8(func(index int, val uint8) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint8 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint8. +func (v *Value) GroupUint8(grouper func(int, uint8) string) *Value { + + groups := make(map[string][]uint8) + + v.EachUint8(func(index int, val uint8) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint8, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint8 uses the specified function to replace each uint8s +// by iterating each item. The data in the returned result will be a +// []uint8 containing the replaced items. +func (v *Value) ReplaceUint8(replacer func(int, uint8) uint8) *Value { + + arr := v.MustUint8Slice() + replaced := make([]uint8, len(arr)) + + v.EachUint8(func(index int, val uint8) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint8 uses the specified collector function to collect a value +// for each of the uint8s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint8(collector func(int, uint8) interface{}) *Value { + + arr := v.MustUint8Slice() + collected := make([]interface{}, len(arr)) + + v.EachUint8(func(index int, val uint8) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint16 (uint16 and []uint16) + -------------------------------------------------- +*/ + +// Uint16 gets the value as a uint16, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint16(optionalDefault ...uint16) uint16 { + if s, ok := v.data.(uint16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint16 gets the value as a uint16. +// +// Panics if the object is not a uint16. +func (v *Value) MustUint16() uint16 { + return v.data.(uint16) +} + +// Uint16Slice gets the value as a []uint16, returns the optionalDefault +// value or nil if the value is not a []uint16. +func (v *Value) Uint16Slice(optionalDefault ...[]uint16) []uint16 { + if s, ok := v.data.([]uint16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint16Slice gets the value as a []uint16. +// +// Panics if the object is not a []uint16. +func (v *Value) MustUint16Slice() []uint16 { + return v.data.([]uint16) +} + +// IsUint16 gets whether the object contained is a uint16 or not. +func (v *Value) IsUint16() bool { + _, ok := v.data.(uint16) + return ok +} + +// IsUint16Slice gets whether the object contained is a []uint16 or not. +func (v *Value) IsUint16Slice() bool { + _, ok := v.data.([]uint16) + return ok +} + +// EachUint16 calls the specified callback for each object +// in the []uint16. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint16(callback func(int, uint16) bool) *Value { + + for index, val := range v.MustUint16Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint16 uses the specified decider function to select items +// from the []uint16. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint16(decider func(int, uint16) bool) *Value { + + var selected []uint16 + + v.EachUint16(func(index int, val uint16) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint16 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint16. +func (v *Value) GroupUint16(grouper func(int, uint16) string) *Value { + + groups := make(map[string][]uint16) + + v.EachUint16(func(index int, val uint16) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint16, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint16 uses the specified function to replace each uint16s +// by iterating each item. The data in the returned result will be a +// []uint16 containing the replaced items. +func (v *Value) ReplaceUint16(replacer func(int, uint16) uint16) *Value { + + arr := v.MustUint16Slice() + replaced := make([]uint16, len(arr)) + + v.EachUint16(func(index int, val uint16) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint16 uses the specified collector function to collect a value +// for each of the uint16s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint16(collector func(int, uint16) interface{}) *Value { + + arr := v.MustUint16Slice() + collected := make([]interface{}, len(arr)) + + v.EachUint16(func(index int, val uint16) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint32 (uint32 and []uint32) + -------------------------------------------------- +*/ + +// Uint32 gets the value as a uint32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint32(optionalDefault ...uint32) uint32 { + if s, ok := v.data.(uint32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint32 gets the value as a uint32. +// +// Panics if the object is not a uint32. +func (v *Value) MustUint32() uint32 { + return v.data.(uint32) +} + +// Uint32Slice gets the value as a []uint32, returns the optionalDefault +// value or nil if the value is not a []uint32. +func (v *Value) Uint32Slice(optionalDefault ...[]uint32) []uint32 { + if s, ok := v.data.([]uint32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint32Slice gets the value as a []uint32. +// +// Panics if the object is not a []uint32. +func (v *Value) MustUint32Slice() []uint32 { + return v.data.([]uint32) +} + +// IsUint32 gets whether the object contained is a uint32 or not. +func (v *Value) IsUint32() bool { + _, ok := v.data.(uint32) + return ok +} + +// IsUint32Slice gets whether the object contained is a []uint32 or not. +func (v *Value) IsUint32Slice() bool { + _, ok := v.data.([]uint32) + return ok +} + +// EachUint32 calls the specified callback for each object +// in the []uint32. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint32(callback func(int, uint32) bool) *Value { + + for index, val := range v.MustUint32Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint32 uses the specified decider function to select items +// from the []uint32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint32(decider func(int, uint32) bool) *Value { + + var selected []uint32 + + v.EachUint32(func(index int, val uint32) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint32. +func (v *Value) GroupUint32(grouper func(int, uint32) string) *Value { + + groups := make(map[string][]uint32) + + v.EachUint32(func(index int, val uint32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint32 uses the specified function to replace each uint32s +// by iterating each item. The data in the returned result will be a +// []uint32 containing the replaced items. +func (v *Value) ReplaceUint32(replacer func(int, uint32) uint32) *Value { + + arr := v.MustUint32Slice() + replaced := make([]uint32, len(arr)) + + v.EachUint32(func(index int, val uint32) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint32 uses the specified collector function to collect a value +// for each of the uint32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint32(collector func(int, uint32) interface{}) *Value { + + arr := v.MustUint32Slice() + collected := make([]interface{}, len(arr)) + + v.EachUint32(func(index int, val uint32) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint64 (uint64 and []uint64) + -------------------------------------------------- +*/ + +// Uint64 gets the value as a uint64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint64(optionalDefault ...uint64) uint64 { + if s, ok := v.data.(uint64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint64 gets the value as a uint64. +// +// Panics if the object is not a uint64. +func (v *Value) MustUint64() uint64 { + return v.data.(uint64) +} + +// Uint64Slice gets the value as a []uint64, returns the optionalDefault +// value or nil if the value is not a []uint64. +func (v *Value) Uint64Slice(optionalDefault ...[]uint64) []uint64 { + if s, ok := v.data.([]uint64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint64Slice gets the value as a []uint64. +// +// Panics if the object is not a []uint64. +func (v *Value) MustUint64Slice() []uint64 { + return v.data.([]uint64) +} + +// IsUint64 gets whether the object contained is a uint64 or not. +func (v *Value) IsUint64() bool { + _, ok := v.data.(uint64) + return ok +} + +// IsUint64Slice gets whether the object contained is a []uint64 or not. +func (v *Value) IsUint64Slice() bool { + _, ok := v.data.([]uint64) + return ok +} + +// EachUint64 calls the specified callback for each object +// in the []uint64. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint64(callback func(int, uint64) bool) *Value { + + for index, val := range v.MustUint64Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint64 uses the specified decider function to select items +// from the []uint64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint64(decider func(int, uint64) bool) *Value { + + var selected []uint64 + + v.EachUint64(func(index int, val uint64) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint64. +func (v *Value) GroupUint64(grouper func(int, uint64) string) *Value { + + groups := make(map[string][]uint64) + + v.EachUint64(func(index int, val uint64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint64 uses the specified function to replace each uint64s +// by iterating each item. The data in the returned result will be a +// []uint64 containing the replaced items. +func (v *Value) ReplaceUint64(replacer func(int, uint64) uint64) *Value { + + arr := v.MustUint64Slice() + replaced := make([]uint64, len(arr)) + + v.EachUint64(func(index int, val uint64) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint64 uses the specified collector function to collect a value +// for each of the uint64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint64(collector func(int, uint64) interface{}) *Value { + + arr := v.MustUint64Slice() + collected := make([]interface{}, len(arr)) + + v.EachUint64(func(index int, val uint64) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uintptr (uintptr and []uintptr) + -------------------------------------------------- +*/ + +// Uintptr gets the value as a uintptr, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uintptr(optionalDefault ...uintptr) uintptr { + if s, ok := v.data.(uintptr); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUintptr gets the value as a uintptr. +// +// Panics if the object is not a uintptr. +func (v *Value) MustUintptr() uintptr { + return v.data.(uintptr) +} + +// UintptrSlice gets the value as a []uintptr, returns the optionalDefault +// value or nil if the value is not a []uintptr. +func (v *Value) UintptrSlice(optionalDefault ...[]uintptr) []uintptr { + if s, ok := v.data.([]uintptr); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUintptrSlice gets the value as a []uintptr. +// +// Panics if the object is not a []uintptr. +func (v *Value) MustUintptrSlice() []uintptr { + return v.data.([]uintptr) +} + +// IsUintptr gets whether the object contained is a uintptr or not. +func (v *Value) IsUintptr() bool { + _, ok := v.data.(uintptr) + return ok +} + +// IsUintptrSlice gets whether the object contained is a []uintptr or not. +func (v *Value) IsUintptrSlice() bool { + _, ok := v.data.([]uintptr) + return ok +} + +// EachUintptr calls the specified callback for each object +// in the []uintptr. +// +// Panics if the object is the wrong type. +func (v *Value) EachUintptr(callback func(int, uintptr) bool) *Value { + + for index, val := range v.MustUintptrSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUintptr uses the specified decider function to select items +// from the []uintptr. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUintptr(decider func(int, uintptr) bool) *Value { + + var selected []uintptr + + v.EachUintptr(func(index int, val uintptr) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUintptr uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uintptr. +func (v *Value) GroupUintptr(grouper func(int, uintptr) string) *Value { + + groups := make(map[string][]uintptr) + + v.EachUintptr(func(index int, val uintptr) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uintptr, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUintptr uses the specified function to replace each uintptrs +// by iterating each item. The data in the returned result will be a +// []uintptr containing the replaced items. +func (v *Value) ReplaceUintptr(replacer func(int, uintptr) uintptr) *Value { + + arr := v.MustUintptrSlice() + replaced := make([]uintptr, len(arr)) + + v.EachUintptr(func(index int, val uintptr) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUintptr uses the specified collector function to collect a value +// for each of the uintptrs in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUintptr(collector func(int, uintptr) interface{}) *Value { + + arr := v.MustUintptrSlice() + collected := make([]interface{}, len(arr)) + + v.EachUintptr(func(index int, val uintptr) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Float32 (float32 and []float32) + -------------------------------------------------- +*/ + +// Float32 gets the value as a float32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Float32(optionalDefault ...float32) float32 { + if s, ok := v.data.(float32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustFloat32 gets the value as a float32. +// +// Panics if the object is not a float32. +func (v *Value) MustFloat32() float32 { + return v.data.(float32) +} + +// Float32Slice gets the value as a []float32, returns the optionalDefault +// value or nil if the value is not a []float32. +func (v *Value) Float32Slice(optionalDefault ...[]float32) []float32 { + if s, ok := v.data.([]float32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustFloat32Slice gets the value as a []float32. +// +// Panics if the object is not a []float32. +func (v *Value) MustFloat32Slice() []float32 { + return v.data.([]float32) +} + +// IsFloat32 gets whether the object contained is a float32 or not. +func (v *Value) IsFloat32() bool { + _, ok := v.data.(float32) + return ok +} + +// IsFloat32Slice gets whether the object contained is a []float32 or not. +func (v *Value) IsFloat32Slice() bool { + _, ok := v.data.([]float32) + return ok +} + +// EachFloat32 calls the specified callback for each object +// in the []float32. +// +// Panics if the object is the wrong type. +func (v *Value) EachFloat32(callback func(int, float32) bool) *Value { + + for index, val := range v.MustFloat32Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereFloat32 uses the specified decider function to select items +// from the []float32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereFloat32(decider func(int, float32) bool) *Value { + + var selected []float32 + + v.EachFloat32(func(index int, val float32) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupFloat32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]float32. +func (v *Value) GroupFloat32(grouper func(int, float32) string) *Value { + + groups := make(map[string][]float32) + + v.EachFloat32(func(index int, val float32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]float32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceFloat32 uses the specified function to replace each float32s +// by iterating each item. The data in the returned result will be a +// []float32 containing the replaced items. +func (v *Value) ReplaceFloat32(replacer func(int, float32) float32) *Value { + + arr := v.MustFloat32Slice() + replaced := make([]float32, len(arr)) + + v.EachFloat32(func(index int, val float32) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectFloat32 uses the specified collector function to collect a value +// for each of the float32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectFloat32(collector func(int, float32) interface{}) *Value { + + arr := v.MustFloat32Slice() + collected := make([]interface{}, len(arr)) + + v.EachFloat32(func(index int, val float32) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Float64 (float64 and []float64) + -------------------------------------------------- +*/ + +// Float64 gets the value as a float64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Float64(optionalDefault ...float64) float64 { + if s, ok := v.data.(float64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustFloat64 gets the value as a float64. +// +// Panics if the object is not a float64. +func (v *Value) MustFloat64() float64 { + return v.data.(float64) +} + +// Float64Slice gets the value as a []float64, returns the optionalDefault +// value or nil if the value is not a []float64. +func (v *Value) Float64Slice(optionalDefault ...[]float64) []float64 { + if s, ok := v.data.([]float64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustFloat64Slice gets the value as a []float64. +// +// Panics if the object is not a []float64. +func (v *Value) MustFloat64Slice() []float64 { + return v.data.([]float64) +} + +// IsFloat64 gets whether the object contained is a float64 or not. +func (v *Value) IsFloat64() bool { + _, ok := v.data.(float64) + return ok +} + +// IsFloat64Slice gets whether the object contained is a []float64 or not. +func (v *Value) IsFloat64Slice() bool { + _, ok := v.data.([]float64) + return ok +} + +// EachFloat64 calls the specified callback for each object +// in the []float64. +// +// Panics if the object is the wrong type. +func (v *Value) EachFloat64(callback func(int, float64) bool) *Value { + + for index, val := range v.MustFloat64Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereFloat64 uses the specified decider function to select items +// from the []float64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereFloat64(decider func(int, float64) bool) *Value { + + var selected []float64 + + v.EachFloat64(func(index int, val float64) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupFloat64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]float64. +func (v *Value) GroupFloat64(grouper func(int, float64) string) *Value { + + groups := make(map[string][]float64) + + v.EachFloat64(func(index int, val float64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]float64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceFloat64 uses the specified function to replace each float64s +// by iterating each item. The data in the returned result will be a +// []float64 containing the replaced items. +func (v *Value) ReplaceFloat64(replacer func(int, float64) float64) *Value { + + arr := v.MustFloat64Slice() + replaced := make([]float64, len(arr)) + + v.EachFloat64(func(index int, val float64) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectFloat64 uses the specified collector function to collect a value +// for each of the float64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectFloat64(collector func(int, float64) interface{}) *Value { + + arr := v.MustFloat64Slice() + collected := make([]interface{}, len(arr)) + + v.EachFloat64(func(index int, val float64) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Complex64 (complex64 and []complex64) + -------------------------------------------------- +*/ + +// Complex64 gets the value as a complex64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Complex64(optionalDefault ...complex64) complex64 { + if s, ok := v.data.(complex64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustComplex64 gets the value as a complex64. +// +// Panics if the object is not a complex64. +func (v *Value) MustComplex64() complex64 { + return v.data.(complex64) +} + +// Complex64Slice gets the value as a []complex64, returns the optionalDefault +// value or nil if the value is not a []complex64. +func (v *Value) Complex64Slice(optionalDefault ...[]complex64) []complex64 { + if s, ok := v.data.([]complex64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustComplex64Slice gets the value as a []complex64. +// +// Panics if the object is not a []complex64. +func (v *Value) MustComplex64Slice() []complex64 { + return v.data.([]complex64) +} + +// IsComplex64 gets whether the object contained is a complex64 or not. +func (v *Value) IsComplex64() bool { + _, ok := v.data.(complex64) + return ok +} + +// IsComplex64Slice gets whether the object contained is a []complex64 or not. +func (v *Value) IsComplex64Slice() bool { + _, ok := v.data.([]complex64) + return ok +} + +// EachComplex64 calls the specified callback for each object +// in the []complex64. +// +// Panics if the object is the wrong type. +func (v *Value) EachComplex64(callback func(int, complex64) bool) *Value { + + for index, val := range v.MustComplex64Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereComplex64 uses the specified decider function to select items +// from the []complex64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereComplex64(decider func(int, complex64) bool) *Value { + + var selected []complex64 + + v.EachComplex64(func(index int, val complex64) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupComplex64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]complex64. +func (v *Value) GroupComplex64(grouper func(int, complex64) string) *Value { + + groups := make(map[string][]complex64) + + v.EachComplex64(func(index int, val complex64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]complex64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceComplex64 uses the specified function to replace each complex64s +// by iterating each item. The data in the returned result will be a +// []complex64 containing the replaced items. +func (v *Value) ReplaceComplex64(replacer func(int, complex64) complex64) *Value { + + arr := v.MustComplex64Slice() + replaced := make([]complex64, len(arr)) + + v.EachComplex64(func(index int, val complex64) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectComplex64 uses the specified collector function to collect a value +// for each of the complex64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectComplex64(collector func(int, complex64) interface{}) *Value { + + arr := v.MustComplex64Slice() + collected := make([]interface{}, len(arr)) + + v.EachComplex64(func(index int, val complex64) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Complex128 (complex128 and []complex128) + -------------------------------------------------- +*/ + +// Complex128 gets the value as a complex128, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Complex128(optionalDefault ...complex128) complex128 { + if s, ok := v.data.(complex128); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustComplex128 gets the value as a complex128. +// +// Panics if the object is not a complex128. +func (v *Value) MustComplex128() complex128 { + return v.data.(complex128) +} + +// Complex128Slice gets the value as a []complex128, returns the optionalDefault +// value or nil if the value is not a []complex128. +func (v *Value) Complex128Slice(optionalDefault ...[]complex128) []complex128 { + if s, ok := v.data.([]complex128); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustComplex128Slice gets the value as a []complex128. +// +// Panics if the object is not a []complex128. +func (v *Value) MustComplex128Slice() []complex128 { + return v.data.([]complex128) +} + +// IsComplex128 gets whether the object contained is a complex128 or not. +func (v *Value) IsComplex128() bool { + _, ok := v.data.(complex128) + return ok +} + +// IsComplex128Slice gets whether the object contained is a []complex128 or not. +func (v *Value) IsComplex128Slice() bool { + _, ok := v.data.([]complex128) + return ok +} + +// EachComplex128 calls the specified callback for each object +// in the []complex128. +// +// Panics if the object is the wrong type. +func (v *Value) EachComplex128(callback func(int, complex128) bool) *Value { + + for index, val := range v.MustComplex128Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereComplex128 uses the specified decider function to select items +// from the []complex128. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereComplex128(decider func(int, complex128) bool) *Value { + + var selected []complex128 + + v.EachComplex128(func(index int, val complex128) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupComplex128 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]complex128. +func (v *Value) GroupComplex128(grouper func(int, complex128) string) *Value { + + groups := make(map[string][]complex128) + + v.EachComplex128(func(index int, val complex128) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]complex128, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceComplex128 uses the specified function to replace each complex128s +// by iterating each item. The data in the returned result will be a +// []complex128 containing the replaced items. +func (v *Value) ReplaceComplex128(replacer func(int, complex128) complex128) *Value { + + arr := v.MustComplex128Slice() + replaced := make([]complex128, len(arr)) + + v.EachComplex128(func(index int, val complex128) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectComplex128 uses the specified collector function to collect a value +// for each of the complex128s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectComplex128(collector func(int, complex128) interface{}) *Value { + + arr := v.MustComplex128Slice() + collected := make([]interface{}, len(arr)) + + v.EachComplex128(func(index int, val complex128) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen_test.go new file mode 100644 index 000000000..f7a4fceea --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen_test.go @@ -0,0 +1,2867 @@ +package objx + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "testing" +) + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestInter(t *testing.T) { + + val := interface{}("something") + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Inter()) + assert.Equal(t, val, New(m).Get("value").MustInter()) + assert.Equal(t, interface{}(nil), New(m).Get("nothing").Inter()) + assert.Equal(t, val, New(m).Get("nothing").Inter("something")) + + assert.Panics(t, func() { + New(m).Get("age").MustInter() + }) + +} + +func TestInterSlice(t *testing.T) { + + val := interface{}("something") + m := map[string]interface{}{"value": []interface{}{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").InterSlice()[0]) + assert.Equal(t, val, New(m).Get("value").MustInterSlice()[0]) + assert.Equal(t, []interface{}(nil), New(m).Get("nothing").InterSlice()) + assert.Equal(t, val, New(m).Get("nothing").InterSlice([]interface{}{interface{}("something")})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustInterSlice() + }) + +} + +func TestIsInter(t *testing.T) { + + var v *Value + + v = &Value{data: interface{}("something")} + assert.True(t, v.IsInter()) + + v = &Value{data: []interface{}{interface{}("something")}} + assert.True(t, v.IsInterSlice()) + +} + +func TestEachInter(t *testing.T) { + + v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}} + count := 0 + replacedVals := make([]interface{}, 0) + assert.Equal(t, v, v.EachInter(func(i int, val interface{}) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustInterSlice()[0]) + assert.Equal(t, replacedVals[1], v.MustInterSlice()[1]) + assert.Equal(t, replacedVals[2], v.MustInterSlice()[2]) + +} + +func TestWhereInter(t *testing.T) { + + v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}} + + selected := v.WhereInter(func(i int, val interface{}) bool { + return i%2 == 0 + }).MustInterSlice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupInter(t *testing.T) { + + v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}} + + grouped := v.GroupInter(func(i int, val interface{}) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]interface{}) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceInter(t *testing.T) { + + v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}} + + rawArr := v.MustInterSlice() + + replaced := v.ReplaceInter(func(index int, val interface{}) interface{} { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustInterSlice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectInter(t *testing.T) { + + v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}} + + collected := v.CollectInter(func(index int, val interface{}) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestMSI(t *testing.T) { + + val := map[string]interface{}(map[string]interface{}{"name": "Tyler"}) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").MSI()) + assert.Equal(t, val, New(m).Get("value").MustMSI()) + assert.Equal(t, map[string]interface{}(nil), New(m).Get("nothing").MSI()) + assert.Equal(t, val, New(m).Get("nothing").MSI(map[string]interface{}{"name": "Tyler"})) + + assert.Panics(t, func() { + New(m).Get("age").MustMSI() + }) + +} + +func TestMSISlice(t *testing.T) { + + val := map[string]interface{}(map[string]interface{}{"name": "Tyler"}) + m := map[string]interface{}{"value": []map[string]interface{}{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").MSISlice()[0]) + assert.Equal(t, val, New(m).Get("value").MustMSISlice()[0]) + assert.Equal(t, []map[string]interface{}(nil), New(m).Get("nothing").MSISlice()) + assert.Equal(t, val, New(m).Get("nothing").MSISlice([]map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"})})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustMSISlice() + }) + +} + +func TestIsMSI(t *testing.T) { + + var v *Value + + v = &Value{data: map[string]interface{}(map[string]interface{}{"name": "Tyler"})} + assert.True(t, v.IsMSI()) + + v = &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"})}} + assert.True(t, v.IsMSISlice()) + +} + +func TestEachMSI(t *testing.T) { + + v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}} + count := 0 + replacedVals := make([]map[string]interface{}, 0) + assert.Equal(t, v, v.EachMSI(func(i int, val map[string]interface{}) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustMSISlice()[0]) + assert.Equal(t, replacedVals[1], v.MustMSISlice()[1]) + assert.Equal(t, replacedVals[2], v.MustMSISlice()[2]) + +} + +func TestWhereMSI(t *testing.T) { + + v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}} + + selected := v.WhereMSI(func(i int, val map[string]interface{}) bool { + return i%2 == 0 + }).MustMSISlice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupMSI(t *testing.T) { + + v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}} + + grouped := v.GroupMSI(func(i int, val map[string]interface{}) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]map[string]interface{}) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceMSI(t *testing.T) { + + v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}} + + rawArr := v.MustMSISlice() + + replaced := v.ReplaceMSI(func(index int, val map[string]interface{}) map[string]interface{} { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustMSISlice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectMSI(t *testing.T) { + + v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}} + + collected := v.CollectMSI(func(index int, val map[string]interface{}) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestObjxMap(t *testing.T) { + + val := (Map)(New(1)) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").ObjxMap()) + assert.Equal(t, val, New(m).Get("value").MustObjxMap()) + assert.Equal(t, (Map)(New(nil)), New(m).Get("nothing").ObjxMap()) + assert.Equal(t, val, New(m).Get("nothing").ObjxMap(New(1))) + + assert.Panics(t, func() { + New(m).Get("age").MustObjxMap() + }) + +} + +func TestObjxMapSlice(t *testing.T) { + + val := (Map)(New(1)) + m := map[string]interface{}{"value": [](Map){val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").ObjxMapSlice()[0]) + assert.Equal(t, val, New(m).Get("value").MustObjxMapSlice()[0]) + assert.Equal(t, [](Map)(nil), New(m).Get("nothing").ObjxMapSlice()) + assert.Equal(t, val, New(m).Get("nothing").ObjxMapSlice([](Map){(Map)(New(1))})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustObjxMapSlice() + }) + +} + +func TestIsObjxMap(t *testing.T) { + + var v *Value + + v = &Value{data: (Map)(New(1))} + assert.True(t, v.IsObjxMap()) + + v = &Value{data: [](Map){(Map)(New(1))}} + assert.True(t, v.IsObjxMapSlice()) + +} + +func TestEachObjxMap(t *testing.T) { + + v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}} + count := 0 + replacedVals := make([](Map), 0) + assert.Equal(t, v, v.EachObjxMap(func(i int, val Map) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustObjxMapSlice()[0]) + assert.Equal(t, replacedVals[1], v.MustObjxMapSlice()[1]) + assert.Equal(t, replacedVals[2], v.MustObjxMapSlice()[2]) + +} + +func TestWhereObjxMap(t *testing.T) { + + v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}} + + selected := v.WhereObjxMap(func(i int, val Map) bool { + return i%2 == 0 + }).MustObjxMapSlice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupObjxMap(t *testing.T) { + + v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}} + + grouped := v.GroupObjxMap(func(i int, val Map) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][](Map)) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceObjxMap(t *testing.T) { + + v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}} + + rawArr := v.MustObjxMapSlice() + + replaced := v.ReplaceObjxMap(func(index int, val Map) Map { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustObjxMapSlice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectObjxMap(t *testing.T) { + + v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}} + + collected := v.CollectObjxMap(func(index int, val Map) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestBool(t *testing.T) { + + val := bool(true) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Bool()) + assert.Equal(t, val, New(m).Get("value").MustBool()) + assert.Equal(t, bool(false), New(m).Get("nothing").Bool()) + assert.Equal(t, val, New(m).Get("nothing").Bool(true)) + + assert.Panics(t, func() { + New(m).Get("age").MustBool() + }) + +} + +func TestBoolSlice(t *testing.T) { + + val := bool(true) + m := map[string]interface{}{"value": []bool{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").BoolSlice()[0]) + assert.Equal(t, val, New(m).Get("value").MustBoolSlice()[0]) + assert.Equal(t, []bool(nil), New(m).Get("nothing").BoolSlice()) + assert.Equal(t, val, New(m).Get("nothing").BoolSlice([]bool{bool(true)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustBoolSlice() + }) + +} + +func TestIsBool(t *testing.T) { + + var v *Value + + v = &Value{data: bool(true)} + assert.True(t, v.IsBool()) + + v = &Value{data: []bool{bool(true)}} + assert.True(t, v.IsBoolSlice()) + +} + +func TestEachBool(t *testing.T) { + + v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true)}} + count := 0 + replacedVals := make([]bool, 0) + assert.Equal(t, v, v.EachBool(func(i int, val bool) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustBoolSlice()[0]) + assert.Equal(t, replacedVals[1], v.MustBoolSlice()[1]) + assert.Equal(t, replacedVals[2], v.MustBoolSlice()[2]) + +} + +func TestWhereBool(t *testing.T) { + + v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true), bool(true)}} + + selected := v.WhereBool(func(i int, val bool) bool { + return i%2 == 0 + }).MustBoolSlice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupBool(t *testing.T) { + + v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true), bool(true)}} + + grouped := v.GroupBool(func(i int, val bool) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]bool) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceBool(t *testing.T) { + + v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true), bool(true)}} + + rawArr := v.MustBoolSlice() + + replaced := v.ReplaceBool(func(index int, val bool) bool { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustBoolSlice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectBool(t *testing.T) { + + v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true), bool(true)}} + + collected := v.CollectBool(func(index int, val bool) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestStr(t *testing.T) { + + val := string("hello") + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Str()) + assert.Equal(t, val, New(m).Get("value").MustStr()) + assert.Equal(t, string(""), New(m).Get("nothing").Str()) + assert.Equal(t, val, New(m).Get("nothing").Str("hello")) + + assert.Panics(t, func() { + New(m).Get("age").MustStr() + }) + +} + +func TestStrSlice(t *testing.T) { + + val := string("hello") + m := map[string]interface{}{"value": []string{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").StrSlice()[0]) + assert.Equal(t, val, New(m).Get("value").MustStrSlice()[0]) + assert.Equal(t, []string(nil), New(m).Get("nothing").StrSlice()) + assert.Equal(t, val, New(m).Get("nothing").StrSlice([]string{string("hello")})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustStrSlice() + }) + +} + +func TestIsStr(t *testing.T) { + + var v *Value + + v = &Value{data: string("hello")} + assert.True(t, v.IsStr()) + + v = &Value{data: []string{string("hello")}} + assert.True(t, v.IsStrSlice()) + +} + +func TestEachStr(t *testing.T) { + + v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}} + count := 0 + replacedVals := make([]string, 0) + assert.Equal(t, v, v.EachStr(func(i int, val string) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustStrSlice()[0]) + assert.Equal(t, replacedVals[1], v.MustStrSlice()[1]) + assert.Equal(t, replacedVals[2], v.MustStrSlice()[2]) + +} + +func TestWhereStr(t *testing.T) { + + v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}} + + selected := v.WhereStr(func(i int, val string) bool { + return i%2 == 0 + }).MustStrSlice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupStr(t *testing.T) { + + v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}} + + grouped := v.GroupStr(func(i int, val string) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]string) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceStr(t *testing.T) { + + v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}} + + rawArr := v.MustStrSlice() + + replaced := v.ReplaceStr(func(index int, val string) string { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustStrSlice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectStr(t *testing.T) { + + v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}} + + collected := v.CollectStr(func(index int, val string) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestInt(t *testing.T) { + + val := int(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int()) + assert.Equal(t, val, New(m).Get("value").MustInt()) + assert.Equal(t, int(0), New(m).Get("nothing").Int()) + assert.Equal(t, val, New(m).Get("nothing").Int(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustInt() + }) + +} + +func TestIntSlice(t *testing.T) { + + val := int(1) + m := map[string]interface{}{"value": []int{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").IntSlice()[0]) + assert.Equal(t, val, New(m).Get("value").MustIntSlice()[0]) + assert.Equal(t, []int(nil), New(m).Get("nothing").IntSlice()) + assert.Equal(t, val, New(m).Get("nothing").IntSlice([]int{int(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustIntSlice() + }) + +} + +func TestIsInt(t *testing.T) { + + var v *Value + + v = &Value{data: int(1)} + assert.True(t, v.IsInt()) + + v = &Value{data: []int{int(1)}} + assert.True(t, v.IsIntSlice()) + +} + +func TestEachInt(t *testing.T) { + + v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1)}} + count := 0 + replacedVals := make([]int, 0) + assert.Equal(t, v, v.EachInt(func(i int, val int) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustIntSlice()[0]) + assert.Equal(t, replacedVals[1], v.MustIntSlice()[1]) + assert.Equal(t, replacedVals[2], v.MustIntSlice()[2]) + +} + +func TestWhereInt(t *testing.T) { + + v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1), int(1)}} + + selected := v.WhereInt(func(i int, val int) bool { + return i%2 == 0 + }).MustIntSlice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupInt(t *testing.T) { + + v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1), int(1)}} + + grouped := v.GroupInt(func(i int, val int) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]int) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceInt(t *testing.T) { + + v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1), int(1)}} + + rawArr := v.MustIntSlice() + + replaced := v.ReplaceInt(func(index int, val int) int { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustIntSlice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectInt(t *testing.T) { + + v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1), int(1)}} + + collected := v.CollectInt(func(index int, val int) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestInt8(t *testing.T) { + + val := int8(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int8()) + assert.Equal(t, val, New(m).Get("value").MustInt8()) + assert.Equal(t, int8(0), New(m).Get("nothing").Int8()) + assert.Equal(t, val, New(m).Get("nothing").Int8(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustInt8() + }) + +} + +func TestInt8Slice(t *testing.T) { + + val := int8(1) + m := map[string]interface{}{"value": []int8{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int8Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustInt8Slice()[0]) + assert.Equal(t, []int8(nil), New(m).Get("nothing").Int8Slice()) + assert.Equal(t, val, New(m).Get("nothing").Int8Slice([]int8{int8(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustInt8Slice() + }) + +} + +func TestIsInt8(t *testing.T) { + + var v *Value + + v = &Value{data: int8(1)} + assert.True(t, v.IsInt8()) + + v = &Value{data: []int8{int8(1)}} + assert.True(t, v.IsInt8Slice()) + +} + +func TestEachInt8(t *testing.T) { + + v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1)}} + count := 0 + replacedVals := make([]int8, 0) + assert.Equal(t, v, v.EachInt8(func(i int, val int8) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustInt8Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustInt8Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustInt8Slice()[2]) + +} + +func TestWhereInt8(t *testing.T) { + + v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1), int8(1)}} + + selected := v.WhereInt8(func(i int, val int8) bool { + return i%2 == 0 + }).MustInt8Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupInt8(t *testing.T) { + + v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1), int8(1)}} + + grouped := v.GroupInt8(func(i int, val int8) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]int8) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceInt8(t *testing.T) { + + v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1), int8(1)}} + + rawArr := v.MustInt8Slice() + + replaced := v.ReplaceInt8(func(index int, val int8) int8 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustInt8Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectInt8(t *testing.T) { + + v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1), int8(1)}} + + collected := v.CollectInt8(func(index int, val int8) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestInt16(t *testing.T) { + + val := int16(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int16()) + assert.Equal(t, val, New(m).Get("value").MustInt16()) + assert.Equal(t, int16(0), New(m).Get("nothing").Int16()) + assert.Equal(t, val, New(m).Get("nothing").Int16(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustInt16() + }) + +} + +func TestInt16Slice(t *testing.T) { + + val := int16(1) + m := map[string]interface{}{"value": []int16{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int16Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustInt16Slice()[0]) + assert.Equal(t, []int16(nil), New(m).Get("nothing").Int16Slice()) + assert.Equal(t, val, New(m).Get("nothing").Int16Slice([]int16{int16(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustInt16Slice() + }) + +} + +func TestIsInt16(t *testing.T) { + + var v *Value + + v = &Value{data: int16(1)} + assert.True(t, v.IsInt16()) + + v = &Value{data: []int16{int16(1)}} + assert.True(t, v.IsInt16Slice()) + +} + +func TestEachInt16(t *testing.T) { + + v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1)}} + count := 0 + replacedVals := make([]int16, 0) + assert.Equal(t, v, v.EachInt16(func(i int, val int16) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustInt16Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustInt16Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustInt16Slice()[2]) + +} + +func TestWhereInt16(t *testing.T) { + + v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1), int16(1)}} + + selected := v.WhereInt16(func(i int, val int16) bool { + return i%2 == 0 + }).MustInt16Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupInt16(t *testing.T) { + + v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1), int16(1)}} + + grouped := v.GroupInt16(func(i int, val int16) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]int16) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceInt16(t *testing.T) { + + v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1), int16(1)}} + + rawArr := v.MustInt16Slice() + + replaced := v.ReplaceInt16(func(index int, val int16) int16 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustInt16Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectInt16(t *testing.T) { + + v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1), int16(1)}} + + collected := v.CollectInt16(func(index int, val int16) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestInt32(t *testing.T) { + + val := int32(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int32()) + assert.Equal(t, val, New(m).Get("value").MustInt32()) + assert.Equal(t, int32(0), New(m).Get("nothing").Int32()) + assert.Equal(t, val, New(m).Get("nothing").Int32(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustInt32() + }) + +} + +func TestInt32Slice(t *testing.T) { + + val := int32(1) + m := map[string]interface{}{"value": []int32{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int32Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustInt32Slice()[0]) + assert.Equal(t, []int32(nil), New(m).Get("nothing").Int32Slice()) + assert.Equal(t, val, New(m).Get("nothing").Int32Slice([]int32{int32(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustInt32Slice() + }) + +} + +func TestIsInt32(t *testing.T) { + + var v *Value + + v = &Value{data: int32(1)} + assert.True(t, v.IsInt32()) + + v = &Value{data: []int32{int32(1)}} + assert.True(t, v.IsInt32Slice()) + +} + +func TestEachInt32(t *testing.T) { + + v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1)}} + count := 0 + replacedVals := make([]int32, 0) + assert.Equal(t, v, v.EachInt32(func(i int, val int32) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustInt32Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustInt32Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustInt32Slice()[2]) + +} + +func TestWhereInt32(t *testing.T) { + + v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1), int32(1)}} + + selected := v.WhereInt32(func(i int, val int32) bool { + return i%2 == 0 + }).MustInt32Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupInt32(t *testing.T) { + + v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1), int32(1)}} + + grouped := v.GroupInt32(func(i int, val int32) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]int32) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceInt32(t *testing.T) { + + v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1), int32(1)}} + + rawArr := v.MustInt32Slice() + + replaced := v.ReplaceInt32(func(index int, val int32) int32 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustInt32Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectInt32(t *testing.T) { + + v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1), int32(1)}} + + collected := v.CollectInt32(func(index int, val int32) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestInt64(t *testing.T) { + + val := int64(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int64()) + assert.Equal(t, val, New(m).Get("value").MustInt64()) + assert.Equal(t, int64(0), New(m).Get("nothing").Int64()) + assert.Equal(t, val, New(m).Get("nothing").Int64(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustInt64() + }) + +} + +func TestInt64Slice(t *testing.T) { + + val := int64(1) + m := map[string]interface{}{"value": []int64{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Int64Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustInt64Slice()[0]) + assert.Equal(t, []int64(nil), New(m).Get("nothing").Int64Slice()) + assert.Equal(t, val, New(m).Get("nothing").Int64Slice([]int64{int64(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustInt64Slice() + }) + +} + +func TestIsInt64(t *testing.T) { + + var v *Value + + v = &Value{data: int64(1)} + assert.True(t, v.IsInt64()) + + v = &Value{data: []int64{int64(1)}} + assert.True(t, v.IsInt64Slice()) + +} + +func TestEachInt64(t *testing.T) { + + v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1)}} + count := 0 + replacedVals := make([]int64, 0) + assert.Equal(t, v, v.EachInt64(func(i int, val int64) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustInt64Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustInt64Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustInt64Slice()[2]) + +} + +func TestWhereInt64(t *testing.T) { + + v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}} + + selected := v.WhereInt64(func(i int, val int64) bool { + return i%2 == 0 + }).MustInt64Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupInt64(t *testing.T) { + + v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}} + + grouped := v.GroupInt64(func(i int, val int64) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]int64) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceInt64(t *testing.T) { + + v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}} + + rawArr := v.MustInt64Slice() + + replaced := v.ReplaceInt64(func(index int, val int64) int64 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustInt64Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectInt64(t *testing.T) { + + v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}} + + collected := v.CollectInt64(func(index int, val int64) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestUint(t *testing.T) { + + val := uint(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint()) + assert.Equal(t, val, New(m).Get("value").MustUint()) + assert.Equal(t, uint(0), New(m).Get("nothing").Uint()) + assert.Equal(t, val, New(m).Get("nothing").Uint(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustUint() + }) + +} + +func TestUintSlice(t *testing.T) { + + val := uint(1) + m := map[string]interface{}{"value": []uint{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").UintSlice()[0]) + assert.Equal(t, val, New(m).Get("value").MustUintSlice()[0]) + assert.Equal(t, []uint(nil), New(m).Get("nothing").UintSlice()) + assert.Equal(t, val, New(m).Get("nothing").UintSlice([]uint{uint(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustUintSlice() + }) + +} + +func TestIsUint(t *testing.T) { + + var v *Value + + v = &Value{data: uint(1)} + assert.True(t, v.IsUint()) + + v = &Value{data: []uint{uint(1)}} + assert.True(t, v.IsUintSlice()) + +} + +func TestEachUint(t *testing.T) { + + v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1)}} + count := 0 + replacedVals := make([]uint, 0) + assert.Equal(t, v, v.EachUint(func(i int, val uint) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustUintSlice()[0]) + assert.Equal(t, replacedVals[1], v.MustUintSlice()[1]) + assert.Equal(t, replacedVals[2], v.MustUintSlice()[2]) + +} + +func TestWhereUint(t *testing.T) { + + v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1), uint(1)}} + + selected := v.WhereUint(func(i int, val uint) bool { + return i%2 == 0 + }).MustUintSlice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupUint(t *testing.T) { + + v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1), uint(1)}} + + grouped := v.GroupUint(func(i int, val uint) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]uint) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceUint(t *testing.T) { + + v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1), uint(1)}} + + rawArr := v.MustUintSlice() + + replaced := v.ReplaceUint(func(index int, val uint) uint { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustUintSlice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectUint(t *testing.T) { + + v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1), uint(1)}} + + collected := v.CollectUint(func(index int, val uint) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestUint8(t *testing.T) { + + val := uint8(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint8()) + assert.Equal(t, val, New(m).Get("value").MustUint8()) + assert.Equal(t, uint8(0), New(m).Get("nothing").Uint8()) + assert.Equal(t, val, New(m).Get("nothing").Uint8(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustUint8() + }) + +} + +func TestUint8Slice(t *testing.T) { + + val := uint8(1) + m := map[string]interface{}{"value": []uint8{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint8Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustUint8Slice()[0]) + assert.Equal(t, []uint8(nil), New(m).Get("nothing").Uint8Slice()) + assert.Equal(t, val, New(m).Get("nothing").Uint8Slice([]uint8{uint8(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustUint8Slice() + }) + +} + +func TestIsUint8(t *testing.T) { + + var v *Value + + v = &Value{data: uint8(1)} + assert.True(t, v.IsUint8()) + + v = &Value{data: []uint8{uint8(1)}} + assert.True(t, v.IsUint8Slice()) + +} + +func TestEachUint8(t *testing.T) { + + v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}} + count := 0 + replacedVals := make([]uint8, 0) + assert.Equal(t, v, v.EachUint8(func(i int, val uint8) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustUint8Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustUint8Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustUint8Slice()[2]) + +} + +func TestWhereUint8(t *testing.T) { + + v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}} + + selected := v.WhereUint8(func(i int, val uint8) bool { + return i%2 == 0 + }).MustUint8Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupUint8(t *testing.T) { + + v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}} + + grouped := v.GroupUint8(func(i int, val uint8) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]uint8) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceUint8(t *testing.T) { + + v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}} + + rawArr := v.MustUint8Slice() + + replaced := v.ReplaceUint8(func(index int, val uint8) uint8 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustUint8Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectUint8(t *testing.T) { + + v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}} + + collected := v.CollectUint8(func(index int, val uint8) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestUint16(t *testing.T) { + + val := uint16(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint16()) + assert.Equal(t, val, New(m).Get("value").MustUint16()) + assert.Equal(t, uint16(0), New(m).Get("nothing").Uint16()) + assert.Equal(t, val, New(m).Get("nothing").Uint16(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustUint16() + }) + +} + +func TestUint16Slice(t *testing.T) { + + val := uint16(1) + m := map[string]interface{}{"value": []uint16{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint16Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustUint16Slice()[0]) + assert.Equal(t, []uint16(nil), New(m).Get("nothing").Uint16Slice()) + assert.Equal(t, val, New(m).Get("nothing").Uint16Slice([]uint16{uint16(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustUint16Slice() + }) + +} + +func TestIsUint16(t *testing.T) { + + var v *Value + + v = &Value{data: uint16(1)} + assert.True(t, v.IsUint16()) + + v = &Value{data: []uint16{uint16(1)}} + assert.True(t, v.IsUint16Slice()) + +} + +func TestEachUint16(t *testing.T) { + + v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}} + count := 0 + replacedVals := make([]uint16, 0) + assert.Equal(t, v, v.EachUint16(func(i int, val uint16) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustUint16Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustUint16Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustUint16Slice()[2]) + +} + +func TestWhereUint16(t *testing.T) { + + v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}} + + selected := v.WhereUint16(func(i int, val uint16) bool { + return i%2 == 0 + }).MustUint16Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupUint16(t *testing.T) { + + v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}} + + grouped := v.GroupUint16(func(i int, val uint16) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]uint16) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceUint16(t *testing.T) { + + v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}} + + rawArr := v.MustUint16Slice() + + replaced := v.ReplaceUint16(func(index int, val uint16) uint16 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustUint16Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectUint16(t *testing.T) { + + v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}} + + collected := v.CollectUint16(func(index int, val uint16) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestUint32(t *testing.T) { + + val := uint32(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint32()) + assert.Equal(t, val, New(m).Get("value").MustUint32()) + assert.Equal(t, uint32(0), New(m).Get("nothing").Uint32()) + assert.Equal(t, val, New(m).Get("nothing").Uint32(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustUint32() + }) + +} + +func TestUint32Slice(t *testing.T) { + + val := uint32(1) + m := map[string]interface{}{"value": []uint32{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint32Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustUint32Slice()[0]) + assert.Equal(t, []uint32(nil), New(m).Get("nothing").Uint32Slice()) + assert.Equal(t, val, New(m).Get("nothing").Uint32Slice([]uint32{uint32(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustUint32Slice() + }) + +} + +func TestIsUint32(t *testing.T) { + + var v *Value + + v = &Value{data: uint32(1)} + assert.True(t, v.IsUint32()) + + v = &Value{data: []uint32{uint32(1)}} + assert.True(t, v.IsUint32Slice()) + +} + +func TestEachUint32(t *testing.T) { + + v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}} + count := 0 + replacedVals := make([]uint32, 0) + assert.Equal(t, v, v.EachUint32(func(i int, val uint32) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustUint32Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustUint32Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustUint32Slice()[2]) + +} + +func TestWhereUint32(t *testing.T) { + + v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}} + + selected := v.WhereUint32(func(i int, val uint32) bool { + return i%2 == 0 + }).MustUint32Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupUint32(t *testing.T) { + + v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}} + + grouped := v.GroupUint32(func(i int, val uint32) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]uint32) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceUint32(t *testing.T) { + + v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}} + + rawArr := v.MustUint32Slice() + + replaced := v.ReplaceUint32(func(index int, val uint32) uint32 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustUint32Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectUint32(t *testing.T) { + + v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}} + + collected := v.CollectUint32(func(index int, val uint32) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestUint64(t *testing.T) { + + val := uint64(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint64()) + assert.Equal(t, val, New(m).Get("value").MustUint64()) + assert.Equal(t, uint64(0), New(m).Get("nothing").Uint64()) + assert.Equal(t, val, New(m).Get("nothing").Uint64(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustUint64() + }) + +} + +func TestUint64Slice(t *testing.T) { + + val := uint64(1) + m := map[string]interface{}{"value": []uint64{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uint64Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustUint64Slice()[0]) + assert.Equal(t, []uint64(nil), New(m).Get("nothing").Uint64Slice()) + assert.Equal(t, val, New(m).Get("nothing").Uint64Slice([]uint64{uint64(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustUint64Slice() + }) + +} + +func TestIsUint64(t *testing.T) { + + var v *Value + + v = &Value{data: uint64(1)} + assert.True(t, v.IsUint64()) + + v = &Value{data: []uint64{uint64(1)}} + assert.True(t, v.IsUint64Slice()) + +} + +func TestEachUint64(t *testing.T) { + + v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}} + count := 0 + replacedVals := make([]uint64, 0) + assert.Equal(t, v, v.EachUint64(func(i int, val uint64) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustUint64Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustUint64Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustUint64Slice()[2]) + +} + +func TestWhereUint64(t *testing.T) { + + v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}} + + selected := v.WhereUint64(func(i int, val uint64) bool { + return i%2 == 0 + }).MustUint64Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupUint64(t *testing.T) { + + v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}} + + grouped := v.GroupUint64(func(i int, val uint64) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]uint64) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceUint64(t *testing.T) { + + v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}} + + rawArr := v.MustUint64Slice() + + replaced := v.ReplaceUint64(func(index int, val uint64) uint64 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustUint64Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectUint64(t *testing.T) { + + v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}} + + collected := v.CollectUint64(func(index int, val uint64) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestUintptr(t *testing.T) { + + val := uintptr(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Uintptr()) + assert.Equal(t, val, New(m).Get("value").MustUintptr()) + assert.Equal(t, uintptr(0), New(m).Get("nothing").Uintptr()) + assert.Equal(t, val, New(m).Get("nothing").Uintptr(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustUintptr() + }) + +} + +func TestUintptrSlice(t *testing.T) { + + val := uintptr(1) + m := map[string]interface{}{"value": []uintptr{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").UintptrSlice()[0]) + assert.Equal(t, val, New(m).Get("value").MustUintptrSlice()[0]) + assert.Equal(t, []uintptr(nil), New(m).Get("nothing").UintptrSlice()) + assert.Equal(t, val, New(m).Get("nothing").UintptrSlice([]uintptr{uintptr(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustUintptrSlice() + }) + +} + +func TestIsUintptr(t *testing.T) { + + var v *Value + + v = &Value{data: uintptr(1)} + assert.True(t, v.IsUintptr()) + + v = &Value{data: []uintptr{uintptr(1)}} + assert.True(t, v.IsUintptrSlice()) + +} + +func TestEachUintptr(t *testing.T) { + + v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}} + count := 0 + replacedVals := make([]uintptr, 0) + assert.Equal(t, v, v.EachUintptr(func(i int, val uintptr) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustUintptrSlice()[0]) + assert.Equal(t, replacedVals[1], v.MustUintptrSlice()[1]) + assert.Equal(t, replacedVals[2], v.MustUintptrSlice()[2]) + +} + +func TestWhereUintptr(t *testing.T) { + + v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}} + + selected := v.WhereUintptr(func(i int, val uintptr) bool { + return i%2 == 0 + }).MustUintptrSlice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupUintptr(t *testing.T) { + + v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}} + + grouped := v.GroupUintptr(func(i int, val uintptr) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]uintptr) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceUintptr(t *testing.T) { + + v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}} + + rawArr := v.MustUintptrSlice() + + replaced := v.ReplaceUintptr(func(index int, val uintptr) uintptr { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustUintptrSlice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectUintptr(t *testing.T) { + + v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}} + + collected := v.CollectUintptr(func(index int, val uintptr) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestFloat32(t *testing.T) { + + val := float32(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Float32()) + assert.Equal(t, val, New(m).Get("value").MustFloat32()) + assert.Equal(t, float32(0), New(m).Get("nothing").Float32()) + assert.Equal(t, val, New(m).Get("nothing").Float32(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustFloat32() + }) + +} + +func TestFloat32Slice(t *testing.T) { + + val := float32(1) + m := map[string]interface{}{"value": []float32{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Float32Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustFloat32Slice()[0]) + assert.Equal(t, []float32(nil), New(m).Get("nothing").Float32Slice()) + assert.Equal(t, val, New(m).Get("nothing").Float32Slice([]float32{float32(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustFloat32Slice() + }) + +} + +func TestIsFloat32(t *testing.T) { + + var v *Value + + v = &Value{data: float32(1)} + assert.True(t, v.IsFloat32()) + + v = &Value{data: []float32{float32(1)}} + assert.True(t, v.IsFloat32Slice()) + +} + +func TestEachFloat32(t *testing.T) { + + v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1)}} + count := 0 + replacedVals := make([]float32, 0) + assert.Equal(t, v, v.EachFloat32(func(i int, val float32) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustFloat32Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustFloat32Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustFloat32Slice()[2]) + +} + +func TestWhereFloat32(t *testing.T) { + + v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)}} + + selected := v.WhereFloat32(func(i int, val float32) bool { + return i%2 == 0 + }).MustFloat32Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupFloat32(t *testing.T) { + + v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)}} + + grouped := v.GroupFloat32(func(i int, val float32) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]float32) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceFloat32(t *testing.T) { + + v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)}} + + rawArr := v.MustFloat32Slice() + + replaced := v.ReplaceFloat32(func(index int, val float32) float32 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustFloat32Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectFloat32(t *testing.T) { + + v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)}} + + collected := v.CollectFloat32(func(index int, val float32) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestFloat64(t *testing.T) { + + val := float64(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Float64()) + assert.Equal(t, val, New(m).Get("value").MustFloat64()) + assert.Equal(t, float64(0), New(m).Get("nothing").Float64()) + assert.Equal(t, val, New(m).Get("nothing").Float64(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustFloat64() + }) + +} + +func TestFloat64Slice(t *testing.T) { + + val := float64(1) + m := map[string]interface{}{"value": []float64{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Float64Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustFloat64Slice()[0]) + assert.Equal(t, []float64(nil), New(m).Get("nothing").Float64Slice()) + assert.Equal(t, val, New(m).Get("nothing").Float64Slice([]float64{float64(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustFloat64Slice() + }) + +} + +func TestIsFloat64(t *testing.T) { + + var v *Value + + v = &Value{data: float64(1)} + assert.True(t, v.IsFloat64()) + + v = &Value{data: []float64{float64(1)}} + assert.True(t, v.IsFloat64Slice()) + +} + +func TestEachFloat64(t *testing.T) { + + v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1)}} + count := 0 + replacedVals := make([]float64, 0) + assert.Equal(t, v, v.EachFloat64(func(i int, val float64) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustFloat64Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustFloat64Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustFloat64Slice()[2]) + +} + +func TestWhereFloat64(t *testing.T) { + + v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1), float64(1)}} + + selected := v.WhereFloat64(func(i int, val float64) bool { + return i%2 == 0 + }).MustFloat64Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupFloat64(t *testing.T) { + + v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1), float64(1)}} + + grouped := v.GroupFloat64(func(i int, val float64) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]float64) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceFloat64(t *testing.T) { + + v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1), float64(1)}} + + rawArr := v.MustFloat64Slice() + + replaced := v.ReplaceFloat64(func(index int, val float64) float64 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustFloat64Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectFloat64(t *testing.T) { + + v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1), float64(1)}} + + collected := v.CollectFloat64(func(index int, val float64) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestComplex64(t *testing.T) { + + val := complex64(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Complex64()) + assert.Equal(t, val, New(m).Get("value").MustComplex64()) + assert.Equal(t, complex64(0), New(m).Get("nothing").Complex64()) + assert.Equal(t, val, New(m).Get("nothing").Complex64(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustComplex64() + }) + +} + +func TestComplex64Slice(t *testing.T) { + + val := complex64(1) + m := map[string]interface{}{"value": []complex64{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Complex64Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustComplex64Slice()[0]) + assert.Equal(t, []complex64(nil), New(m).Get("nothing").Complex64Slice()) + assert.Equal(t, val, New(m).Get("nothing").Complex64Slice([]complex64{complex64(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustComplex64Slice() + }) + +} + +func TestIsComplex64(t *testing.T) { + + var v *Value + + v = &Value{data: complex64(1)} + assert.True(t, v.IsComplex64()) + + v = &Value{data: []complex64{complex64(1)}} + assert.True(t, v.IsComplex64Slice()) + +} + +func TestEachComplex64(t *testing.T) { + + v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}} + count := 0 + replacedVals := make([]complex64, 0) + assert.Equal(t, v, v.EachComplex64(func(i int, val complex64) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustComplex64Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustComplex64Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustComplex64Slice()[2]) + +} + +func TestWhereComplex64(t *testing.T) { + + v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}} + + selected := v.WhereComplex64(func(i int, val complex64) bool { + return i%2 == 0 + }).MustComplex64Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupComplex64(t *testing.T) { + + v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}} + + grouped := v.GroupComplex64(func(i int, val complex64) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]complex64) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceComplex64(t *testing.T) { + + v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}} + + rawArr := v.MustComplex64Slice() + + replaced := v.ReplaceComplex64(func(index int, val complex64) complex64 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustComplex64Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectComplex64(t *testing.T) { + + v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}} + + collected := v.CollectComplex64(func(index int, val complex64) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} + +// ************************************************************ +// TESTS +// ************************************************************ + +func TestComplex128(t *testing.T) { + + val := complex128(1) + m := map[string]interface{}{"value": val, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Complex128()) + assert.Equal(t, val, New(m).Get("value").MustComplex128()) + assert.Equal(t, complex128(0), New(m).Get("nothing").Complex128()) + assert.Equal(t, val, New(m).Get("nothing").Complex128(1)) + + assert.Panics(t, func() { + New(m).Get("age").MustComplex128() + }) + +} + +func TestComplex128Slice(t *testing.T) { + + val := complex128(1) + m := map[string]interface{}{"value": []complex128{val}, "nothing": nil} + assert.Equal(t, val, New(m).Get("value").Complex128Slice()[0]) + assert.Equal(t, val, New(m).Get("value").MustComplex128Slice()[0]) + assert.Equal(t, []complex128(nil), New(m).Get("nothing").Complex128Slice()) + assert.Equal(t, val, New(m).Get("nothing").Complex128Slice([]complex128{complex128(1)})[0]) + + assert.Panics(t, func() { + New(m).Get("nothing").MustComplex128Slice() + }) + +} + +func TestIsComplex128(t *testing.T) { + + var v *Value + + v = &Value{data: complex128(1)} + assert.True(t, v.IsComplex128()) + + v = &Value{data: []complex128{complex128(1)}} + assert.True(t, v.IsComplex128Slice()) + +} + +func TestEachComplex128(t *testing.T) { + + v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}} + count := 0 + replacedVals := make([]complex128, 0) + assert.Equal(t, v, v.EachComplex128(func(i int, val complex128) bool { + + count++ + replacedVals = append(replacedVals, val) + + // abort early + if i == 2 { + return false + } + + return true + + })) + + assert.Equal(t, count, 3) + assert.Equal(t, replacedVals[0], v.MustComplex128Slice()[0]) + assert.Equal(t, replacedVals[1], v.MustComplex128Slice()[1]) + assert.Equal(t, replacedVals[2], v.MustComplex128Slice()[2]) + +} + +func TestWhereComplex128(t *testing.T) { + + v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}} + + selected := v.WhereComplex128(func(i int, val complex128) bool { + return i%2 == 0 + }).MustComplex128Slice() + + assert.Equal(t, 3, len(selected)) + +} + +func TestGroupComplex128(t *testing.T) { + + v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}} + + grouped := v.GroupComplex128(func(i int, val complex128) string { + return fmt.Sprintf("%v", i%2 == 0) + }).data.(map[string][]complex128) + + assert.Equal(t, 2, len(grouped)) + assert.Equal(t, 3, len(grouped["true"])) + assert.Equal(t, 3, len(grouped["false"])) + +} + +func TestReplaceComplex128(t *testing.T) { + + v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}} + + rawArr := v.MustComplex128Slice() + + replaced := v.ReplaceComplex128(func(index int, val complex128) complex128 { + if index < len(rawArr)-1 { + return rawArr[index+1] + } + return rawArr[0] + }) + + replacedArr := replaced.MustComplex128Slice() + if assert.Equal(t, 6, len(replacedArr)) { + assert.Equal(t, replacedArr[0], rawArr[1]) + assert.Equal(t, replacedArr[1], rawArr[2]) + assert.Equal(t, replacedArr[2], rawArr[3]) + assert.Equal(t, replacedArr[3], rawArr[4]) + assert.Equal(t, replacedArr[4], rawArr[5]) + assert.Equal(t, replacedArr[5], rawArr[0]) + } + +} + +func TestCollectComplex128(t *testing.T) { + + v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}} + + collected := v.CollectComplex128(func(index int, val complex128) interface{} { + return index + }) + + collectedArr := collected.MustInterSlice() + if assert.Equal(t, 6, len(collectedArr)) { + assert.Equal(t, collectedArr[0], 0) + assert.Equal(t, collectedArr[1], 1) + assert.Equal(t, collectedArr[2], 2) + assert.Equal(t, collectedArr[3], 3) + assert.Equal(t, collectedArr[4], 4) + assert.Equal(t, collectedArr[5], 5) + } + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/value.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/value.go new file mode 100644 index 000000000..7aaef06b1 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/value.go @@ -0,0 +1,13 @@ +package objx + +// Value provides methods for extracting interface{} data in various +// types. +type Value struct { + // data contains the raw data being managed by this Value + data interface{} +} + +// Data returns the raw data contained by this Value +func (v *Value) Data() interface{} { + return v.data +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/value_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/value_test.go new file mode 100644 index 000000000..0bc65d92c --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/objx/value_test.go @@ -0,0 +1 @@ +package objx diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions.go new file mode 100644 index 000000000..58e178165 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions.go @@ -0,0 +1,805 @@ +package assert + +import ( + "bufio" + "bytes" + "fmt" + "reflect" + "regexp" + "runtime" + "strings" + "time" +) + +// TestingT is an interface wrapper around *testing.T +type TestingT interface { + Errorf(format string, args ...interface{}) +} + +// Comparison a custom function that returns true on success and false on failure +type Comparison func() (success bool) + +/* + Helper functions +*/ + +// ObjectsAreEqual determines if two objects are considered equal. +// +// This function does no assertion of any kind. +func ObjectsAreEqual(expected, actual interface{}) bool { + + if expected == nil || actual == nil { + return expected == actual + } + + if reflect.DeepEqual(expected, actual) { + return true + } + + // Last ditch effort + if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) { + return true + } + + return false + +} + +func ObjectsAreEqualValues(expected, actual interface{}) bool { + if ObjectsAreEqual(expected, actual) { + return true + } + + actualType := reflect.TypeOf(actual) + expectedValue := reflect.ValueOf(expected) + if expectedValue.Type().ConvertibleTo(actualType) { + // Attempt comparison after type conversion + if reflect.DeepEqual(actual, expectedValue.Convert(actualType).Interface()) { + return true + } + } + + return false +} + +/* CallerInfo is necessary because the assert functions use the testing object +internally, causing it to print the file:line of the assert method, rather than where +the problem actually occured in calling code.*/ + +// CallerInfo returns a string containing the file and line number of the assert call +// that failed. +func CallerInfo() string { + + file := "" + line := 0 + ok := false + + for i := 0; ; i++ { + _, file, line, ok = runtime.Caller(i) + if !ok { + return "" + } + parts := strings.Split(file, "/") + dir := parts[len(parts)-2] + file = parts[len(parts)-1] + if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { + break + } + } + + return fmt.Sprintf("%s:%d", file, line) +} + +// getWhitespaceString returns a string that is long enough to overwrite the default +// output from the go testing framework. +func getWhitespaceString() string { + + _, file, line, ok := runtime.Caller(1) + if !ok { + return "" + } + parts := strings.Split(file, "/") + file = parts[len(parts)-1] + + return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line))) + +} + +func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { + if len(msgAndArgs) == 0 || msgAndArgs == nil { + return "" + } + if len(msgAndArgs) == 1 { + return msgAndArgs[0].(string) + } + if len(msgAndArgs) > 1 { + return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) + } + return "" +} + +// Indents all lines of the message by appending a number of tabs to each line, in an output format compatible with Go's +// test printing (see inner comment for specifics) +func indentMessageLines(message string, tabs int) string { + outBuf := new(bytes.Buffer) + + for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { + if i != 0 { + outBuf.WriteRune('\n') + } + for ii := 0; ii < tabs; ii++ { + outBuf.WriteRune('\t') + // Bizarrely, all lines except the first need one fewer tabs prepended, so deliberately advance the counter + // by 1 prematurely. + if ii == 0 && i > 0 { + ii++ + } + } + outBuf.WriteString(scanner.Text()) + } + + return outBuf.String() +} + +// Fail reports a failure through +func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + + if len(message) > 0 { + t.Errorf("\r%s\r\tLocation:\t%s\n"+ + "\r\tError:%s\n"+ + "\r\tMessages:\t%s\n\r", + getWhitespaceString(), + CallerInfo(), + indentMessageLines(failureMessage, 2), + message) + } else { + t.Errorf("\r%s\r\tLocation:\t%s\n"+ + "\r\tError:%s\n\r", + getWhitespaceString(), + CallerInfo(), + indentMessageLines(failureMessage, 2)) + } + + return false +} + +// Implements asserts that an object is implemented by the specified interface. +// +// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject") +func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + + interfaceType := reflect.TypeOf(interfaceObject).Elem() + + if !reflect.TypeOf(object).Implements(interfaceType) { + return Fail(t, fmt.Sprintf("Object must implement %v", interfaceType), msgAndArgs...) + } + + return true + +} + +// IsType asserts that the specified objects are of the same type. +func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { + return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) + } + + return true +} + +// Equal asserts that two objects are equal. +// +// assert.Equal(t, 123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqual(expected, actual) { + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)", expected, actual), msgAndArgs...) + } + + return true + +} + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqualValues(expected, actual) { + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)", expected, actual), msgAndArgs...) + } + + return true + +} + +// Exactly asserts that two objects are equal is value and type. +// +// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + aType := reflect.TypeOf(expected) + bType := reflect.TypeOf(actual) + + if aType != bType { + return Fail(t, "Types expected to match exactly", "%v != %v", aType, bType) + } + + return Equal(t, expected, actual, msgAndArgs...) + +} + +// NotNil asserts that the specified object is not nil. +// +// assert.NotNil(t, err, "err should be something") +// +// Returns whether the assertion was successful (true) or not (false). +func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + + success := true + + if object == nil { + success = false + } else { + value := reflect.ValueOf(object) + kind := value.Kind() + if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { + success = false + } + } + + if !success { + Fail(t, "Expected not to be nil.", msgAndArgs...) + } + + return success +} + +// isNil checks if a specified object is nil or not, without Failing. +func isNil(object interface{}) bool { + if object == nil { + return true + } + + value := reflect.ValueOf(object) + kind := value.Kind() + if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { + return true + } + + return false +} + +// Nil asserts that the specified object is nil. +// +// assert.Nil(t, err, "err should be nothing") +// +// Returns whether the assertion was successful (true) or not (false). +func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if isNil(object) { + return true + } + return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) +} + +var zeros = []interface{}{ + int(0), + int8(0), + int16(0), + int32(0), + int64(0), + uint(0), + uint8(0), + uint16(0), + uint32(0), + uint64(0), + float32(0), + float64(0), +} + +// isEmpty gets whether the specified object is considered empty or not. +func isEmpty(object interface{}) bool { + + if object == nil { + return true + } else if object == "" { + return true + } else if object == false { + return true + } + + for _, v := range zeros { + if object == v { + return true + } + } + + objValue := reflect.ValueOf(object) + + switch objValue.Kind() { + case reflect.Map: + fallthrough + case reflect.Slice, reflect.Chan: + { + return (objValue.Len() == 0) + } + case reflect.Ptr: + { + switch object.(type) { + case *time.Time: + return object.(*time.Time).IsZero() + default: + return false + } + } + } + return false +} + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Empty(t, obj) +// +// Returns whether the assertion was successful (true) or not (false). +func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + + pass := isEmpty(object) + if !pass { + Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + + pass := !isEmpty(object) + if !pass { + Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// getLen try to get length of object. +// return (false, 0) if impossible. +func getLen(x interface{}) (ok bool, length int) { + v := reflect.ValueOf(x) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + return true, v.Len() +} + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// assert.Len(t, mySlice, 3, "The size of slice is not 3") +// +// Returns whether the assertion was successful (true) or not (false). +func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { + ok, l := getLen(object) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) + } + + if l != length { + return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + } + return true +} + +// True asserts that the specified value is true. +// +// assert.True(t, myBool, "myBool should be true") +// +// Returns whether the assertion was successful (true) or not (false). +func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { + + if value != true { + return Fail(t, "Should be true", msgAndArgs...) + } + + return true + +} + +// False asserts that the specified value is true. +// +// assert.False(t, myBool, "myBool should be false") +// +// Returns whether the assertion was successful (true) or not (false). +func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { + + if value != false { + return Fail(t, "Should be false", msgAndArgs...) + } + + return true + +} + +// NotEqual asserts that the specified values are NOT equal. +// +// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if ObjectsAreEqual(expected, actual) { + return Fail(t, "Should not be equal", msgAndArgs...) + } + + return true + +} + +// containsElement try loop over the list check if the list includes the element. +// return (false, false) if impossible. +// return (true, false) if element was not found. +// return (true, true) if element was found. +func includeElement(list interface{}, element interface{}) (ok, found bool) { + + listValue := reflect.ValueOf(list) + elementValue := reflect.ValueOf(element) + defer func() { + if e := recover(); e != nil { + ok = false + found = false + } + }() + + if reflect.TypeOf(list).Kind() == reflect.String { + return true, strings.Contains(listValue.String(), elementValue.String()) + } + + for i := 0; i < listValue.Len(); i++ { + if ObjectsAreEqual(listValue.Index(i).Interface(), element) { + return true, true + } + } + return true, false + +} + +// Contains asserts that the specified string or list(array, slice...) contains the +// specified substring or element. +// +// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'") +// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") +// +// Returns whether the assertion was successful (true) or not (false). +func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if !found { + return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// NotContains asserts that the specified string or list(array, slice...) does NOT contain the +// specified substring or element. +// +// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") +// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") +// +// Returns whether the assertion was successful (true) or not (false). +func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if found { + return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// Condition uses a Comparison to assert a complex condition. +func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { + result := comp() + if !result { + Fail(t, "Condition failed!", msgAndArgs...) + } + return result +} + +// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics +// methods, and represents a simple func that takes no arguments, and returns nothing. +type PanicTestFunc func() + +// didPanic returns true if the function passed to it panics. Otherwise, it returns false. +func didPanic(f PanicTestFunc) (bool, interface{}) { + + didPanic := false + var message interface{} + func() { + + defer func() { + if message = recover(); message != nil { + didPanic = true + } + }() + + // call the target function + f() + + }() + + return didPanic, message + +} + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panics(t, func(){ +// GoCrazy() +// }, "Calling GoCrazy() should panic") +// +// Returns whether the assertion was successful (true) or not (false). +func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + + if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) + } + + return true +} + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanics(t, func(){ +// RemainCalm() +// }, "Calling RemainCalm() should NOT panic") +// +// Returns whether the assertion was successful (true) or not (false). +func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + + if funcDidPanic, panicValue := didPanic(f); funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) + } + + return true +} + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") +// +// Returns whether the assertion was successful (true) or not (false). +func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + + dt := expected.Sub(actual) + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +func toFloat(x interface{}) (float64, bool) { + var xf float64 + xok := true + + switch xn := x.(type) { + case uint8: + xf = float64(xn) + case uint16: + xf = float64(xn) + case uint32: + xf = float64(xn) + case uint64: + xf = float64(xn) + case int: + xf = float64(xn) + case int8: + xf = float64(xn) + case int16: + xf = float64(xn) + case int32: + xf = float64(xn) + case int64: + xf = float64(xn) + case float32: + xf = float64(xn) + case float64: + xf = float64(xn) + default: + xok = false + } + + return xf, xok +} + +// InDelta asserts that the two numerals are within delta of each other. +// +// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) +// +// Returns whether the assertion was successful (true) or not (false). +func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + + af, aok := toFloat(expected) + bf, bok := toFloat(actual) + + if !aok || !bok { + return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) + } + + dt := af - bf + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +// min(|expected|, |actual|) * epsilon +func calcEpsilonDelta(expected, actual interface{}, epsilon float64) float64 { + af, aok := toFloat(expected) + bf, bok := toFloat(actual) + + if !aok || !bok { + // invalid input + return 0 + } + + if af < 0 { + af = -af + } + if bf < 0 { + bf = -bf + } + var delta float64 + if af < bf { + delta = af * epsilon + } else { + delta = bf * epsilon + } + return delta +} + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +// +// Returns whether the assertion was successful (true) or not (false). +func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + delta := calcEpsilonDelta(expected, actual, epsilon) + + return InDelta(t, expected, actual, delta, msgAndArgs...) +} + +/* + Errors +*/ + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, actualObj, expectedObj) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { + if isNil(err) { + return true + } + + return Fail(t, fmt.Sprintf("No error is expected but got %v", err), msgAndArgs...) +} + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + return NotNil(t, err, "An error is expected but got nil. %s", message) + +} + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + if !NotNil(t, theError, "An error is expected but got nil. %s", message) { + return false + } + s := "An error with value \"%s\" is expected but got \"%s\". %s" + return Equal(t, theError.Error(), errString, + s, errString, theError.Error(), message) +} + +// matchRegexp return true if a specified regexp matches a string. +func matchRegexp(rx interface{}, str interface{}) bool { + + var r *regexp.Regexp + if rr, ok := rx.(*regexp.Regexp); ok { + r = rr + } else { + r = regexp.MustCompile(fmt.Sprint(rx)) + } + + return (r.FindStringIndex(fmt.Sprint(str)) != nil) + +} + +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + + match := matchRegexp(rx, str) + + if !match { + Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) + } + + return match +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + match := matchRegexp(rx, str) + + if match { + Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) + } + + return !match + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go new file mode 100644 index 000000000..2cb58dbd7 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go @@ -0,0 +1,768 @@ +package assert + +import ( + "errors" + "regexp" + "testing" + "time" +) + +// AssertionTesterInterface defines an interface to be used for testing assertion methods +type AssertionTesterInterface interface { + TestMethod() +} + +// AssertionTesterConformingObject is an object that conforms to the AssertionTesterInterface interface +type AssertionTesterConformingObject struct { +} + +func (a *AssertionTesterConformingObject) TestMethod() { +} + +// AssertionTesterNonConformingObject is an object that does not conform to the AssertionTesterInterface interface +type AssertionTesterNonConformingObject struct { +} + +func TestObjectsAreEqual(t *testing.T) { + + if !ObjectsAreEqual("Hello World", "Hello World") { + t.Error("objectsAreEqual should return true") + } + if !ObjectsAreEqual(123, 123) { + t.Error("objectsAreEqual should return true") + } + if !ObjectsAreEqual(123.5, 123.5) { + t.Error("objectsAreEqual should return true") + } + if !ObjectsAreEqual([]byte("Hello World"), []byte("Hello World")) { + t.Error("objectsAreEqual should return true") + } + if !ObjectsAreEqual(nil, nil) { + t.Error("objectsAreEqual should return true") + } + if ObjectsAreEqual(map[int]int{5: 10}, map[int]int{10: 20}) { + t.Error("objectsAreEqual should return false") + } + if ObjectsAreEqual('x', "x") { + t.Error("objectsAreEqual should return false") + } + if ObjectsAreEqual("x", 'x') { + t.Error("objectsAreEqual should return false") + } + if ObjectsAreEqual(0, 0.1) { + t.Error("objectsAreEqual should return false") + } + if ObjectsAreEqual(0.1, 0) { + t.Error("objectsAreEqual should return false") + } + if ObjectsAreEqual(uint32(10), int32(10)) { + t.Error("objectsAreEqual should return false") + } + if !ObjectsAreEqualValues(uint32(10), int32(10)) { + t.Error("ObjectsAreEqualValues should return true") + } + +} + +func TestImplements(t *testing.T) { + + mockT := new(testing.T) + + if !Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) { + t.Error("Implements method should return true: AssertionTesterConformingObject implements AssertionTesterInterface") + } + if Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) { + t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface") + } + +} + +func TestIsType(t *testing.T) { + + mockT := new(testing.T) + + if !IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) { + t.Error("IsType should return true: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject") + } + if IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) { + t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject") + } + +} + +func TestEqual(t *testing.T) { + + mockT := new(testing.T) + + if !Equal(mockT, "Hello World", "Hello World") { + t.Error("Equal should return true") + } + if !Equal(mockT, 123, 123) { + t.Error("Equal should return true") + } + if !Equal(mockT, 123.5, 123.5) { + t.Error("Equal should return true") + } + if !Equal(mockT, []byte("Hello World"), []byte("Hello World")) { + t.Error("Equal should return true") + } + if !Equal(mockT, nil, nil) { + t.Error("Equal should return true") + } + if !Equal(mockT, int32(123), int32(123)) { + t.Error("Equal should return true") + } + if !Equal(mockT, uint64(123), uint64(123)) { + t.Error("Equal should return true") + } + funcA := func() int { return 42 } + if !Equal(mockT, funcA, funcA) { + t.Error("Equal should return true") + } + +} + +func TestNotNil(t *testing.T) { + + mockT := new(testing.T) + + if !NotNil(mockT, new(AssertionTesterConformingObject)) { + t.Error("NotNil should return true: object is not nil") + } + if NotNil(mockT, nil) { + t.Error("NotNil should return false: object is nil") + } + +} + +func TestNil(t *testing.T) { + + mockT := new(testing.T) + + if !Nil(mockT, nil) { + t.Error("Nil should return true: object is nil") + } + if Nil(mockT, new(AssertionTesterConformingObject)) { + t.Error("Nil should return false: object is not nil") + } + +} + +func TestTrue(t *testing.T) { + + mockT := new(testing.T) + + if !True(mockT, true) { + t.Error("True should return true") + } + if True(mockT, false) { + t.Error("True should return false") + } + +} + +func TestFalse(t *testing.T) { + + mockT := new(testing.T) + + if !False(mockT, false) { + t.Error("False should return true") + } + if False(mockT, true) { + t.Error("False should return false") + } + +} + +func TestExactly(t *testing.T) { + + mockT := new(testing.T) + + a := float32(1) + b := float64(1) + c := float32(1) + d := float32(2) + + if Exactly(mockT, a, b) { + t.Error("Exactly should return false") + } + if Exactly(mockT, a, d) { + t.Error("Exactly should return false") + } + if !Exactly(mockT, a, c) { + t.Error("Exactly should return true") + } + + if Exactly(mockT, nil, a) { + t.Error("Exactly should return false") + } + if Exactly(mockT, a, nil) { + t.Error("Exactly should return false") + } + +} + +func TestNotEqual(t *testing.T) { + + mockT := new(testing.T) + + if !NotEqual(mockT, "Hello World", "Hello World!") { + t.Error("NotEqual should return true") + } + if !NotEqual(mockT, 123, 1234) { + t.Error("NotEqual should return true") + } + if !NotEqual(mockT, 123.5, 123.55) { + t.Error("NotEqual should return true") + } + if !NotEqual(mockT, []byte("Hello World"), []byte("Hello World!")) { + t.Error("NotEqual should return true") + } + if !NotEqual(mockT, nil, new(AssertionTesterConformingObject)) { + t.Error("NotEqual should return true") + } + funcA := func() int { return 23 } + funcB := func() int { return 42 } + if !NotEqual(mockT, funcA, funcB) { + t.Error("NotEqual should return true") + } + + if NotEqual(mockT, "Hello World", "Hello World") { + t.Error("NotEqual should return false") + } + if NotEqual(mockT, 123, 123) { + t.Error("NotEqual should return false") + } + if NotEqual(mockT, 123.5, 123.5) { + t.Error("NotEqual should return false") + } + if NotEqual(mockT, []byte("Hello World"), []byte("Hello World")) { + t.Error("NotEqual should return false") + } + if NotEqual(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) { + t.Error("NotEqual should return false") + } +} + +type A struct { + Name, Value string +} + +func TestContains(t *testing.T) { + + mockT := new(testing.T) + list := []string{"Foo", "Bar"} + complexList := []*A{ + {"b", "c"}, + {"d", "e"}, + {"g", "h"}, + {"j", "k"}, + } + + if !Contains(mockT, "Hello World", "Hello") { + t.Error("Contains should return true: \"Hello World\" contains \"Hello\"") + } + if Contains(mockT, "Hello World", "Salut") { + t.Error("Contains should return false: \"Hello World\" does not contain \"Salut\"") + } + + if !Contains(mockT, list, "Bar") { + t.Error("Contains should return true: \"[\"Foo\", \"Bar\"]\" contains \"Bar\"") + } + if Contains(mockT, list, "Salut") { + t.Error("Contains should return false: \"[\"Foo\", \"Bar\"]\" does not contain \"Salut\"") + } + if !Contains(mockT, complexList, &A{"g", "h"}) { + t.Error("Contains should return true: complexList contains {\"g\", \"h\"}") + } + if Contains(mockT, complexList, &A{"g", "e"}) { + t.Error("Contains should return false: complexList contains {\"g\", \"e\"}") + } +} + +func TestNotContains(t *testing.T) { + + mockT := new(testing.T) + list := []string{"Foo", "Bar"} + + if !NotContains(mockT, "Hello World", "Hello!") { + t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"") + } + if NotContains(mockT, "Hello World", "Hello") { + t.Error("NotContains should return false: \"Hello World\" contains \"Hello\"") + } + + if !NotContains(mockT, list, "Foo!") { + t.Error("NotContains should return true: \"[\"Foo\", \"Bar\"]\" does not contain \"Foo!\"") + } + if NotContains(mockT, list, "Foo") { + t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"") + } + +} + +func Test_includeElement(t *testing.T) { + + list1 := []string{"Foo", "Bar"} + list2 := []int{1, 2} + + ok, found := includeElement("Hello World", "World") + True(t, ok) + True(t, found) + + ok, found = includeElement(list1, "Foo") + True(t, ok) + True(t, found) + + ok, found = includeElement(list1, "Bar") + True(t, ok) + True(t, found) + + ok, found = includeElement(list2, 1) + True(t, ok) + True(t, found) + + ok, found = includeElement(list2, 2) + True(t, ok) + True(t, found) + + ok, found = includeElement(list1, "Foo!") + True(t, ok) + False(t, found) + + ok, found = includeElement(list2, 3) + True(t, ok) + False(t, found) + + ok, found = includeElement(list2, "1") + True(t, ok) + False(t, found) + + ok, found = includeElement(1433, "1") + False(t, ok) + False(t, found) + +} + +func TestCondition(t *testing.T) { + mockT := new(testing.T) + + if !Condition(mockT, func() bool { return true }, "Truth") { + t.Error("Condition should return true") + } + + if Condition(mockT, func() bool { return false }, "Lie") { + t.Error("Condition should return false") + } + +} + +func TestDidPanic(t *testing.T) { + + if funcDidPanic, _ := didPanic(func() { + panic("Panic!") + }); !funcDidPanic { + t.Error("didPanic should return true") + } + + if funcDidPanic, _ := didPanic(func() { + }); funcDidPanic { + t.Error("didPanic should return false") + } + +} + +func TestPanics(t *testing.T) { + + mockT := new(testing.T) + + if !Panics(mockT, func() { + panic("Panic!") + }) { + t.Error("Panics should return true") + } + + if Panics(mockT, func() { + }) { + t.Error("Panics should return false") + } + +} + +func TestNotPanics(t *testing.T) { + + mockT := new(testing.T) + + if !NotPanics(mockT, func() { + }) { + t.Error("NotPanics should return true") + } + + if NotPanics(mockT, func() { + panic("Panic!") + }) { + t.Error("NotPanics should return false") + } + +} + +func TestEqual_Funcs(t *testing.T) { + + type f func() int + f1 := func() int { return 1 } + f2 := func() int { return 2 } + + f1Copy := f1 + + Equal(t, f1Copy, f1, "Funcs are the same and should be considered equal") + NotEqual(t, f1, f2, "f1 and f2 are different") + +} + +func TestNoError(t *testing.T) { + + mockT := new(testing.T) + + // start with a nil error + var err error + + True(t, NoError(mockT, err), "NoError should return True for nil arg") + + // now set an error + err = errors.New("some error") + + False(t, NoError(mockT, err), "NoError with error should return False") + +} + +func TestError(t *testing.T) { + + mockT := new(testing.T) + + // start with a nil error + var err error + + False(t, Error(mockT, err), "Error should return False for nil arg") + + // now set an error + err = errors.New("some error") + + True(t, Error(mockT, err), "Error with error should return True") + +} + +func TestEqualError(t *testing.T) { + mockT := new(testing.T) + + // start with a nil error + var err error + False(t, EqualError(mockT, err, ""), + "EqualError should return false for nil arg") + + // now set an error + err = errors.New("some error") + False(t, EqualError(mockT, err, "Not some error"), + "EqualError should return false for different error string") + True(t, EqualError(mockT, err, "some error"), + "EqualError should return true") +} + +func Test_isEmpty(t *testing.T) { + + chWithValue := make(chan struct{}, 1) + chWithValue <- struct{}{} + + True(t, isEmpty("")) + True(t, isEmpty(nil)) + True(t, isEmpty([]string{})) + True(t, isEmpty(0)) + True(t, isEmpty(int32(0))) + True(t, isEmpty(int64(0))) + True(t, isEmpty(false)) + True(t, isEmpty(map[string]string{})) + True(t, isEmpty(new(time.Time))) + True(t, isEmpty(make(chan struct{}))) + False(t, isEmpty("something")) + False(t, isEmpty(errors.New("something"))) + False(t, isEmpty([]string{"something"})) + False(t, isEmpty(1)) + False(t, isEmpty(true)) + False(t, isEmpty(map[string]string{"Hello": "World"})) + False(t, isEmpty(chWithValue)) + +} + +func TestEmpty(t *testing.T) { + + mockT := new(testing.T) + chWithValue := make(chan struct{}, 1) + chWithValue <- struct{}{} + + True(t, Empty(mockT, ""), "Empty string is empty") + True(t, Empty(mockT, nil), "Nil is empty") + True(t, Empty(mockT, []string{}), "Empty string array is empty") + True(t, Empty(mockT, 0), "Zero int value is empty") + True(t, Empty(mockT, false), "False value is empty") + True(t, Empty(mockT, make(chan struct{})), "Channel without values is empty") + + False(t, Empty(mockT, "something"), "Non Empty string is not empty") + False(t, Empty(mockT, errors.New("something")), "Non nil object is not empty") + False(t, Empty(mockT, []string{"something"}), "Non empty string array is not empty") + False(t, Empty(mockT, 1), "Non-zero int value is not empty") + False(t, Empty(mockT, true), "True value is not empty") + False(t, Empty(mockT, chWithValue), "Channel with values is not empty") +} + +func TestNotEmpty(t *testing.T) { + + mockT := new(testing.T) + chWithValue := make(chan struct{}, 1) + chWithValue <- struct{}{} + + False(t, NotEmpty(mockT, ""), "Empty string is empty") + False(t, NotEmpty(mockT, nil), "Nil is empty") + False(t, NotEmpty(mockT, []string{}), "Empty string array is empty") + False(t, NotEmpty(mockT, 0), "Zero int value is empty") + False(t, NotEmpty(mockT, false), "False value is empty") + False(t, NotEmpty(mockT, make(chan struct{})), "Channel without values is empty") + + True(t, NotEmpty(mockT, "something"), "Non Empty string is not empty") + True(t, NotEmpty(mockT, errors.New("something")), "Non nil object is not empty") + True(t, NotEmpty(mockT, []string{"something"}), "Non empty string array is not empty") + True(t, NotEmpty(mockT, 1), "Non-zero int value is not empty") + True(t, NotEmpty(mockT, true), "True value is not empty") + True(t, NotEmpty(mockT, chWithValue), "Channel with values is not empty") +} + +func Test_getLen(t *testing.T) { + falseCases := []interface{}{ + nil, + 0, + true, + false, + 'A', + struct{}{}, + } + for _, v := range falseCases { + ok, l := getLen(v) + False(t, ok, "Expected getLen fail to get length of %#v", v) + Equal(t, 0, l, "getLen should return 0 for %#v", v) + } + + ch := make(chan int, 5) + ch <- 1 + ch <- 2 + ch <- 3 + trueCases := []struct { + v interface{} + l int + }{ + {[]int{1, 2, 3}, 3}, + {[...]int{1, 2, 3}, 3}, + {"ABC", 3}, + {map[int]int{1: 2, 2: 4, 3: 6}, 3}, + {ch, 3}, + + {[]int{}, 0}, + {map[int]int{}, 0}, + {make(chan int), 0}, + + {[]int(nil), 0}, + {map[int]int(nil), 0}, + {(chan int)(nil), 0}, + } + + for _, c := range trueCases { + ok, l := getLen(c.v) + True(t, ok, "Expected getLen success to get length of %#v", c.v) + Equal(t, c.l, l) + } +} + +func TestLen(t *testing.T) { + mockT := new(testing.T) + + False(t, Len(mockT, nil, 0), "nil does not have length") + False(t, Len(mockT, 0, 0), "int does not have length") + False(t, Len(mockT, true, 0), "true does not have length") + False(t, Len(mockT, false, 0), "false does not have length") + False(t, Len(mockT, 'A', 0), "Rune does not have length") + False(t, Len(mockT, struct{}{}, 0), "Struct does not have length") + + ch := make(chan int, 5) + ch <- 1 + ch <- 2 + ch <- 3 + + cases := []struct { + v interface{} + l int + }{ + {[]int{1, 2, 3}, 3}, + {[...]int{1, 2, 3}, 3}, + {"ABC", 3}, + {map[int]int{1: 2, 2: 4, 3: 6}, 3}, + {ch, 3}, + + {[]int{}, 0}, + {map[int]int{}, 0}, + {make(chan int), 0}, + + {[]int(nil), 0}, + {map[int]int(nil), 0}, + {(chan int)(nil), 0}, + } + + for _, c := range cases { + True(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l) + } + + cases = []struct { + v interface{} + l int + }{ + {[]int{1, 2, 3}, 4}, + {[...]int{1, 2, 3}, 2}, + {"ABC", 2}, + {map[int]int{1: 2, 2: 4, 3: 6}, 4}, + {ch, 2}, + + {[]int{}, 1}, + {map[int]int{}, 1}, + {make(chan int), 1}, + + {[]int(nil), 1}, + {map[int]int(nil), 1}, + {(chan int)(nil), 1}, + } + + for _, c := range cases { + False(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l) + } +} + +func TestWithinDuration(t *testing.T) { + + mockT := new(testing.T) + a := time.Now() + b := a.Add(10 * time.Second) + + True(t, WithinDuration(mockT, a, b, 10*time.Second), "A 10s difference is within a 10s time difference") + True(t, WithinDuration(mockT, b, a, 10*time.Second), "A 10s difference is within a 10s time difference") + + False(t, WithinDuration(mockT, a, b, 9*time.Second), "A 10s difference is not within a 9s time difference") + False(t, WithinDuration(mockT, b, a, 9*time.Second), "A 10s difference is not within a 9s time difference") + + False(t, WithinDuration(mockT, a, b, -9*time.Second), "A 10s difference is not within a 9s time difference") + False(t, WithinDuration(mockT, b, a, -9*time.Second), "A 10s difference is not within a 9s time difference") + + False(t, WithinDuration(mockT, a, b, -11*time.Second), "A 10s difference is not within a 9s time difference") + False(t, WithinDuration(mockT, b, a, -11*time.Second), "A 10s difference is not within a 9s time difference") +} + +func TestInDelta(t *testing.T) { + mockT := new(testing.T) + + True(t, InDelta(mockT, 1.001, 1, 0.01), "|1.001 - 1| <= 0.01") + True(t, InDelta(mockT, 1, 1.001, 0.01), "|1 - 1.001| <= 0.01") + True(t, InDelta(mockT, 1, 2, 1), "|1 - 2| <= 1") + False(t, InDelta(mockT, 1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail") + False(t, InDelta(mockT, 2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail") + False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail") + + cases := []struct { + a, b interface{} + delta float64 + }{ + {uint8(2), uint8(1), 1}, + {uint16(2), uint16(1), 1}, + {uint32(2), uint32(1), 1}, + {uint64(2), uint64(1), 1}, + + {int(2), int(1), 1}, + {int8(2), int8(1), 1}, + {int16(2), int16(1), 1}, + {int32(2), int32(1), 1}, + {int64(2), int64(1), 1}, + + {float32(2), float32(1), 1}, + {float64(2), float64(1), 1}, + } + + for _, tc := range cases { + True(t, InDelta(mockT, tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta) + } +} + +func TestInEpsilon(t *testing.T) { + mockT := new(testing.T) + + cases := []struct { + a, b interface{} + epsilon float64 + }{ + {uint8(2), uint16(2), .001}, + {2.1, 2.2, 0.1}, + {2.2, 2.1, 0.1}, + {-2.1, -2.2, 0.1}, + {-2.2, -2.1, 0.1}, + {uint64(100), uint8(101), 0.01}, + {0.1, -0.1, 2}, + } + + for _, tc := range cases { + True(t, InEpsilon(mockT, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon)) + } + + cases = []struct { + a, b interface{} + epsilon float64 + }{ + {uint8(2), int16(-2), .001}, + {uint64(100), uint8(102), 0.01}, + {2.1, 2.2, 0.001}, + {2.2, 2.1, 0.001}, + {2.1, -2.2, 1}, + {2.1, "bla-bla", 0}, + {0.1, -0.1, 1.99}, + } + + for _, tc := range cases { + False(t, InEpsilon(mockT, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon)) + } + +} + +func TestRegexp(t *testing.T) { + mockT := new(testing.T) + + cases := []struct { + rx, str string + }{ + {"^start", "start of the line"}, + {"end$", "in the end"}, + {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"}, + } + + for _, tc := range cases { + True(t, Regexp(mockT, tc.rx, tc.str)) + True(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str)) + False(t, NotRegexp(mockT, tc.rx, tc.str)) + False(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str)) + } + + cases = []struct { + rx, str string + }{ + {"^asdfastart", "Not the start of the line"}, + {"end$", "in the end."}, + {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"}, + } + + for _, tc := range cases { + False(t, Regexp(mockT, tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str) + False(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str)) + True(t, NotRegexp(mockT, tc.rx, tc.str)) + True(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str)) + } +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go new file mode 100644 index 000000000..1c6de283d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go @@ -0,0 +1,150 @@ +// A set of comprehensive testing tools for use with the normal Go testing system. +// +// Example Usage +// +// The following is a complete example using assert in a standard test function: +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) +// +// func TestSomething(t *testing.T) { +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(t, a, b, "The two words should be the same.") +// +// } +// +// if you assert many times, use the below: +// +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) +// +// func TestSomething(t *testing.T) { +// assert := assert.New(t) +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(a, b, "The two words should be the same.") +// } +// +// Assertions +// +// Assertions allow you to easily write test code, and are global funcs in the `assert` package. +// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// testing framework. This allows the assertion funcs to write the failings and other details to +// the correct place. +// +// Every assertion function also takes an optional string message as the final argument, +// allowing custom error messages to be appended to the message the assertion method outputs. +// +// Here is an overview of the assert functions: +// +// assert.Equal(t, expected, actual [, message [, format-args]) +// +// assert.NotEqual(t, notExpected, actual [, message [, format-args]]) +// +// assert.True(t, actualBool [, message [, format-args]]) +// +// assert.False(t, actualBool [, message [, format-args]]) +// +// assert.Nil(t, actualObject [, message [, format-args]]) +// +// assert.NotNil(t, actualObject [, message [, format-args]]) +// +// assert.Empty(t, actualObject [, message [, format-args]]) +// +// assert.NotEmpty(t, actualObject [, message [, format-args]]) +// +// assert.Len(t, actualObject, expectedLength, [, message [, format-args]]) +// +// assert.Error(t, errorObject [, message [, format-args]]) +// +// assert.NoError(t, errorObject [, message [, format-args]]) +// +// assert.EqualError(t, theError, errString [, message [, format-args]]) +// +// assert.Implements(t, (*MyInterface)(nil), new(MyObject) [,message [, format-args]]) +// +// assert.IsType(t, expectedObject, actualObject [, message [, format-args]]) +// +// assert.Contains(t, stringOrSlice, substringOrElement [, message [, format-args]]) +// +// assert.NotContains(t, stringOrSlice, substringOrElement [, message [, format-args]]) +// +// assert.Panics(t, func(){ +// +// // call code that should panic +// +// } [, message [, format-args]]) +// +// assert.NotPanics(t, func(){ +// +// // call code that should not panic +// +// } [, message [, format-args]]) +// +// assert.WithinDuration(t, timeA, timeB, deltaTime, [, message [, format-args]]) +// +// assert.InDelta(t, numA, numB, delta, [, message [, format-args]]) +// +// assert.InEpsilon(t, numA, numB, epsilon, [, message [, format-args]]) +// +// assert package contains Assertions object. it has assertion methods. +// +// Here is an overview of the assert functions: +// assert.Equal(expected, actual [, message [, format-args]) +// +// assert.NotEqual(notExpected, actual [, message [, format-args]]) +// +// assert.True(actualBool [, message [, format-args]]) +// +// assert.False(actualBool [, message [, format-args]]) +// +// assert.Nil(actualObject [, message [, format-args]]) +// +// assert.NotNil(actualObject [, message [, format-args]]) +// +// assert.Empty(actualObject [, message [, format-args]]) +// +// assert.NotEmpty(actualObject [, message [, format-args]]) +// +// assert.Len(actualObject, expectedLength, [, message [, format-args]]) +// +// assert.Error(errorObject [, message [, format-args]]) +// +// assert.NoError(errorObject [, message [, format-args]]) +// +// assert.EqualError(theError, errString [, message [, format-args]]) +// +// assert.Implements((*MyInterface)(nil), new(MyObject) [,message [, format-args]]) +// +// assert.IsType(expectedObject, actualObject [, message [, format-args]]) +// +// assert.Contains(stringOrSlice, substringOrElement [, message [, format-args]]) +// +// assert.NotContains(stringOrSlice, substringOrElement [, message [, format-args]]) +// +// assert.Panics(func(){ +// +// // call code that should panic +// +// } [, message [, format-args]]) +// +// assert.NotPanics(func(){ +// +// // call code that should not panic +// +// } [, message [, format-args]]) +// +// assert.WithinDuration(timeA, timeB, deltaTime, [, message [, format-args]]) +// +// assert.InDelta(numA, numB, delta, [, message [, format-args]]) +// +// assert.InEpsilon(numA, numB, epsilon, [, message [, format-args]]) +package assert diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/errors.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/errors.go new file mode 100644 index 000000000..ac9dc9d1d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/errors.go @@ -0,0 +1,10 @@ +package assert + +import ( + "errors" +) + +// AnError is an error instance useful for testing. If the code does not care +// about error specifics, and only needs to return the error for example, this +// error should be used to make the test code more readable. +var AnError = errors.New("assert.AnError general error for testing") diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go new file mode 100644 index 000000000..67a6925a1 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go @@ -0,0 +1,262 @@ +package assert + +import "time" + +type Assertions struct { + t TestingT +} + +func New(t TestingT) *Assertions { + return &Assertions{ + t: t, + } +} + +// Fail reports a failure through +func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { + return Fail(a.t, failureMessage, msgAndArgs...) +} + +// Implements asserts that an object is implemented by the specified interface. +// +// assert.Implements((*MyInterface)(nil), new(MyObject), "MyObject") +func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + return Implements(a.t, interfaceObject, object, msgAndArgs...) +} + +// IsType asserts that the specified objects are of the same type. +func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + return IsType(a.t, expectedType, object, msgAndArgs...) +} + +// Equal asserts that two objects are equal. +// +// assert.Equal(123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Equal(expected, actual interface{}, msgAndArgs ...interface{}) bool { + return Equal(a.t, expected, actual, msgAndArgs...) +} + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualValues(expected, actual interface{}, msgAndArgs ...interface{}) bool { + return EqualValues(a.t, expected, actual, msgAndArgs...) +} + +// Exactly asserts that two objects are equal is value and type. +// +// assert.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Exactly(expected, actual interface{}, msgAndArgs ...interface{}) bool { + return Exactly(a.t, expected, actual, msgAndArgs...) +} + +// NotNil asserts that the specified object is not nil. +// +// assert.NotNil(err, "err should be something") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { + return NotNil(a.t, object, msgAndArgs...) +} + +// Nil asserts that the specified object is nil. +// +// assert.Nil(err, "err should be nothing") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { + return Nil(a.t, object, msgAndArgs...) +} + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or a +// slice with len == 0. +// +// assert.Empty(obj) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { + return Empty(a.t, object, msgAndArgs...) +} + +// Empty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a +// slice with len == 0. +// +// if assert.NotEmpty(obj) { +// assert.Equal("two", obj[1]) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { + return NotEmpty(a.t, object, msgAndArgs...) +} + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// assert.Len(mySlice, 3, "The size of slice is not 3") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { + return Len(a.t, object, length, msgAndArgs...) +} + +// True asserts that the specified value is true. +// +// assert.True(myBool, "myBool should be true") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { + return True(a.t, value, msgAndArgs...) +} + +// False asserts that the specified value is true. +// +// assert.False(myBool, "myBool should be false") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { + return False(a.t, value, msgAndArgs...) +} + +// NotEqual asserts that the specified values are NOT equal. +// +// assert.NotEqual(obj1, obj2, "two objects shouldn't be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotEqual(expected, actual interface{}, msgAndArgs ...interface{}) bool { + return NotEqual(a.t, expected, actual, msgAndArgs...) +} + +// Contains asserts that the specified string contains the specified substring. +// +// assert.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Contains(s, contains interface{}, msgAndArgs ...interface{}) bool { + return Contains(a.t, s, contains, msgAndArgs...) +} + +// NotContains asserts that the specified string does NOT contain the specified substring. +// +// assert.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotContains(s, contains interface{}, msgAndArgs ...interface{}) bool { + return NotContains(a.t, s, contains, msgAndArgs...) +} + +// Uses a Comparison to assert a complex condition. +func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { + return Condition(a.t, comp, msgAndArgs...) +} + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panics(func(){ +// GoCrazy() +// }, "Calling GoCrazy() should panic") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + return Panics(a.t, f, msgAndArgs...) +} + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanics(func(){ +// RemainCalm() +// }, "Calling RemainCalm() should NOT panic") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + return NotPanics(a.t, f, msgAndArgs...) +} + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// assert.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) WithinDuration(expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) +} + +// InDelta asserts that the two numerals are within delta of each other. +// +// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) InDelta(expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + return InDelta(a.t, expected, actual, delta, msgAndArgs...) +} + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) InEpsilon(expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) +} + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoError(err) { +// assert.Equal(actualObj, expectedObj) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NoError(theError error, msgAndArgs ...interface{}) bool { + return NoError(a.t, theError, msgAndArgs...) +} + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Error(err, "An error was expected") { +// assert.Equal(err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Error(theError error, msgAndArgs ...interface{}) bool { + return Error(a.t, theError, msgAndArgs...) +} + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// if assert.Error(err, "An error was expected") { +// assert.Equal(err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { + return EqualError(a.t, theError, errString, msgAndArgs...) +} + +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + return Regexp(a.t, rx, str, msgAndArgs...) +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + return NotRegexp(a.t, rx, str, msgAndArgs...) +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go new file mode 100644 index 000000000..0dac6c7ae --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go @@ -0,0 +1,526 @@ +package assert + +import ( + "errors" + "regexp" + "testing" + "time" +) + +func TestImplementsWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) { + t.Error("Implements method should return true: AssertionTesterConformingObject implements AssertionTesterInterface") + } + if assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) { + t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface") + } +} + +func TestIsTypeWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) { + t.Error("IsType should return true: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject") + } + if assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) { + t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject") + } + +} + +func TestEqualWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.Equal("Hello World", "Hello World") { + t.Error("Equal should return true") + } + if !assert.Equal(123, 123) { + t.Error("Equal should return true") + } + if !assert.Equal(123.5, 123.5) { + t.Error("Equal should return true") + } + if !assert.Equal([]byte("Hello World"), []byte("Hello World")) { + t.Error("Equal should return true") + } + if !assert.Equal(nil, nil) { + t.Error("Equal should return true") + } +} + +func TestEqualValuesWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.EqualValues(uint32(10), int32(10)) { + t.Error("EqualValues should return true") + } +} + +func TestNotNilWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.NotNil(new(AssertionTesterConformingObject)) { + t.Error("NotNil should return true: object is not nil") + } + if assert.NotNil(nil) { + t.Error("NotNil should return false: object is nil") + } + +} + +func TestNilWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.Nil(nil) { + t.Error("Nil should return true: object is nil") + } + if assert.Nil(new(AssertionTesterConformingObject)) { + t.Error("Nil should return false: object is not nil") + } + +} + +func TestTrueWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.True(true) { + t.Error("True should return true") + } + if assert.True(false) { + t.Error("True should return false") + } + +} + +func TestFalseWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.False(false) { + t.Error("False should return true") + } + if assert.False(true) { + t.Error("False should return false") + } + +} + +func TestExactlyWrapper(t *testing.T) { + assert := New(new(testing.T)) + + a := float32(1) + b := float64(1) + c := float32(1) + d := float32(2) + + if assert.Exactly(a, b) { + t.Error("Exactly should return false") + } + if assert.Exactly(a, d) { + t.Error("Exactly should return false") + } + if !assert.Exactly(a, c) { + t.Error("Exactly should return true") + } + + if assert.Exactly(nil, a) { + t.Error("Exactly should return false") + } + if assert.Exactly(a, nil) { + t.Error("Exactly should return false") + } + +} + +func TestNotEqualWrapper(t *testing.T) { + + assert := New(new(testing.T)) + + if !assert.NotEqual("Hello World", "Hello World!") { + t.Error("NotEqual should return true") + } + if !assert.NotEqual(123, 1234) { + t.Error("NotEqual should return true") + } + if !assert.NotEqual(123.5, 123.55) { + t.Error("NotEqual should return true") + } + if !assert.NotEqual([]byte("Hello World"), []byte("Hello World!")) { + t.Error("NotEqual should return true") + } + if !assert.NotEqual(nil, new(AssertionTesterConformingObject)) { + t.Error("NotEqual should return true") + } +} + +func TestContainsWrapper(t *testing.T) { + + assert := New(new(testing.T)) + list := []string{"Foo", "Bar"} + + if !assert.Contains("Hello World", "Hello") { + t.Error("Contains should return true: \"Hello World\" contains \"Hello\"") + } + if assert.Contains("Hello World", "Salut") { + t.Error("Contains should return false: \"Hello World\" does not contain \"Salut\"") + } + + if !assert.Contains(list, "Foo") { + t.Error("Contains should return true: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"") + } + if assert.Contains(list, "Salut") { + t.Error("Contains should return false: \"[\"Foo\", \"Bar\"]\" does not contain \"Salut\"") + } + +} + +func TestNotContainsWrapper(t *testing.T) { + + assert := New(new(testing.T)) + list := []string{"Foo", "Bar"} + + if !assert.NotContains("Hello World", "Hello!") { + t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"") + } + if assert.NotContains("Hello World", "Hello") { + t.Error("NotContains should return false: \"Hello World\" contains \"Hello\"") + } + + if !assert.NotContains(list, "Foo!") { + t.Error("NotContains should return true: \"[\"Foo\", \"Bar\"]\" does not contain \"Foo!\"") + } + if assert.NotContains(list, "Foo") { + t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"") + } + +} + +func TestConditionWrapper(t *testing.T) { + + assert := New(new(testing.T)) + + if !assert.Condition(func() bool { return true }, "Truth") { + t.Error("Condition should return true") + } + + if assert.Condition(func() bool { return false }, "Lie") { + t.Error("Condition should return false") + } + +} + +func TestDidPanicWrapper(t *testing.T) { + + if funcDidPanic, _ := didPanic(func() { + panic("Panic!") + }); !funcDidPanic { + t.Error("didPanic should return true") + } + + if funcDidPanic, _ := didPanic(func() { + }); funcDidPanic { + t.Error("didPanic should return false") + } + +} + +func TestPanicsWrapper(t *testing.T) { + + assert := New(new(testing.T)) + + if !assert.Panics(func() { + panic("Panic!") + }) { + t.Error("Panics should return true") + } + + if assert.Panics(func() { + }) { + t.Error("Panics should return false") + } + +} + +func TestNotPanicsWrapper(t *testing.T) { + + assert := New(new(testing.T)) + + if !assert.NotPanics(func() { + }) { + t.Error("NotPanics should return true") + } + + if assert.NotPanics(func() { + panic("Panic!") + }) { + t.Error("NotPanics should return false") + } + +} + +func TestEqualWrapper_Funcs(t *testing.T) { + + assert := New(t) + + type f func() int + var f1 f = func() int { return 1 } + var f2 f = func() int { return 2 } + + var f1_copy f = f1 + + assert.Equal(f1_copy, f1, "Funcs are the same and should be considered equal") + assert.NotEqual(f1, f2, "f1 and f2 are different") + +} + +func TestNoErrorWrapper(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + + // start with a nil error + var err error = nil + + assert.True(mockAssert.NoError(err), "NoError should return True for nil arg") + + // now set an error + err = errors.New("Some error") + + assert.False(mockAssert.NoError(err), "NoError with error should return False") + +} + +func TestErrorWrapper(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + + // start with a nil error + var err error = nil + + assert.False(mockAssert.Error(err), "Error should return False for nil arg") + + // now set an error + err = errors.New("Some error") + + assert.True(mockAssert.Error(err), "Error with error should return True") + +} + +func TestEqualErrorWrapper(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + + // start with a nil error + var err error + assert.False(mockAssert.EqualError(err, ""), + "EqualError should return false for nil arg") + + // now set an error + err = errors.New("some error") + assert.False(mockAssert.EqualError(err, "Not some error"), + "EqualError should return false for different error string") + assert.True(mockAssert.EqualError(err, "some error"), + "EqualError should return true") +} + +func TestEmptyWrapper(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + + assert.True(mockAssert.Empty(""), "Empty string is empty") + assert.True(mockAssert.Empty(nil), "Nil is empty") + assert.True(mockAssert.Empty([]string{}), "Empty string array is empty") + assert.True(mockAssert.Empty(0), "Zero int value is empty") + assert.True(mockAssert.Empty(false), "False value is empty") + + assert.False(mockAssert.Empty("something"), "Non Empty string is not empty") + assert.False(mockAssert.Empty(errors.New("something")), "Non nil object is not empty") + assert.False(mockAssert.Empty([]string{"something"}), "Non empty string array is not empty") + assert.False(mockAssert.Empty(1), "Non-zero int value is not empty") + assert.False(mockAssert.Empty(true), "True value is not empty") + +} + +func TestNotEmptyWrapper(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + + assert.False(mockAssert.NotEmpty(""), "Empty string is empty") + assert.False(mockAssert.NotEmpty(nil), "Nil is empty") + assert.False(mockAssert.NotEmpty([]string{}), "Empty string array is empty") + assert.False(mockAssert.NotEmpty(0), "Zero int value is empty") + assert.False(mockAssert.NotEmpty(false), "False value is empty") + + assert.True(mockAssert.NotEmpty("something"), "Non Empty string is not empty") + assert.True(mockAssert.NotEmpty(errors.New("something")), "Non nil object is not empty") + assert.True(mockAssert.NotEmpty([]string{"something"}), "Non empty string array is not empty") + assert.True(mockAssert.NotEmpty(1), "Non-zero int value is not empty") + assert.True(mockAssert.NotEmpty(true), "True value is not empty") + +} + +func TestLenWrapper(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + + assert.False(mockAssert.Len(nil, 0), "nil does not have length") + assert.False(mockAssert.Len(0, 0), "int does not have length") + assert.False(mockAssert.Len(true, 0), "true does not have length") + assert.False(mockAssert.Len(false, 0), "false does not have length") + assert.False(mockAssert.Len('A', 0), "Rune does not have length") + assert.False(mockAssert.Len(struct{}{}, 0), "Struct does not have length") + + ch := make(chan int, 5) + ch <- 1 + ch <- 2 + ch <- 3 + + cases := []struct { + v interface{} + l int + }{ + {[]int{1, 2, 3}, 3}, + {[...]int{1, 2, 3}, 3}, + {"ABC", 3}, + {map[int]int{1: 2, 2: 4, 3: 6}, 3}, + {ch, 3}, + + {[]int{}, 0}, + {map[int]int{}, 0}, + {make(chan int), 0}, + + {[]int(nil), 0}, + {map[int]int(nil), 0}, + {(chan int)(nil), 0}, + } + + for _, c := range cases { + assert.True(mockAssert.Len(c.v, c.l), "%#v have %d items", c.v, c.l) + } +} + +func TestWithinDurationWrapper(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + a := time.Now() + b := a.Add(10 * time.Second) + + assert.True(mockAssert.WithinDuration(a, b, 10*time.Second), "A 10s difference is within a 10s time difference") + assert.True(mockAssert.WithinDuration(b, a, 10*time.Second), "A 10s difference is within a 10s time difference") + + assert.False(mockAssert.WithinDuration(a, b, 9*time.Second), "A 10s difference is not within a 9s time difference") + assert.False(mockAssert.WithinDuration(b, a, 9*time.Second), "A 10s difference is not within a 9s time difference") + + assert.False(mockAssert.WithinDuration(a, b, -9*time.Second), "A 10s difference is not within a 9s time difference") + assert.False(mockAssert.WithinDuration(b, a, -9*time.Second), "A 10s difference is not within a 9s time difference") + + assert.False(mockAssert.WithinDuration(a, b, -11*time.Second), "A 10s difference is not within a 9s time difference") + assert.False(mockAssert.WithinDuration(b, a, -11*time.Second), "A 10s difference is not within a 9s time difference") +} + +func TestInDeltaWrapper(t *testing.T) { + assert := New(new(testing.T)) + + True(t, assert.InDelta(1.001, 1, 0.01), "|1.001 - 1| <= 0.01") + True(t, assert.InDelta(1, 1.001, 0.01), "|1 - 1.001| <= 0.01") + True(t, assert.InDelta(1, 2, 1), "|1 - 2| <= 1") + False(t, assert.InDelta(1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail") + False(t, assert.InDelta(2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail") + False(t, assert.InDelta("", nil, 1), "Expected non numerals to fail") + + cases := []struct { + a, b interface{} + delta float64 + }{ + {uint8(2), uint8(1), 1}, + {uint16(2), uint16(1), 1}, + {uint32(2), uint32(1), 1}, + {uint64(2), uint64(1), 1}, + + {int(2), int(1), 1}, + {int8(2), int8(1), 1}, + {int16(2), int16(1), 1}, + {int32(2), int32(1), 1}, + {int64(2), int64(1), 1}, + + {float32(2), float32(1), 1}, + {float64(2), float64(1), 1}, + } + + for _, tc := range cases { + True(t, assert.InDelta(tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta) + } +} + +func TestInEpsilonWrapper(t *testing.T) { + assert := New(new(testing.T)) + + cases := []struct { + a, b interface{} + epsilon float64 + }{ + {uint8(2), uint16(2), .001}, + {2.1, 2.2, 0.1}, + {2.2, 2.1, 0.1}, + {-2.1, -2.2, 0.1}, + {-2.2, -2.1, 0.1}, + {uint64(100), uint8(101), 0.01}, + {0.1, -0.1, 2}, + } + + for _, tc := range cases { + True(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon)) + } + + cases = []struct { + a, b interface{} + epsilon float64 + }{ + {uint8(2), int16(-2), .001}, + {uint64(100), uint8(102), 0.01}, + {2.1, 2.2, 0.001}, + {2.2, 2.1, 0.001}, + {2.1, -2.2, 1}, + {2.1, "bla-bla", 0}, + {0.1, -0.1, 1.99}, + } + + for _, tc := range cases { + False(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon)) + } +} + +func TestRegexpWrapper(t *testing.T) { + + assert := New(new(testing.T)) + + cases := []struct { + rx, str string + }{ + {"^start", "start of the line"}, + {"end$", "in the end"}, + {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"}, + } + + for _, tc := range cases { + True(t, assert.Regexp(tc.rx, tc.str)) + True(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str)) + False(t, assert.NotRegexp(tc.rx, tc.str)) + False(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str)) + } + + cases = []struct { + rx, str string + }{ + {"^asdfastart", "Not the start of the line"}, + {"end$", "in the end."}, + {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"}, + } + + for _, tc := range cases { + False(t, assert.Regexp(tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str) + False(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str)) + True(t, assert.NotRegexp(tc.rx, tc.str)) + True(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str)) + } +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go new file mode 100644 index 000000000..0419c1b60 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go @@ -0,0 +1,157 @@ +package assert + +import ( + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strings" +) + +// httpCode is a helper that returns HTTP code of the response. It returns -1 +// if building a new request fails. +func httpCode(handler http.HandlerFunc, mode, url string, values url.Values) int { + w := httptest.NewRecorder() + req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil) + if err != nil { + return -1 + } + handler(w, req) + return w.Code +} + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccess(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool { + code := httpCode(handler, mode, url, values) + if code == -1 { + return false + } + return code >= http.StatusOK && code <= http.StatusPartialContent +} + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPRedirect(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool { + code := httpCode(handler, mode, url, values) + if code == -1 { + return false + } + return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect +} + +// HTTPError asserts that a specified handler returns an error status code. +// +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPError(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool { + code := httpCode(handler, mode, url, values) + if code == -1 { + return false + } + return code >= http.StatusBadRequest +} + +// HttpBody is a helper that returns HTTP body of the response. It returns +// empty string if building a new request fails. +func HttpBody(handler http.HandlerFunc, mode, url string, values url.Values) string { + w := httptest.NewRecorder() + req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil) + if err != nil { + return "" + } + handler(w, req) + return w.Body.String() +} + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool { + body := HttpBody(handler, mode, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if !contains { + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) + } + + return contains +} + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool { + body := HttpBody(handler, mode, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if contains { + Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body) + } + + return !contains +} + +// +// Assertions Wrappers +// + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, mode, url string, values url.Values) bool { + return HTTPSuccess(a.t, handler, mode, url, values) +} + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, mode, url string, values url.Values) bool { + return HTTPRedirect(a.t, handler, mode, url, values) +} + +// HTTPError asserts that a specified handler returns an error status code. +// +// assert.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPError(handler http.HandlerFunc, mode, url string, values url.Values) bool { + return HTTPError(a.t, handler, mode, url, values) +} + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool { + return HTTPBodyContains(a.t, handler, mode, url, values, str) +} + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool { + return HTTPBodyNotContains(a.t, handler, mode, url, values, str) +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions_test.go new file mode 100644 index 000000000..684c2d5d1 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions_test.go @@ -0,0 +1,86 @@ +package assert + +import ( + "fmt" + "net/http" + "net/url" + "testing" +) + +func httpOK(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) +} + +func httpRedirect(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusTemporaryRedirect) +} + +func httpError(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) +} + +func TestHTTPStatuses(t *testing.T) { + assert := New(t) + mockT := new(testing.T) + + assert.Equal(HTTPSuccess(mockT, httpOK, "GET", "/", nil), true) + assert.Equal(HTTPSuccess(mockT, httpRedirect, "GET", "/", nil), false) + assert.Equal(HTTPSuccess(mockT, httpError, "GET", "/", nil), false) + + assert.Equal(HTTPRedirect(mockT, httpOK, "GET", "/", nil), false) + assert.Equal(HTTPRedirect(mockT, httpRedirect, "GET", "/", nil), true) + assert.Equal(HTTPRedirect(mockT, httpError, "GET", "/", nil), false) + + assert.Equal(HTTPError(mockT, httpOK, "GET", "/", nil), false) + assert.Equal(HTTPError(mockT, httpRedirect, "GET", "/", nil), false) + assert.Equal(HTTPError(mockT, httpError, "GET", "/", nil), true) +} + +func TestHTTPStatusesWrapper(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + + assert.Equal(mockAssert.HTTPSuccess(httpOK, "GET", "/", nil), true) + assert.Equal(mockAssert.HTTPSuccess(httpRedirect, "GET", "/", nil), false) + assert.Equal(mockAssert.HTTPSuccess(httpError, "GET", "/", nil), false) + + assert.Equal(mockAssert.HTTPRedirect(httpOK, "GET", "/", nil), false) + assert.Equal(mockAssert.HTTPRedirect(httpRedirect, "GET", "/", nil), true) + assert.Equal(mockAssert.HTTPRedirect(httpError, "GET", "/", nil), false) + + assert.Equal(mockAssert.HTTPError(httpOK, "GET", "/", nil), false) + assert.Equal(mockAssert.HTTPError(httpRedirect, "GET", "/", nil), false) + assert.Equal(mockAssert.HTTPError(httpError, "GET", "/", nil), true) +} + +func httpHelloName(w http.ResponseWriter, r *http.Request) { + name := r.FormValue("name") + w.Write([]byte(fmt.Sprintf("Hello, %s!", name))) +} + +func TestHttpBody(t *testing.T) { + assert := New(t) + mockT := new(testing.T) + + assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!")) + assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World")) + assert.False(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world")) + + assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!")) + assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World")) + assert.True(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world")) +} + +func TestHttpBodyWrappers(t *testing.T) { + assert := New(t) + mockAssert := New(new(testing.T)) + + assert.True(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!")) + assert.True(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World")) + assert.False(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world")) + + assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!")) + assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World")) + assert.True(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world")) + +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/doc.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/doc.go new file mode 100644 index 000000000..dd385074b --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/doc.go @@ -0,0 +1,43 @@ +// Provides a system by which it is possible to mock your objects and verify calls are happening as expected. +// +// Example Usage +// +// The mock package provides an object, Mock, that tracks activity on another object. It is usually +// embedded into a test object as shown below: +// +// type MyTestObject struct { +// // add a Mock object instance +// mock.Mock +// +// // other fields go here as normal +// } +// +// When implementing the methods of an interface, you wire your functions up +// to call the Mock.Called(args...) method, and return the appropriate values. +// +// For example, to mock a method that saves the name and age of a person and returns +// the year of their birth or an error, you might write this: +// +// func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) { +// args := o.Called(firstname, lastname, age) +// return args.Int(0), args.Error(1) +// } +// +// The Int, Error and Bool methods are examples of strongly typed getters that take the argument +// index position. Given this argument list: +// +// (12, true, "Something") +// +// You could read them out strongly typed like this: +// +// args.Int(0) +// args.Bool(1) +// args.String(2) +// +// For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion: +// +// return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine) +// +// This may cause a panic if the object you are getting is nil (the type assertion will fail), in those +// cases you should check for nil first. +package mock diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go new file mode 100644 index 000000000..f73fa2516 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go @@ -0,0 +1,510 @@ +package mock + +import ( + "fmt" + "github.com/stretchr/objx" + "github.com/stretchr/testify/assert" + "reflect" + "runtime" + "strings" + "sync" +) + +// TestingT is an interface wrapper around *testing.T +type TestingT interface { + Logf(format string, args ...interface{}) + Errorf(format string, args ...interface{}) +} + +/* + Call +*/ + +// Call represents a method call and is used for setting expectations, +// as well as recording activity. +type Call struct { + + // The name of the method that was or will be called. + Method string + + // Holds the arguments of the method. + Arguments Arguments + + // Holds the arguments that should be returned when + // this method is called. + ReturnArguments Arguments + + // The number of times to return the return arguments when setting + // expectations. 0 means to always return the value. + Repeatability int +} + +// Mock is the workhorse used to track activity on another object. +// For an example of its usage, refer to the "Example Usage" section at the top of this document. +type Mock struct { + + // The method name that is currently + // being referred to by the On method. + onMethodName string + + // An array of the arguments that are + // currently being referred to by the On method. + onMethodArguments Arguments + + // Represents the calls that are expected of + // an object. + ExpectedCalls []Call + + // Holds the calls that were made to this mocked object. + Calls []Call + + // TestData holds any data that might be useful for testing. Testify ignores + // this data completely allowing you to do whatever you like with it. + testData objx.Map + + mutex sync.Mutex +} + +// TestData holds any data that might be useful for testing. Testify ignores +// this data completely allowing you to do whatever you like with it. +func (m *Mock) TestData() objx.Map { + + if m.testData == nil { + m.testData = make(objx.Map) + } + + return m.testData +} + +/* + Setting expectations +*/ + +// On starts a description of an expectation of the specified method +// being called. +// +// Mock.On("MyMethod", arg1, arg2) +func (m *Mock) On(methodName string, arguments ...interface{}) *Mock { + m.onMethodName = methodName + m.onMethodArguments = arguments + return m +} + +// Return finishes a description of an expectation of the method (and arguments) +// specified in the most recent On method call. +// +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2) +func (m *Mock) Return(returnArguments ...interface{}) *Mock { + m.ExpectedCalls = append(m.ExpectedCalls, Call{m.onMethodName, m.onMethodArguments, returnArguments, 0}) + return m +} + +// Once indicates that that the mock should only return the value once. +// +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once() +func (m *Mock) Once() { + m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = 1 +} + +// Twice indicates that that the mock should only return the value twice. +// +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice() +func (m *Mock) Twice() { + m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = 2 +} + +// Times indicates that that the mock should only return the indicated number +// of times. +// +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5) +func (m *Mock) Times(i int) { + m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = i +} + +/* + Recording and responding to activity +*/ + +func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *Call) { + for i, call := range m.ExpectedCalls { + if call.Method == method && call.Repeatability > -1 { + + _, diffCount := call.Arguments.Diff(arguments) + if diffCount == 0 { + return i, &call + } + + } + } + return -1, nil +} + +func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) { + + diffCount := 0 + var closestCall *Call = nil + + for _, call := range m.ExpectedCalls { + if call.Method == method { + + _, tempDiffCount := call.Arguments.Diff(arguments) + if tempDiffCount < diffCount || diffCount == 0 { + diffCount = tempDiffCount + closestCall = &call + } + + } + } + + if closestCall == nil { + return false, nil + } + + return true, closestCall +} + +func callString(method string, arguments Arguments, includeArgumentValues bool) string { + + var argValsString string = "" + if includeArgumentValues { + var argVals []string + for argIndex, arg := range arguments { + argVals = append(argVals, fmt.Sprintf("%d: %v", argIndex, arg)) + } + argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t")) + } + + return fmt.Sprintf("%s(%s)%s", method, arguments.String(), argValsString) +} + +// Called tells the mock object that a method has been called, and gets an array +// of arguments to return. Panics if the call is unexpected (i.e. not preceeded by +// appropriate .On .Return() calls) +func (m *Mock) Called(arguments ...interface{}) Arguments { + defer m.mutex.Unlock() + m.mutex.Lock() + + // get the calling function's name + pc, _, _, ok := runtime.Caller(1) + if !ok { + panic("Couldn't get the caller information") + } + functionPath := runtime.FuncForPC(pc).Name() + parts := strings.Split(functionPath, ".") + functionName := parts[len(parts)-1] + + found, call := m.findExpectedCall(functionName, arguments...) + + switch { + case found < 0: + // we have to fail here - because we don't know what to do + // as the return arguments. This is because: + // + // a) this is a totally unexpected call to this method, + // b) the arguments are not what was expected, or + // c) the developer has forgotten to add an accompanying On...Return pair. + + closestFound, closestCall := m.findClosestCall(functionName, arguments...) + + if closestFound { + panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n", callString(functionName, arguments, true), callString(functionName, closestCall.Arguments, true))) + } else { + panic(fmt.Sprintf("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", functionName, functionName, callString(functionName, arguments, true), assert.CallerInfo())) + } + case call.Repeatability == 1: + call.Repeatability = -1 + m.ExpectedCalls[found] = *call + case call.Repeatability > 1: + call.Repeatability -= 1 + m.ExpectedCalls[found] = *call + } + + // add the call + m.Calls = append(m.Calls, Call{functionName, arguments, make([]interface{}, 0), 0}) + + return call.ReturnArguments + +} + +/* + Assertions +*/ + +// AssertExpectationsForObjects asserts that everything specified with On and Return +// of the specified objects was in fact called as expected. +// +// Calls may have occurred in any order. +func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool { + var success bool = true + for _, obj := range testObjects { + mockObj := obj.(Mock) + success = success && mockObj.AssertExpectations(t) + } + return success +} + +// AssertExpectations asserts that everything specified with On and Return was +// in fact called as expected. Calls may have occurred in any order. +func (m *Mock) AssertExpectations(t TestingT) bool { + + var somethingMissing bool = false + var failedExpectations int = 0 + + // iterate through each expectation + for _, expectedCall := range m.ExpectedCalls { + switch { + case !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments): + somethingMissing = true + failedExpectations++ + t.Logf("\u274C\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String()) + case expectedCall.Repeatability > 0: + somethingMissing = true + failedExpectations++ + default: + t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String()) + } + } + + if somethingMissing { + t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(m.ExpectedCalls)-failedExpectations, len(m.ExpectedCalls), failedExpectations, assert.CallerInfo()) + } + + return !somethingMissing +} + +// AssertNumberOfCalls asserts that the method was called expectedCalls times. +func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool { + var actualCalls int = 0 + for _, call := range m.Calls { + if call.Method == methodName { + actualCalls++ + } + } + return assert.Equal(t, actualCalls, expectedCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls)) +} + +// AssertCalled asserts that the method was called. +func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool { + if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) { + t.Logf("%s", m.ExpectedCalls) + return false + } + return true +} + +// AssertNotCalled asserts that the method was not called. +func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool { + if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) { + t.Logf("%s", m.ExpectedCalls) + return false + } + return true +} + +func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool { + for _, call := range m.Calls { + if call.Method == methodName { + + _, differences := Arguments(expected).Diff(call.Arguments) + + if differences == 0 { + // found the expected call + return true + } + + } + } + // we didn't find the expected call + return false +} + +/* + Arguments +*/ + +// Arguments holds an array of method arguments or return values. +type Arguments []interface{} + +const ( + // The "any" argument. Used in Diff and Assert when + // the argument being tested shouldn't be taken into consideration. + Anything string = "mock.Anything" +) + +// AnythingOfTypeArgument is a string that contains the type of an argument +// for use when type checking. Used in Diff and Assert. +type AnythingOfTypeArgument string + +// AnythingOfType returns an AnythingOfTypeArgument object containing the +// name of the type to check for. Used in Diff and Assert. +// +// For example: +// Assert(t, AnythingOfType("string"), AnythingOfType("int")) +func AnythingOfType(t string) AnythingOfTypeArgument { + return AnythingOfTypeArgument(t) +} + +// Get Returns the argument at the specified index. +func (args Arguments) Get(index int) interface{} { + if index+1 > len(args) { + panic(fmt.Sprintf("assert: arguments: Cannot call Get(%d) because there are %d argument(s).", index, len(args))) + } + return args[index] +} + +// Is gets whether the objects match the arguments specified. +func (args Arguments) Is(objects ...interface{}) bool { + for i, obj := range args { + if obj != objects[i] { + return false + } + } + return true +} + +// Diff gets a string describing the differences between the arguments +// and the specified objects. +// +// Returns the diff string and number of differences found. +func (args Arguments) Diff(objects []interface{}) (string, int) { + + var output string = "\n" + var differences int + + var maxArgCount int = len(args) + if len(objects) > maxArgCount { + maxArgCount = len(objects) + } + + for i := 0; i < maxArgCount; i++ { + var actual, expected interface{} + + if len(objects) <= i { + actual = "(Missing)" + } else { + actual = objects[i] + } + + if len(args) <= i { + expected = "(Missing)" + } else { + expected = args[i] + } + + if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() { + + // type checking + if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) { + // not match + differences++ + output = fmt.Sprintf("%s\t%d: \u274C type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actual) + } + + } else { + + // normal checking + + if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) { + // match + output = fmt.Sprintf("%s\t%d: \u2705 %s == %s\n", output, i, actual, expected) + } else { + // not match + differences++ + output = fmt.Sprintf("%s\t%d: \u274C %s != %s\n", output, i, actual, expected) + } + } + + } + + if differences == 0 { + return "No differences.", differences + } + + return output, differences + +} + +// Assert compares the arguments with the specified objects and fails if +// they do not exactly match. +func (args Arguments) Assert(t TestingT, objects ...interface{}) bool { + + // get the differences + diff, diffCount := args.Diff(objects) + + if diffCount == 0 { + return true + } + + // there are differences... report them... + t.Logf(diff) + t.Errorf("%sArguments do not match.", assert.CallerInfo()) + + return false + +} + +// String gets the argument at the specified index. Panics if there is no argument, or +// if the argument is of the wrong type. +// +// If no index is provided, String() returns a complete string representation +// of the arguments. +func (args Arguments) String(indexOrNil ...int) string { + + if len(indexOrNil) == 0 { + // normal String() method - return a string representation of the args + var argsStr []string + for _, arg := range args { + argsStr = append(argsStr, fmt.Sprintf("%s", reflect.TypeOf(arg))) + } + return strings.Join(argsStr, ",") + } else if len(indexOrNil) == 1 { + // Index has been specified - get the argument at that index + var index int = indexOrNil[0] + var s string + var ok bool + if s, ok = args.Get(index).(string); !ok { + panic(fmt.Sprintf("assert: arguments: String(%d) failed because object wasn't correct type: %s", index, args.Get(index))) + } + return s + } + + panic(fmt.Sprintf("assert: arguments: Wrong number of arguments passed to String. Must be 0 or 1, not %d", len(indexOrNil))) + +} + +// Int gets the argument at the specified index. Panics if there is no argument, or +// if the argument is of the wrong type. +func (args Arguments) Int(index int) int { + var s int + var ok bool + if s, ok = args.Get(index).(int); !ok { + panic(fmt.Sprintf("assert: arguments: Int(%d) failed because object wasn't correct type: %v", index, args.Get(index))) + } + return s +} + +// Error gets the argument at the specified index. Panics if there is no argument, or +// if the argument is of the wrong type. +func (args Arguments) Error(index int) error { + obj := args.Get(index) + var s error + var ok bool + if obj == nil { + return nil + } + if s, ok = obj.(error); !ok { + panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, args.Get(index))) + } + return s +} + +// Bool gets the argument at the specified index. Panics if there is no argument, or +// if the argument is of the wrong type. +func (args Arguments) Bool(index int) bool { + var s bool + var ok bool + if s, ok = args.Get(index).(bool); !ok { + panic(fmt.Sprintf("assert: arguments: Bool(%d) failed because object wasn't correct type: %v", index, args.Get(index))) + } + return s +} diff --git a/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock_test.go b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock_test.go new file mode 100644 index 000000000..a4457e071 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock_test.go @@ -0,0 +1,669 @@ +package mock + +import ( + "errors" + "github.com/stretchr/testify/assert" + "testing" +) + +/* + Test objects +*/ + +// ExampleInterface represents an example interface. +type ExampleInterface interface { + TheExampleMethod(a, b, c int) (int, error) +} + +// TestExampleImplementation is a test implementation of ExampleInterface +type TestExampleImplementation struct { + Mock +} + +func (i *TestExampleImplementation) TheExampleMethod(a, b, c int) (int, error) { + args := i.Called(a, b, c) + return args.Int(0), errors.New("Whoops") +} + +func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) { + i.Called(yesorno) +} + +type ExampleType struct{} + +func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error { + args := i.Called(et) + return args.Error(0) +} + +/* + Mock +*/ + +func Test_Mock_TestData(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + if assert.NotNil(t, mockedService.TestData()) { + + mockedService.TestData().Set("something", 123) + assert.Equal(t, 123, mockedService.TestData().Get("something").Data()) + + } + +} + +func Test_Mock_On(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Equal(t, mockedService.On("TheExampleMethod"), &mockedService.Mock) + assert.Equal(t, "TheExampleMethod", mockedService.onMethodName) + +} + +func Test_Mock_On_WithArgs(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Equal(t, mockedService.On("TheExampleMethod", 1, 2, 3), &mockedService.Mock) + assert.Equal(t, "TheExampleMethod", mockedService.onMethodName) + assert.Equal(t, 1, mockedService.onMethodArguments[0]) + assert.Equal(t, 2, mockedService.onMethodArguments[1]) + assert.Equal(t, 3, mockedService.onMethodArguments[2]) + +} + +func Test_Mock_Return(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Equal(t, mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true), &mockedService.Mock) + + // ensure the call was created + if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) { + call := mockedService.ExpectedCalls[0] + + assert.Equal(t, "TheExampleMethod", call.Method) + assert.Equal(t, "A", call.Arguments[0]) + assert.Equal(t, "B", call.Arguments[1]) + assert.Equal(t, true, call.Arguments[2]) + assert.Equal(t, 1, call.ReturnArguments[0]) + assert.Equal(t, "two", call.ReturnArguments[1]) + assert.Equal(t, true, call.ReturnArguments[2]) + assert.Equal(t, 0, call.Repeatability) + + } + +} + +func Test_Mock_Return_Once(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Once() + + // ensure the call was created + if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) { + call := mockedService.ExpectedCalls[0] + + assert.Equal(t, "TheExampleMethod", call.Method) + assert.Equal(t, "A", call.Arguments[0]) + assert.Equal(t, "B", call.Arguments[1]) + assert.Equal(t, true, call.Arguments[2]) + assert.Equal(t, 1, call.ReturnArguments[0]) + assert.Equal(t, "two", call.ReturnArguments[1]) + assert.Equal(t, true, call.ReturnArguments[2]) + assert.Equal(t, 1, call.Repeatability) + + } + +} + +func Test_Mock_Return_Twice(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Twice() + + // ensure the call was created + if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) { + call := mockedService.ExpectedCalls[0] + + assert.Equal(t, "TheExampleMethod", call.Method) + assert.Equal(t, "A", call.Arguments[0]) + assert.Equal(t, "B", call.Arguments[1]) + assert.Equal(t, true, call.Arguments[2]) + assert.Equal(t, 1, call.ReturnArguments[0]) + assert.Equal(t, "two", call.ReturnArguments[1]) + assert.Equal(t, true, call.ReturnArguments[2]) + assert.Equal(t, 2, call.Repeatability) + + } + +} + +func Test_Mock_Return_Times(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Times(5) + + // ensure the call was created + if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) { + call := mockedService.ExpectedCalls[0] + + assert.Equal(t, "TheExampleMethod", call.Method) + assert.Equal(t, "A", call.Arguments[0]) + assert.Equal(t, "B", call.Arguments[1]) + assert.Equal(t, true, call.Arguments[2]) + assert.Equal(t, 1, call.ReturnArguments[0]) + assert.Equal(t, "two", call.ReturnArguments[1]) + assert.Equal(t, true, call.ReturnArguments[2]) + assert.Equal(t, 5, call.Repeatability) + + } + +} + +func Test_Mock_Return_Nothing(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Equal(t, mockedService.On("TheExampleMethod", "A", "B", true).Return(), &mockedService.Mock) + + // ensure the call was created + if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) { + call := mockedService.ExpectedCalls[0] + + assert.Equal(t, "TheExampleMethod", call.Method) + assert.Equal(t, "A", call.Arguments[0]) + assert.Equal(t, "B", call.Arguments[1]) + assert.Equal(t, true, call.Arguments[2]) + assert.Equal(t, 0, len(call.ReturnArguments)) + + } + +} + +func Test_Mock_findExpectedCall(t *testing.T) { + + m := new(Mock) + m.On("One", 1).Return("one") + m.On("Two", 2).Return("two") + m.On("Two", 3).Return("three") + + f, c := m.findExpectedCall("Two", 3) + + if assert.Equal(t, 2, f) { + if assert.NotNil(t, c) { + assert.Equal(t, "Two", c.Method) + assert.Equal(t, 3, c.Arguments[0]) + assert.Equal(t, "three", c.ReturnArguments[0]) + } + } + +} + +func Test_Mock_findExpectedCall_For_Unknown_Method(t *testing.T) { + + m := new(Mock) + m.On("One", 1).Return("one") + m.On("Two", 2).Return("two") + m.On("Two", 3).Return("three") + + f, _ := m.findExpectedCall("Two") + + assert.Equal(t, -1, f) + +} + +func Test_Mock_findExpectedCall_Respects_Repeatability(t *testing.T) { + + m := new(Mock) + m.On("One", 1).Return("one") + m.On("Two", 2).Return("two").Once() + m.On("Two", 3).Return("three").Twice() + m.On("Two", 3).Return("three").Times(8) + + f, c := m.findExpectedCall("Two", 3) + + if assert.Equal(t, 2, f) { + if assert.NotNil(t, c) { + assert.Equal(t, "Two", c.Method) + assert.Equal(t, 3, c.Arguments[0]) + assert.Equal(t, "three", c.ReturnArguments[0]) + } + } + +} + +func Test_callString(t *testing.T) { + + assert.Equal(t, `Method(int,bool,string)`, callString("Method", []interface{}{1, true, "something"}, false)) + +} + +func Test_Mock_Called(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_Called", 1, 2, 3).Return(5, "6", true) + + returnArguments := mockedService.Called(1, 2, 3) + + if assert.Equal(t, 1, len(mockedService.Calls)) { + assert.Equal(t, "Test_Mock_Called", mockedService.Calls[0].Method) + assert.Equal(t, 1, mockedService.Calls[0].Arguments[0]) + assert.Equal(t, 2, mockedService.Calls[0].Arguments[1]) + assert.Equal(t, 3, mockedService.Calls[0].Arguments[2]) + } + + if assert.Equal(t, 3, len(returnArguments)) { + assert.Equal(t, 5, returnArguments[0]) + assert.Equal(t, "6", returnArguments[1]) + assert.Equal(t, true, returnArguments[2]) + } + +} + +func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).Return(5, "6", true).Once() + mockedService.On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).Return(-1, "hi", false) + + returnArguments1 := mockedService.Called(1, 2, 3) + returnArguments2 := mockedService.Called(1, 2, 3) + + if assert.Equal(t, 2, len(mockedService.Calls)) { + assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Calls[0].Method) + assert.Equal(t, 1, mockedService.Calls[0].Arguments[0]) + assert.Equal(t, 2, mockedService.Calls[0].Arguments[1]) + assert.Equal(t, 3, mockedService.Calls[0].Arguments[2]) + + assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Calls[1].Method) + assert.Equal(t, 1, mockedService.Calls[1].Arguments[0]) + assert.Equal(t, 2, mockedService.Calls[1].Arguments[1]) + assert.Equal(t, 3, mockedService.Calls[1].Arguments[2]) + } + + if assert.Equal(t, 3, len(returnArguments1)) { + assert.Equal(t, 5, returnArguments1[0]) + assert.Equal(t, "6", returnArguments1[1]) + assert.Equal(t, true, returnArguments1[2]) + } + + if assert.Equal(t, 3, len(returnArguments2)) { + assert.Equal(t, -1, returnArguments2[0]) + assert.Equal(t, "hi", returnArguments2[1]) + assert.Equal(t, false, returnArguments2[2]) + } + +} + +func Test_Mock_Called_For_SetTime_Expectation(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("TheExampleMethod", 1, 2, 3).Return(5, "6", true).Times(4) + + mockedService.TheExampleMethod(1, 2, 3) + mockedService.TheExampleMethod(1, 2, 3) + mockedService.TheExampleMethod(1, 2, 3) + mockedService.TheExampleMethod(1, 2, 3) + assert.Panics(t, func() { + mockedService.TheExampleMethod(1, 2, 3) + }) + +} + +func Test_Mock_Called_Unexpected(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + // make sure it panics if no expectation was made + assert.Panics(t, func() { + mockedService.Called(1, 2, 3) + }, "Calling unexpected method should panic") + +} + +func Test_AssertExpectationsForObjects_Helper(t *testing.T) { + + var mockedService1 *TestExampleImplementation = new(TestExampleImplementation) + var mockedService2 *TestExampleImplementation = new(TestExampleImplementation) + var mockedService3 *TestExampleImplementation = new(TestExampleImplementation) + + mockedService1.On("Test_AssertExpectationsForObjects_Helper", 1).Return() + mockedService2.On("Test_AssertExpectationsForObjects_Helper", 2).Return() + mockedService3.On("Test_AssertExpectationsForObjects_Helper", 3).Return() + + mockedService1.Called(1) + mockedService2.Called(2) + mockedService3.Called(3) + + assert.True(t, AssertExpectationsForObjects(t, mockedService1.Mock, mockedService2.Mock, mockedService3.Mock)) + +} + +func Test_AssertExpectationsForObjects_Helper_Failed(t *testing.T) { + + var mockedService1 *TestExampleImplementation = new(TestExampleImplementation) + var mockedService2 *TestExampleImplementation = new(TestExampleImplementation) + var mockedService3 *TestExampleImplementation = new(TestExampleImplementation) + + mockedService1.On("Test_AssertExpectationsForObjects_Helper_Failed", 1).Return() + mockedService2.On("Test_AssertExpectationsForObjects_Helper_Failed", 2).Return() + mockedService3.On("Test_AssertExpectationsForObjects_Helper_Failed", 3).Return() + + mockedService1.Called(1) + mockedService3.Called(3) + + tt := new(testing.T) + assert.False(t, AssertExpectationsForObjects(tt, mockedService1.Mock, mockedService2.Mock, mockedService3.Mock)) + +} + +func Test_Mock_AssertExpectations(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_AssertExpectations", 1, 2, 3).Return(5, 6, 7) + + tt := new(testing.T) + assert.False(t, mockedService.AssertExpectations(tt)) + + // make the call now + mockedService.Called(1, 2, 3) + + // now assert expectations + assert.True(t, mockedService.AssertExpectations(tt)) + +} + +func Test_Mock_AssertExpectationsCustomType(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).Return(nil).Once() + + tt := new(testing.T) + assert.False(t, mockedService.AssertExpectations(tt)) + + // make the call now + mockedService.TheExampleMethod3(&ExampleType{}) + + // now assert expectations + assert.True(t, mockedService.AssertExpectations(tt)) + +} + +func Test_Mock_AssertExpectations_With_Repeatability(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_AssertExpectations_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Twice() + + tt := new(testing.T) + assert.False(t, mockedService.AssertExpectations(tt)) + + // make the call now + mockedService.Called(1, 2, 3) + + assert.False(t, mockedService.AssertExpectations(tt)) + + mockedService.Called(1, 2, 3) + + // now assert expectations + assert.True(t, mockedService.AssertExpectations(tt)) + +} + +func Test_Mock_TwoCallsWithDifferentArguments(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_TwoCallsWithDifferentArguments", 1, 2, 3).Return(5, 6, 7) + mockedService.On("Test_Mock_TwoCallsWithDifferentArguments", 4, 5, 6).Return(5, 6, 7) + + args1 := mockedService.Called(1, 2, 3) + assert.Equal(t, 5, args1.Int(0)) + assert.Equal(t, 6, args1.Int(1)) + assert.Equal(t, 7, args1.Int(2)) + + args2 := mockedService.Called(4, 5, 6) + assert.Equal(t, 5, args2.Int(0)) + assert.Equal(t, 6, args2.Int(1)) + assert.Equal(t, 7, args2.Int(2)) + +} + +func Test_Mock_AssertNumberOfCalls(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_AssertNumberOfCalls", 1, 2, 3).Return(5, 6, 7) + + mockedService.Called(1, 2, 3) + assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 1)) + + mockedService.Called(1, 2, 3) + assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 2)) + +} + +func Test_Mock_AssertCalled(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_AssertCalled", 1, 2, 3).Return(5, 6, 7) + + mockedService.Called(1, 2, 3) + + assert.True(t, mockedService.AssertCalled(t, "Test_Mock_AssertCalled", 1, 2, 3)) + +} + +func Test_Mock_AssertCalled_WithAnythingOfTypeArgument(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_AssertCalled_WithAnythingOfTypeArgument", Anything, Anything, Anything).Return() + + mockedService.Called(1, "two", []uint8("three")) + + assert.True(t, mockedService.AssertCalled(t, "Test_Mock_AssertCalled_WithAnythingOfTypeArgument", AnythingOfType("int"), AnythingOfType("string"), AnythingOfType("[]uint8"))) + +} + +func Test_Mock_AssertCalled_WithArguments(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_AssertCalled_WithArguments", 1, 2, 3).Return(5, 6, 7) + + mockedService.Called(1, 2, 3) + + tt := new(testing.T) + assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments", 1, 2, 3)) + assert.False(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments", 2, 3, 4)) + +} + +func Test_Mock_AssertCalled_WithArguments_With_Repeatability(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Once() + mockedService.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 2, 3, 4).Return(5, 6, 7).Once() + + mockedService.Called(1, 2, 3) + mockedService.Called(2, 3, 4) + + tt := new(testing.T) + assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3)) + assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 2, 3, 4)) + assert.False(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 3, 4, 5)) + +} + +func Test_Mock_AssertNotCalled(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.On("Test_Mock_AssertNotCalled", 1, 2, 3).Return(5, 6, 7) + + mockedService.Called(1, 2, 3) + + assert.True(t, mockedService.AssertNotCalled(t, "Test_Mock_NotCalled")) + +} + +/* + Arguments helper methods +*/ +func Test_Arguments_Get(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + + assert.Equal(t, "string", args.Get(0).(string)) + assert.Equal(t, 123, args.Get(1).(int)) + assert.Equal(t, true, args.Get(2).(bool)) + +} + +func Test_Arguments_Is(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + + assert.True(t, args.Is("string", 123, true)) + assert.False(t, args.Is("wrong", 456, false)) + +} + +func Test_Arguments_Diff(t *testing.T) { + + var args Arguments = []interface{}{"Hello World", 123, true} + var diff string + var count int + diff, count = args.Diff([]interface{}{"Hello World", 456, "false"}) + + assert.Equal(t, 2, count) + assert.Contains(t, diff, `%!s(int=456) != %!s(int=123)`) + assert.Contains(t, diff, `false != %!s(bool=true)`) + +} + +func Test_Arguments_Diff_DifferentNumberOfArgs(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + var diff string + var count int + diff, count = args.Diff([]interface{}{"string", 456, "false", "extra"}) + + assert.Equal(t, 3, count) + assert.Contains(t, diff, `extra != (Missing)`) + +} + +func Test_Arguments_Diff_WithAnythingArgument(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + var count int + _, count = args.Diff([]interface{}{"string", Anything, true}) + + assert.Equal(t, 0, count) + +} + +func Test_Arguments_Diff_WithAnythingArgument_InActualToo(t *testing.T) { + + var args Arguments = []interface{}{"string", Anything, true} + var count int + _, count = args.Diff([]interface{}{"string", 123, true}) + + assert.Equal(t, 0, count) + +} + +func Test_Arguments_Diff_WithAnythingOfTypeArgument(t *testing.T) { + + var args Arguments = []interface{}{"string", AnythingOfType("int"), true} + var count int + _, count = args.Diff([]interface{}{"string", 123, true}) + + assert.Equal(t, 0, count) + +} + +func Test_Arguments_Diff_WithAnythingOfTypeArgument_Failing(t *testing.T) { + + var args Arguments = []interface{}{"string", AnythingOfType("string"), true} + var count int + var diff string + diff, count = args.Diff([]interface{}{"string", 123, true}) + + assert.Equal(t, 1, count) + assert.Contains(t, diff, `string != type int - %!s(int=123)`) + +} + +func Test_Arguments_Assert(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + + assert.True(t, args.Assert(t, "string", 123, true)) + +} + +func Test_Arguments_String_Representation(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + assert.Equal(t, `string,int,bool`, args.String()) + +} + +func Test_Arguments_String(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + assert.Equal(t, "string", args.String(0)) + +} + +func Test_Arguments_Error(t *testing.T) { + + var err error = errors.New("An Error") + var args Arguments = []interface{}{"string", 123, true, err} + assert.Equal(t, err, args.Error(3)) + +} + +func Test_Arguments_Error_Nil(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true, nil} + assert.Equal(t, nil, args.Error(3)) + +} + +func Test_Arguments_Int(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + assert.Equal(t, 123, args.Int(1)) + +} + +func Test_Arguments_Bool(t *testing.T) { + + var args Arguments = []interface{}{"string", 123, true} + assert.Equal(t, true, args.Bool(2)) + +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/.gitignore b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/.gitignore new file mode 100644 index 000000000..191a5360b --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/.gitignore @@ -0,0 +1,4 @@ +_* +*.swp +*.[568] +[568].out diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/LICENSE b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/LICENSE new file mode 100644 index 000000000..545cf2d33 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/LICENSE @@ -0,0 +1,25 @@ +Gocheck - A rich testing framework for Go + +Copyright (c) 2010-2013 Gustavo Niemeyer + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/README.md b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/README.md new file mode 100644 index 000000000..0ca9e5726 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/README.md @@ -0,0 +1,20 @@ +Instructions +============ + +Install the package with: + + go get gopkg.in/check.v1 + +Import it with: + + import "gopkg.in/check.v1" + +and use _check_ as the package name inside the code. + +For more details, visit the project page: + +* http://labix.org/gocheck + +and the API documentation: + +* https://gopkg.in/check.v1 diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/TODO b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/TODO new file mode 100644 index 000000000..33498270e --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/TODO @@ -0,0 +1,2 @@ +- Assert(slice, Contains, item) +- Parallel test support diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go new file mode 100644 index 000000000..48cb8c811 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go @@ -0,0 +1,163 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package check + +import ( + "fmt" + "runtime" + "time" +) + +var memStats runtime.MemStats + +// testingB is a type passed to Benchmark functions to manage benchmark +// timing and to specify the number of iterations to run. +type timer struct { + start time.Time // Time test or benchmark started + duration time.Duration + N int + bytes int64 + timerOn bool + benchTime time.Duration + // The initial states of memStats.Mallocs and memStats.TotalAlloc. + startAllocs uint64 + startBytes uint64 + // The net total of this test after being run. + netAllocs uint64 + netBytes uint64 +} + +// StartTimer starts timing a test. This function is called automatically +// before a benchmark starts, but it can also used to resume timing after +// a call to StopTimer. +func (c *C) StartTimer() { + if !c.timerOn { + c.start = time.Now() + c.timerOn = true + + runtime.ReadMemStats(&memStats) + c.startAllocs = memStats.Mallocs + c.startBytes = memStats.TotalAlloc + } +} + +// StopTimer stops timing a test. This can be used to pause the timer +// while performing complex initialization that you don't +// want to measure. +func (c *C) StopTimer() { + if c.timerOn { + c.duration += time.Now().Sub(c.start) + c.timerOn = false + runtime.ReadMemStats(&memStats) + c.netAllocs += memStats.Mallocs - c.startAllocs + c.netBytes += memStats.TotalAlloc - c.startBytes + } +} + +// ResetTimer sets the elapsed benchmark time to zero. +// It does not affect whether the timer is running. +func (c *C) ResetTimer() { + if c.timerOn { + c.start = time.Now() + runtime.ReadMemStats(&memStats) + c.startAllocs = memStats.Mallocs + c.startBytes = memStats.TotalAlloc + } + c.duration = 0 + c.netAllocs = 0 + c.netBytes = 0 +} + +// SetBytes informs the number of bytes that the benchmark processes +// on each iteration. If this is called in a benchmark it will also +// report MB/s. +func (c *C) SetBytes(n int64) { + c.bytes = n +} + +func (c *C) nsPerOp() int64 { + if c.N <= 0 { + return 0 + } + return c.duration.Nanoseconds() / int64(c.N) +} + +func (c *C) mbPerSec() float64 { + if c.bytes <= 0 || c.duration <= 0 || c.N <= 0 { + return 0 + } + return (float64(c.bytes) * float64(c.N) / 1e6) / c.duration.Seconds() +} + +func (c *C) timerString() string { + if c.N <= 0 { + return fmt.Sprintf("%3.3fs", float64(c.duration.Nanoseconds())/1e9) + } + mbs := c.mbPerSec() + mb := "" + if mbs != 0 { + mb = fmt.Sprintf("\t%7.2f MB/s", mbs) + } + nsop := c.nsPerOp() + ns := fmt.Sprintf("%10d ns/op", nsop) + if c.N > 0 && nsop < 100 { + // The format specifiers here make sure that + // the ones digits line up for all three possible formats. + if nsop < 10 { + ns = fmt.Sprintf("%13.2f ns/op", float64(c.duration.Nanoseconds())/float64(c.N)) + } else { + ns = fmt.Sprintf("%12.1f ns/op", float64(c.duration.Nanoseconds())/float64(c.N)) + } + } + memStats := "" + if c.benchMem { + allocedBytes := fmt.Sprintf("%8d B/op", int64(c.netBytes)/int64(c.N)) + allocs := fmt.Sprintf("%8d allocs/op", int64(c.netAllocs)/int64(c.N)) + memStats = fmt.Sprintf("\t%s\t%s", allocedBytes, allocs) + } + return fmt.Sprintf("%8d\t%s%s%s", c.N, ns, mb, memStats) +} + +func min(x, y int) int { + if x > y { + return y + } + return x +} + +func max(x, y int) int { + if x < y { + return y + } + return x +} + +// roundDown10 rounds a number down to the nearest power of 10. +func roundDown10(n int) int { + var tens = 0 + // tens = floor(log_10(n)) + for n > 10 { + n = n / 10 + tens++ + } + // result = 10^tens + result := 1 + for i := 0; i < tens; i++ { + result *= 10 + } + return result +} + +// roundUp rounds x up to a number of the form [1eX, 2eX, 5eX]. +func roundUp(n int) int { + base := roundDown10(n) + if n < (2 * base) { + return 2 * base + } + if n < (5 * base) { + return 5 * base + } + return 10 * base +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go new file mode 100644 index 000000000..4dd827c16 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go @@ -0,0 +1,91 @@ +// These tests verify the test running logic. + +package check_test + +import ( + "time" + . "gopkg.in/check.v1" +) + +var benchmarkS = Suite(&BenchmarkS{}) + +type BenchmarkS struct{} + +func (s *BenchmarkS) TestCountSuite(c *C) { + suitesRun += 1 +} + +func (s *BenchmarkS) TestBasicTestTiming(c *C) { + helper := FixtureHelper{sleepOn: "Test1", sleep: 1000000 * time.Nanosecond} + output := String{} + runConf := RunConf{Output: &output, Verbose: true} + Run(&helper, &runConf) + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t0\\.001s\n" + + "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t0\\.000s\n" + c.Assert(output.value, Matches, expected) +} + +func (s *BenchmarkS) TestStreamTestTiming(c *C) { + helper := FixtureHelper{sleepOn: "SetUpSuite", sleep: 1000000 * time.Nanosecond} + output := String{} + runConf := RunConf{Output: &output, Stream: true} + Run(&helper, &runConf) + + expected := "(?s).*\nPASS: check_test\\.go:[0-9]+: FixtureHelper\\.SetUpSuite\t *0\\.001s\n.*" + c.Assert(output.value, Matches, expected) +} + +func (s *BenchmarkS) TestBenchmark(c *C) { + helper := FixtureHelper{sleep: 100000} + output := String{} + runConf := RunConf{ + Output: &output, + Benchmark: true, + BenchmarkTime: 10000000, + Filter: "Benchmark1", + } + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Benchmark1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Benchmark1") + c.Check(helper.calls[6], Equals, "TearDownTest") + // ... and more. + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark1\t *100\t *[12][0-9]{5} ns/op\n" + c.Assert(output.value, Matches, expected) +} + +func (s *BenchmarkS) TestBenchmarkBytes(c *C) { + helper := FixtureHelper{sleep: 100000} + output := String{} + runConf := RunConf{ + Output: &output, + Benchmark: true, + BenchmarkTime: 10000000, + Filter: "Benchmark2", + } + Run(&helper, &runConf) + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark2\t *100\t *[12][0-9]{5} ns/op\t *[4-9]\\.[0-9]{2} MB/s\n" + c.Assert(output.value, Matches, expected) +} + +func (s *BenchmarkS) TestBenchmarkMem(c *C) { + helper := FixtureHelper{sleep: 100000} + output := String{} + runConf := RunConf{ + Output: &output, + Benchmark: true, + BenchmarkMem: true, + BenchmarkTime: 10000000, + Filter: "Benchmark3", + } + Run(&helper, &runConf) + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark3\t *100\t *[12][0-9]{5} ns/op\t *[0-9]+ B/op\t *[1-9] allocs/op\n" + c.Assert(output.value, Matches, expected) +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go new file mode 100644 index 000000000..e55f327c7 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go @@ -0,0 +1,82 @@ +// These initial tests are for bootstrapping. They verify that we can +// basically use the testing infrastructure itself to check if the test +// system is working. +// +// These tests use will break down the test runner badly in case of +// errors because if they simply fail, we can't be sure the developer +// will ever see anything (because failing means the failing system +// somehow isn't working! :-) +// +// Do not assume *any* internal functionality works as expected besides +// what's actually tested here. + +package check_test + +import ( + "fmt" + "gopkg.in/check.v1" + "strings" +) + +type BootstrapS struct{} + +var boostrapS = check.Suite(&BootstrapS{}) + +func (s *BootstrapS) TestCountSuite(c *check.C) { + suitesRun += 1 +} + +func (s *BootstrapS) TestFailedAndFail(c *check.C) { + if c.Failed() { + critical("c.Failed() must be false first!") + } + c.Fail() + if !c.Failed() { + critical("c.Fail() didn't put the test in a failed state!") + } + c.Succeed() +} + +func (s *BootstrapS) TestFailedAndSucceed(c *check.C) { + c.Fail() + c.Succeed() + if c.Failed() { + critical("c.Succeed() didn't put the test back in a non-failed state") + } +} + +func (s *BootstrapS) TestLogAndGetTestLog(c *check.C) { + c.Log("Hello there!") + log := c.GetTestLog() + if log != "Hello there!\n" { + critical(fmt.Sprintf("Log() or GetTestLog() is not working! Got: %#v", log)) + } +} + +func (s *BootstrapS) TestLogfAndGetTestLog(c *check.C) { + c.Logf("Hello %v", "there!") + log := c.GetTestLog() + if log != "Hello there!\n" { + critical(fmt.Sprintf("Logf() or GetTestLog() is not working! Got: %#v", log)) + } +} + +func (s *BootstrapS) TestRunShowsErrors(c *check.C) { + output := String{} + check.Run(&FailHelper{}, &check.RunConf{Output: &output}) + if strings.Index(output.value, "Expected failure!") == -1 { + critical(fmt.Sprintf("RunWithWriter() output did not contain the "+ + "expected failure! Got: %#v", + output.value)) + } +} + +func (s *BootstrapS) TestRunDoesntShowSuccesses(c *check.C) { + output := String{} + check.Run(&SuccessHelper{}, &check.RunConf{Output: &output}) + if strings.Index(output.value, "Expected success!") != -1 { + critical(fmt.Sprintf("RunWithWriter() output contained a successful "+ + "test! Got: %#v", + output.value)) + } +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/check.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/check.go new file mode 100644 index 000000000..ca8c0f92d --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/check.go @@ -0,0 +1,945 @@ +// Package check is a rich testing extension for Go's testing package. +// +// For details about the project, see: +// +// http://labix.org/gocheck +// +package check + +import ( + "bytes" + "errors" + "fmt" + "io" + "math/rand" + "os" + "path" + "path/filepath" + "reflect" + "regexp" + "runtime" + "strconv" + "strings" + "sync" + "time" +) + +// ----------------------------------------------------------------------- +// Internal type which deals with suite method calling. + +const ( + fixtureKd = iota + testKd +) + +type funcKind int + +const ( + succeededSt = iota + failedSt + skippedSt + panickedSt + fixturePanickedSt + missedSt +) + +type funcStatus int + +// A method value can't reach its own Method structure. +type methodType struct { + reflect.Value + Info reflect.Method +} + +func newMethod(receiver reflect.Value, i int) *methodType { + return &methodType{receiver.Method(i), receiver.Type().Method(i)} +} + +func (method *methodType) PC() uintptr { + return method.Info.Func.Pointer() +} + +func (method *methodType) suiteName() string { + t := method.Info.Type.In(0) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t.Name() +} + +func (method *methodType) String() string { + return method.suiteName() + "." + method.Info.Name +} + +func (method *methodType) matches(re *regexp.Regexp) bool { + return (re.MatchString(method.Info.Name) || + re.MatchString(method.suiteName()) || + re.MatchString(method.String())) +} + +type C struct { + method *methodType + kind funcKind + testName string + status funcStatus + logb *logger + logw io.Writer + done chan *C + reason string + mustFail bool + tempDir *tempDir + benchMem bool + startTime time.Time + timer +} + +func (c *C) stopNow() { + runtime.Goexit() +} + +// logger is a concurrency safe byte.Buffer +type logger struct { + sync.Mutex + writer bytes.Buffer +} + +func (l *logger) Write(buf []byte) (int, error) { + l.Lock() + defer l.Unlock() + return l.writer.Write(buf) +} + +func (l *logger) WriteTo(w io.Writer) (int64, error) { + l.Lock() + defer l.Unlock() + return l.writer.WriteTo(w) +} + +func (l *logger) String() string { + l.Lock() + defer l.Unlock() + return l.writer.String() +} + +// ----------------------------------------------------------------------- +// Handling of temporary files and directories. + +type tempDir struct { + sync.Mutex + path string + counter int +} + +func (td *tempDir) newPath() string { + td.Lock() + defer td.Unlock() + if td.path == "" { + var err error + for i := 0; i != 100; i++ { + path := fmt.Sprintf("%s%ccheck-%d", os.TempDir(), os.PathSeparator, rand.Int()) + if err = os.Mkdir(path, 0700); err == nil { + td.path = path + break + } + } + if td.path == "" { + panic("Couldn't create temporary directory: " + err.Error()) + } + } + result := filepath.Join(td.path, strconv.Itoa(td.counter)) + td.counter += 1 + return result +} + +func (td *tempDir) removeAll() { + td.Lock() + defer td.Unlock() + if td.path != "" { + err := os.RemoveAll(td.path) + if err != nil { + fmt.Fprintf(os.Stderr, "WARNING: Error cleaning up temporaries: "+err.Error()) + } + } +} + +// Create a new temporary directory which is automatically removed after +// the suite finishes running. +func (c *C) MkDir() string { + path := c.tempDir.newPath() + if err := os.Mkdir(path, 0700); err != nil { + panic(fmt.Sprintf("Couldn't create temporary directory %s: %s", path, err.Error())) + } + return path +} + +// ----------------------------------------------------------------------- +// Low-level logging functions. + +func (c *C) log(args ...interface{}) { + c.writeLog([]byte(fmt.Sprint(args...) + "\n")) +} + +func (c *C) logf(format string, args ...interface{}) { + c.writeLog([]byte(fmt.Sprintf(format+"\n", args...))) +} + +func (c *C) logNewLine() { + c.writeLog([]byte{'\n'}) +} + +func (c *C) writeLog(buf []byte) { + c.logb.Write(buf) + if c.logw != nil { + c.logw.Write(buf) + } +} + +func hasStringOrError(x interface{}) (ok bool) { + _, ok = x.(fmt.Stringer) + if ok { + return + } + _, ok = x.(error) + return +} + +func (c *C) logValue(label string, value interface{}) { + if label == "" { + if hasStringOrError(value) { + c.logf("... %#v (%q)", value, value) + } else { + c.logf("... %#v", value) + } + } else if value == nil { + c.logf("... %s = nil", label) + } else { + if hasStringOrError(value) { + fv := fmt.Sprintf("%#v", value) + qv := fmt.Sprintf("%q", value) + if fv != qv { + c.logf("... %s %s = %s (%s)", label, reflect.TypeOf(value), fv, qv) + return + } + } + if s, ok := value.(string); ok && isMultiLine(s) { + c.logf(`... %s %s = "" +`, label, reflect.TypeOf(value)) + c.logMultiLine(s) + } else { + c.logf("... %s %s = %#v", label, reflect.TypeOf(value), value) + } + } +} + +func (c *C) logMultiLine(s string) { + b := make([]byte, 0, len(s)*2) + i := 0 + n := len(s) + for i < n { + j := i + 1 + for j < n && s[j-1] != '\n' { + j++ + } + b = append(b, "... "...) + b = strconv.AppendQuote(b, s[i:j]) + if j < n { + b = append(b, " +"...) + } + b = append(b, '\n') + i = j + } + c.writeLog(b) +} + +func isMultiLine(s string) bool { + for i := 0; i+1 < len(s); i++ { + if s[i] == '\n' { + return true + } + } + return false +} + +func (c *C) logString(issue string) { + c.log("... ", issue) +} + +func (c *C) logCaller(skip int) { + // This is a bit heavier than it ought to be. + skip += 1 // Our own frame. + pc, callerFile, callerLine, ok := runtime.Caller(skip) + if !ok { + return + } + var testFile string + var testLine int + testFunc := runtime.FuncForPC(c.method.PC()) + if runtime.FuncForPC(pc) != testFunc { + for { + skip += 1 + if pc, file, line, ok := runtime.Caller(skip); ok { + // Note that the test line may be different on + // distinct calls for the same test. Showing + // the "internal" line is helpful when debugging. + if runtime.FuncForPC(pc) == testFunc { + testFile, testLine = file, line + break + } + } else { + break + } + } + } + if testFile != "" && (testFile != callerFile || testLine != callerLine) { + c.logCode(testFile, testLine) + } + c.logCode(callerFile, callerLine) +} + +func (c *C) logCode(path string, line int) { + c.logf("%s:%d:", nicePath(path), line) + code, err := printLine(path, line) + if code == "" { + code = "..." // XXX Open the file and take the raw line. + if err != nil { + code += err.Error() + } + } + c.log(indent(code, " ")) +} + +var valueGo = filepath.Join("reflect", "value.go") +var asmGo = filepath.Join("runtime", "asm_") + +func (c *C) logPanic(skip int, value interface{}) { + skip++ // Our own frame. + initialSkip := skip + for ; ; skip++ { + if pc, file, line, ok := runtime.Caller(skip); ok { + if skip == initialSkip { + c.logf("... Panic: %s (PC=0x%X)\n", value, pc) + } + name := niceFuncName(pc) + path := nicePath(file) + if strings.Contains(path, "/gopkg.in/check.v") { + continue + } + if name == "Value.call" && strings.HasSuffix(path, valueGo) { + continue + } + if name == "call16" && strings.Contains(path, asmGo) { + continue + } + c.logf("%s:%d\n in %s", nicePath(file), line, name) + } else { + break + } + } +} + +func (c *C) logSoftPanic(issue string) { + c.log("... Panic: ", issue) +} + +func (c *C) logArgPanic(method *methodType, expectedType string) { + c.logf("... Panic: %s argument should be %s", + niceFuncName(method.PC()), expectedType) +} + +// ----------------------------------------------------------------------- +// Some simple formatting helpers. + +var initWD, initWDErr = os.Getwd() + +func init() { + if initWDErr == nil { + initWD = strings.Replace(initWD, "\\", "/", -1) + "/" + } +} + +func nicePath(path string) string { + if initWDErr == nil { + if strings.HasPrefix(path, initWD) { + return path[len(initWD):] + } + } + return path +} + +func niceFuncPath(pc uintptr) string { + function := runtime.FuncForPC(pc) + if function != nil { + filename, line := function.FileLine(pc) + return fmt.Sprintf("%s:%d", nicePath(filename), line) + } + return "" +} + +func niceFuncName(pc uintptr) string { + function := runtime.FuncForPC(pc) + if function != nil { + name := path.Base(function.Name()) + if i := strings.Index(name, "."); i > 0 { + name = name[i+1:] + } + if strings.HasPrefix(name, "(*") { + if i := strings.Index(name, ")"); i > 0 { + name = name[2:i] + name[i+1:] + } + } + if i := strings.LastIndex(name, ".*"); i != -1 { + name = name[:i] + "." + name[i+2:] + } + if i := strings.LastIndex(name, "·"); i != -1 { + name = name[:i] + "." + name[i+2:] + } + return name + } + return "" +} + +// ----------------------------------------------------------------------- +// Result tracker to aggregate call results. + +type Result struct { + Succeeded int + Failed int + Skipped int + Panicked int + FixturePanicked int + ExpectedFailures int + Missed int // Not even tried to run, related to a panic in the fixture. + RunError error // Houston, we've got a problem. + WorkDir string // If KeepWorkDir is true +} + +type resultTracker struct { + result Result + _lastWasProblem bool + _waiting int + _missed int + _expectChan chan *C + _doneChan chan *C + _stopChan chan bool +} + +func newResultTracker() *resultTracker { + return &resultTracker{_expectChan: make(chan *C), // Synchronous + _doneChan: make(chan *C, 32), // Asynchronous + _stopChan: make(chan bool)} // Synchronous +} + +func (tracker *resultTracker) start() { + go tracker._loopRoutine() +} + +func (tracker *resultTracker) waitAndStop() { + <-tracker._stopChan +} + +func (tracker *resultTracker) expectCall(c *C) { + tracker._expectChan <- c +} + +func (tracker *resultTracker) callDone(c *C) { + tracker._doneChan <- c +} + +func (tracker *resultTracker) _loopRoutine() { + for { + var c *C + if tracker._waiting > 0 { + // Calls still running. Can't stop. + select { + // XXX Reindent this (not now to make diff clear) + case c = <-tracker._expectChan: + tracker._waiting += 1 + case c = <-tracker._doneChan: + tracker._waiting -= 1 + switch c.status { + case succeededSt: + if c.kind == testKd { + if c.mustFail { + tracker.result.ExpectedFailures++ + } else { + tracker.result.Succeeded++ + } + } + case failedSt: + tracker.result.Failed++ + case panickedSt: + if c.kind == fixtureKd { + tracker.result.FixturePanicked++ + } else { + tracker.result.Panicked++ + } + case fixturePanickedSt: + // Track it as missed, since the panic + // was on the fixture, not on the test. + tracker.result.Missed++ + case missedSt: + tracker.result.Missed++ + case skippedSt: + if c.kind == testKd { + tracker.result.Skipped++ + } + } + } + } else { + // No calls. Can stop, but no done calls here. + select { + case tracker._stopChan <- true: + return + case c = <-tracker._expectChan: + tracker._waiting += 1 + case c = <-tracker._doneChan: + panic("Tracker got an unexpected done call.") + } + } + } +} + +// ----------------------------------------------------------------------- +// The underlying suite runner. + +type suiteRunner struct { + suite interface{} + setUpSuite, tearDownSuite *methodType + setUpTest, tearDownTest *methodType + tests []*methodType + tracker *resultTracker + tempDir *tempDir + keepDir bool + output *outputWriter + reportedProblemLast bool + benchTime time.Duration + benchMem bool +} + +type RunConf struct { + Output io.Writer + Stream bool + Verbose bool + Filter string + Benchmark bool + BenchmarkTime time.Duration // Defaults to 1 second + BenchmarkMem bool + KeepWorkDir bool +} + +// Create a new suiteRunner able to run all methods in the given suite. +func newSuiteRunner(suite interface{}, runConf *RunConf) *suiteRunner { + var conf RunConf + if runConf != nil { + conf = *runConf + } + if conf.Output == nil { + conf.Output = os.Stdout + } + if conf.Benchmark { + conf.Verbose = true + } + + suiteType := reflect.TypeOf(suite) + suiteNumMethods := suiteType.NumMethod() + suiteValue := reflect.ValueOf(suite) + + runner := &suiteRunner{ + suite: suite, + output: newOutputWriter(conf.Output, conf.Stream, conf.Verbose), + tracker: newResultTracker(), + benchTime: conf.BenchmarkTime, + benchMem: conf.BenchmarkMem, + tempDir: &tempDir{}, + keepDir: conf.KeepWorkDir, + tests: make([]*methodType, 0, suiteNumMethods), + } + if runner.benchTime == 0 { + runner.benchTime = 1 * time.Second + } + + var filterRegexp *regexp.Regexp + if conf.Filter != "" { + if regexp, err := regexp.Compile(conf.Filter); err != nil { + msg := "Bad filter expression: " + err.Error() + runner.tracker.result.RunError = errors.New(msg) + return runner + } else { + filterRegexp = regexp + } + } + + for i := 0; i != suiteNumMethods; i++ { + method := newMethod(suiteValue, i) + switch method.Info.Name { + case "SetUpSuite": + runner.setUpSuite = method + case "TearDownSuite": + runner.tearDownSuite = method + case "SetUpTest": + runner.setUpTest = method + case "TearDownTest": + runner.tearDownTest = method + default: + prefix := "Test" + if conf.Benchmark { + prefix = "Benchmark" + } + if !strings.HasPrefix(method.Info.Name, prefix) { + continue + } + if filterRegexp == nil || method.matches(filterRegexp) { + runner.tests = append(runner.tests, method) + } + } + } + return runner +} + +// Run all methods in the given suite. +func (runner *suiteRunner) run() *Result { + if runner.tracker.result.RunError == nil && len(runner.tests) > 0 { + runner.tracker.start() + if runner.checkFixtureArgs() { + c := runner.runFixture(runner.setUpSuite, "", nil) + if c == nil || c.status == succeededSt { + for i := 0; i != len(runner.tests); i++ { + c := runner.runTest(runner.tests[i]) + if c.status == fixturePanickedSt { + runner.skipTests(missedSt, runner.tests[i+1:]) + break + } + } + } else if c != nil && c.status == skippedSt { + runner.skipTests(skippedSt, runner.tests) + } else { + runner.skipTests(missedSt, runner.tests) + } + runner.runFixture(runner.tearDownSuite, "", nil) + } else { + runner.skipTests(missedSt, runner.tests) + } + runner.tracker.waitAndStop() + if runner.keepDir { + runner.tracker.result.WorkDir = runner.tempDir.path + } else { + runner.tempDir.removeAll() + } + } + return &runner.tracker.result +} + +// Create a call object with the given suite method, and fork a +// goroutine with the provided dispatcher for running it. +func (runner *suiteRunner) forkCall(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C { + var logw io.Writer + if runner.output.Stream { + logw = runner.output + } + if logb == nil { + logb = new(logger) + } + c := &C{ + method: method, + kind: kind, + testName: testName, + logb: logb, + logw: logw, + tempDir: runner.tempDir, + done: make(chan *C, 1), + timer: timer{benchTime: runner.benchTime}, + startTime: time.Now(), + benchMem: runner.benchMem, + } + runner.tracker.expectCall(c) + go (func() { + runner.reportCallStarted(c) + defer runner.callDone(c) + dispatcher(c) + })() + return c +} + +// Same as forkCall(), but wait for call to finish before returning. +func (runner *suiteRunner) runFunc(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C { + c := runner.forkCall(method, kind, testName, logb, dispatcher) + <-c.done + return c +} + +// Handle a finished call. If there were any panics, update the call status +// accordingly. Then, mark the call as done and report to the tracker. +func (runner *suiteRunner) callDone(c *C) { + value := recover() + if value != nil { + switch v := value.(type) { + case *fixturePanic: + if v.status == skippedSt { + c.status = skippedSt + } else { + c.logSoftPanic("Fixture has panicked (see related PANIC)") + c.status = fixturePanickedSt + } + default: + c.logPanic(1, value) + c.status = panickedSt + } + } + if c.mustFail { + switch c.status { + case failedSt: + c.status = succeededSt + case succeededSt: + c.status = failedSt + c.logString("Error: Test succeeded, but was expected to fail") + c.logString("Reason: " + c.reason) + } + } + + runner.reportCallDone(c) + c.done <- c +} + +// Runs a fixture call synchronously. The fixture will still be run in a +// goroutine like all suite methods, but this method will not return +// while the fixture goroutine is not done, because the fixture must be +// run in a desired order. +func (runner *suiteRunner) runFixture(method *methodType, testName string, logb *logger) *C { + if method != nil { + c := runner.runFunc(method, fixtureKd, testName, logb, func(c *C) { + c.ResetTimer() + c.StartTimer() + defer c.StopTimer() + c.method.Call([]reflect.Value{reflect.ValueOf(c)}) + }) + return c + } + return nil +} + +// Run the fixture method with runFixture(), but panic with a fixturePanic{} +// in case the fixture method panics. This makes it easier to track the +// fixture panic together with other call panics within forkTest(). +func (runner *suiteRunner) runFixtureWithPanic(method *methodType, testName string, logb *logger, skipped *bool) *C { + if skipped != nil && *skipped { + return nil + } + c := runner.runFixture(method, testName, logb) + if c != nil && c.status != succeededSt { + if skipped != nil { + *skipped = c.status == skippedSt + } + panic(&fixturePanic{c.status, method}) + } + return c +} + +type fixturePanic struct { + status funcStatus + method *methodType +} + +// Run the suite test method, together with the test-specific fixture, +// asynchronously. +func (runner *suiteRunner) forkTest(method *methodType) *C { + testName := method.String() + return runner.forkCall(method, testKd, testName, nil, func(c *C) { + var skipped bool + defer runner.runFixtureWithPanic(runner.tearDownTest, testName, nil, &skipped) + defer c.StopTimer() + benchN := 1 + for { + runner.runFixtureWithPanic(runner.setUpTest, testName, c.logb, &skipped) + mt := c.method.Type() + if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) { + // Rather than a plain panic, provide a more helpful message when + // the argument type is incorrect. + c.status = panickedSt + c.logArgPanic(c.method, "*check.C") + return + } + if strings.HasPrefix(c.method.Info.Name, "Test") { + c.ResetTimer() + c.StartTimer() + c.method.Call([]reflect.Value{reflect.ValueOf(c)}) + return + } + if !strings.HasPrefix(c.method.Info.Name, "Benchmark") { + panic("unexpected method prefix: " + c.method.Info.Name) + } + + runtime.GC() + c.N = benchN + c.ResetTimer() + c.StartTimer() + c.method.Call([]reflect.Value{reflect.ValueOf(c)}) + c.StopTimer() + if c.status != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 { + return + } + perOpN := int(1e9) + if c.nsPerOp() != 0 { + perOpN = int(c.benchTime.Nanoseconds() / c.nsPerOp()) + } + + // Logic taken from the stock testing package: + // - Run more iterations than we think we'll need for a second (1.5x). + // - Don't grow too fast in case we had timing errors previously. + // - Be sure to run at least one more than last time. + benchN = max(min(perOpN+perOpN/2, 100*benchN), benchN+1) + benchN = roundUp(benchN) + + skipped = true // Don't run the deferred one if this panics. + runner.runFixtureWithPanic(runner.tearDownTest, testName, nil, nil) + skipped = false + } + }) +} + +// Same as forkTest(), but wait for the test to finish before returning. +func (runner *suiteRunner) runTest(method *methodType) *C { + c := runner.forkTest(method) + <-c.done + return c +} + +// Helper to mark tests as skipped or missed. A bit heavy for what +// it does, but it enables homogeneous handling of tracking, including +// nice verbose output. +func (runner *suiteRunner) skipTests(status funcStatus, methods []*methodType) { + for _, method := range methods { + runner.runFunc(method, testKd, "", nil, func(c *C) { + c.status = status + }) + } +} + +// Verify if the fixture arguments are *check.C. In case of errors, +// log the error as a panic in the fixture method call, and return false. +func (runner *suiteRunner) checkFixtureArgs() bool { + succeeded := true + argType := reflect.TypeOf(&C{}) + for _, method := range []*methodType{runner.setUpSuite, runner.tearDownSuite, runner.setUpTest, runner.tearDownTest} { + if method != nil { + mt := method.Type() + if mt.NumIn() != 1 || mt.In(0) != argType { + succeeded = false + runner.runFunc(method, fixtureKd, "", nil, func(c *C) { + c.logArgPanic(method, "*check.C") + c.status = panickedSt + }) + } + } + } + return succeeded +} + +func (runner *suiteRunner) reportCallStarted(c *C) { + runner.output.WriteCallStarted("START", c) +} + +func (runner *suiteRunner) reportCallDone(c *C) { + runner.tracker.callDone(c) + switch c.status { + case succeededSt: + if c.mustFail { + runner.output.WriteCallSuccess("FAIL EXPECTED", c) + } else { + runner.output.WriteCallSuccess("PASS", c) + } + case skippedSt: + runner.output.WriteCallSuccess("SKIP", c) + case failedSt: + runner.output.WriteCallProblem("FAIL", c) + case panickedSt: + runner.output.WriteCallProblem("PANIC", c) + case fixturePanickedSt: + // That's a testKd call reporting that its fixture + // has panicked. The fixture call which caused the + // panic itself was tracked above. We'll report to + // aid debugging. + runner.output.WriteCallProblem("PANIC", c) + case missedSt: + runner.output.WriteCallSuccess("MISS", c) + } +} + +// ----------------------------------------------------------------------- +// Output writer manages atomic output writing according to settings. + +type outputWriter struct { + m sync.Mutex + writer io.Writer + wroteCallProblemLast bool + Stream bool + Verbose bool +} + +func newOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter { + return &outputWriter{writer: writer, Stream: stream, Verbose: verbose} +} + +func (ow *outputWriter) Write(content []byte) (n int, err error) { + ow.m.Lock() + n, err = ow.writer.Write(content) + ow.m.Unlock() + return +} + +func (ow *outputWriter) WriteCallStarted(label string, c *C) { + if ow.Stream { + header := renderCallHeader(label, c, "", "\n") + ow.m.Lock() + ow.writer.Write([]byte(header)) + ow.m.Unlock() + } +} + +func (ow *outputWriter) WriteCallProblem(label string, c *C) { + var prefix string + if !ow.Stream { + prefix = "\n-----------------------------------" + + "-----------------------------------\n" + } + header := renderCallHeader(label, c, prefix, "\n\n") + ow.m.Lock() + ow.wroteCallProblemLast = true + ow.writer.Write([]byte(header)) + if !ow.Stream { + c.logb.WriteTo(ow.writer) + } + ow.m.Unlock() +} + +func (ow *outputWriter) WriteCallSuccess(label string, c *C) { + if ow.Stream || (ow.Verbose && c.kind == testKd) { + // TODO Use a buffer here. + var suffix string + if c.reason != "" { + suffix = " (" + c.reason + ")" + } + if c.status == succeededSt { + suffix += "\t" + c.timerString() + } + suffix += "\n" + if ow.Stream { + suffix += "\n" + } + header := renderCallHeader(label, c, "", suffix) + ow.m.Lock() + // Resist temptation of using line as prefix above due to race. + if !ow.Stream && ow.wroteCallProblemLast { + header = "\n-----------------------------------" + + "-----------------------------------\n" + + header + } + ow.wroteCallProblemLast = false + ow.writer.Write([]byte(header)) + ow.m.Unlock() + } +} + +func renderCallHeader(label string, c *C, prefix, suffix string) string { + pc := c.method.PC() + return fmt.Sprintf("%s%s: %s: %s%s", prefix, label, niceFuncPath(pc), + niceFuncName(pc), suffix) +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/check_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/check_test.go new file mode 100644 index 000000000..871b32527 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/check_test.go @@ -0,0 +1,207 @@ +// This file contains just a few generic helpers which are used by the +// other test files. + +package check_test + +import ( + "flag" + "fmt" + "os" + "regexp" + "runtime" + "testing" + "time" + + "gopkg.in/check.v1" +) + +// We count the number of suites run at least to get a vague hint that the +// test suite is behaving as it should. Otherwise a bug introduced at the +// very core of the system could go unperceived. +const suitesRunExpected = 8 + +var suitesRun int = 0 + +func Test(t *testing.T) { + check.TestingT(t) + if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" { + critical(fmt.Sprintf("Expected %d suites to run rather than %d", + suitesRunExpected, suitesRun)) + } +} + +// ----------------------------------------------------------------------- +// Helper functions. + +// Break down badly. This is used in test cases which can't yet assume +// that the fundamental bits are working. +func critical(error string) { + fmt.Fprintln(os.Stderr, "CRITICAL: "+error) + os.Exit(1) +} + +// Return the file line where it's called. +func getMyLine() int { + if _, _, line, ok := runtime.Caller(1); ok { + return line + } + return -1 +} + +// ----------------------------------------------------------------------- +// Helper type implementing a basic io.Writer for testing output. + +// Type implementing the io.Writer interface for analyzing output. +type String struct { + value string +} + +// The only function required by the io.Writer interface. Will append +// written data to the String.value string. +func (s *String) Write(p []byte) (n int, err error) { + s.value += string(p) + return len(p), nil +} + +// Trivial wrapper to test errors happening on a different file +// than the test itself. +func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) { + return c.Check(obtained, check.Equals, expected), getMyLine() +} + +// ----------------------------------------------------------------------- +// Helper suite for testing basic fail behavior. + +type FailHelper struct { + testLine int +} + +func (s *FailHelper) TestLogAndFail(c *check.C) { + s.testLine = getMyLine() - 1 + c.Log("Expected failure!") + c.Fail() +} + +// ----------------------------------------------------------------------- +// Helper suite for testing basic success behavior. + +type SuccessHelper struct{} + +func (s *SuccessHelper) TestLogAndSucceed(c *check.C) { + c.Log("Expected success!") +} + +// ----------------------------------------------------------------------- +// Helper suite for testing ordering and behavior of fixture. + +type FixtureHelper struct { + calls []string + panicOn string + skip bool + skipOnN int + sleepOn string + sleep time.Duration + bytes int64 +} + +func (s *FixtureHelper) trace(name string, c *check.C) { + s.calls = append(s.calls, name) + if name == s.panicOn { + panic(name) + } + if s.sleep > 0 && s.sleepOn == name { + time.Sleep(s.sleep) + } + if s.skip && s.skipOnN == len(s.calls)-1 { + c.Skip("skipOnN == n") + } +} + +func (s *FixtureHelper) SetUpSuite(c *check.C) { + s.trace("SetUpSuite", c) +} + +func (s *FixtureHelper) TearDownSuite(c *check.C) { + s.trace("TearDownSuite", c) +} + +func (s *FixtureHelper) SetUpTest(c *check.C) { + s.trace("SetUpTest", c) +} + +func (s *FixtureHelper) TearDownTest(c *check.C) { + s.trace("TearDownTest", c) +} + +func (s *FixtureHelper) Test1(c *check.C) { + s.trace("Test1", c) +} + +func (s *FixtureHelper) Test2(c *check.C) { + s.trace("Test2", c) +} + +func (s *FixtureHelper) Benchmark1(c *check.C) { + s.trace("Benchmark1", c) + for i := 0; i < c.N; i++ { + time.Sleep(s.sleep) + } +} + +func (s *FixtureHelper) Benchmark2(c *check.C) { + s.trace("Benchmark2", c) + c.SetBytes(1024) + for i := 0; i < c.N; i++ { + time.Sleep(s.sleep) + } +} + +func (s *FixtureHelper) Benchmark3(c *check.C) { + var x []int64 + s.trace("Benchmark3", c) + for i := 0; i < c.N; i++ { + time.Sleep(s.sleep) + x = make([]int64, 5) + _ = x + } +} + +// ----------------------------------------------------------------------- +// Helper which checks the state of the test and ensures that it matches +// the given expectations. Depends on c.Errorf() working, so shouldn't +// be used to test this one function. + +type expectedState struct { + name string + result interface{} + failed bool + log string +} + +// Verify the state of the test. Note that since this also verifies if +// the test is supposed to be in a failed state, no other checks should +// be done in addition to what is being tested. +func checkState(c *check.C, result interface{}, expected *expectedState) { + failed := c.Failed() + c.Succeed() + log := c.GetTestLog() + matched, matchError := regexp.MatchString("^"+expected.log+"$", log) + if matchError != nil { + c.Errorf("Error in matching expression used in testing %s", + expected.name) + } else if !matched { + c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------", + expected.name, log, expected.log) + } + if result != expected.result { + c.Errorf("%s returned %#v rather than %#v", + expected.name, result, expected.result) + } + if failed != expected.failed { + if failed { + c.Errorf("%s has failed when it shouldn't", expected.name) + } else { + c.Errorf("%s has not failed when it should", expected.name) + } + } +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/checkers.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/checkers.go new file mode 100644 index 000000000..bac338729 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/checkers.go @@ -0,0 +1,458 @@ +package check + +import ( + "fmt" + "reflect" + "regexp" +) + +// ----------------------------------------------------------------------- +// CommentInterface and Commentf helper, to attach extra information to checks. + +type comment struct { + format string + args []interface{} +} + +// Commentf returns an infomational value to use with Assert or Check calls. +// If the checker test fails, the provided arguments will be passed to +// fmt.Sprintf, and will be presented next to the logged failure. +// +// For example: +// +// c.Assert(v, Equals, 42, Commentf("Iteration #%d failed.", i)) +// +// Note that if the comment is constant, a better option is to +// simply use a normal comment right above or next to the line, as +// it will also get printed with any errors: +// +// c.Assert(l, Equals, 8192) // Ensure buffer size is correct (bug #123) +// +func Commentf(format string, args ...interface{}) CommentInterface { + return &comment{format, args} +} + +// CommentInterface must be implemented by types that attach extra +// information to failed checks. See the Commentf function for details. +type CommentInterface interface { + CheckCommentString() string +} + +func (c *comment) CheckCommentString() string { + return fmt.Sprintf(c.format, c.args...) +} + +// ----------------------------------------------------------------------- +// The Checker interface. + +// The Checker interface must be provided by checkers used with +// the Assert and Check verification methods. +type Checker interface { + Info() *CheckerInfo + Check(params []interface{}, names []string) (result bool, error string) +} + +// See the Checker interface. +type CheckerInfo struct { + Name string + Params []string +} + +func (info *CheckerInfo) Info() *CheckerInfo { + return info +} + +// ----------------------------------------------------------------------- +// Not checker logic inverter. + +// The Not checker inverts the logic of the provided checker. The +// resulting checker will succeed where the original one failed, and +// vice-versa. +// +// For example: +// +// c.Assert(a, Not(Equals), b) +// +func Not(checker Checker) Checker { + return ¬Checker{checker} +} + +type notChecker struct { + sub Checker +} + +func (checker *notChecker) Info() *CheckerInfo { + info := *checker.sub.Info() + info.Name = "Not(" + info.Name + ")" + return &info +} + +func (checker *notChecker) Check(params []interface{}, names []string) (result bool, error string) { + result, error = checker.sub.Check(params, names) + result = !result + return +} + +// ----------------------------------------------------------------------- +// IsNil checker. + +type isNilChecker struct { + *CheckerInfo +} + +// The IsNil checker tests whether the obtained value is nil. +// +// For example: +// +// c.Assert(err, IsNil) +// +var IsNil Checker = &isNilChecker{ + &CheckerInfo{Name: "IsNil", Params: []string{"value"}}, +} + +func (checker *isNilChecker) Check(params []interface{}, names []string) (result bool, error string) { + return isNil(params[0]), "" +} + +func isNil(obtained interface{}) (result bool) { + if obtained == nil { + result = true + } else { + switch v := reflect.ValueOf(obtained); v.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return v.IsNil() + } + } + return +} + +// ----------------------------------------------------------------------- +// NotNil checker. Alias for Not(IsNil), since it's so common. + +type notNilChecker struct { + *CheckerInfo +} + +// The NotNil checker verifies that the obtained value is not nil. +// +// For example: +// +// c.Assert(iface, NotNil) +// +// This is an alias for Not(IsNil), made available since it's a +// fairly common check. +// +var NotNil Checker = ¬NilChecker{ + &CheckerInfo{Name: "NotNil", Params: []string{"value"}}, +} + +func (checker *notNilChecker) Check(params []interface{}, names []string) (result bool, error string) { + return !isNil(params[0]), "" +} + +// ----------------------------------------------------------------------- +// Equals checker. + +type equalsChecker struct { + *CheckerInfo +} + +// The Equals checker verifies that the obtained value is equal to +// the expected value, according to usual Go semantics for ==. +// +// For example: +// +// c.Assert(value, Equals, 42) +// +var Equals Checker = &equalsChecker{ + &CheckerInfo{Name: "Equals", Params: []string{"obtained", "expected"}}, +} + +func (checker *equalsChecker) Check(params []interface{}, names []string) (result bool, error string) { + defer func() { + if v := recover(); v != nil { + result = false + error = fmt.Sprint(v) + } + }() + return params[0] == params[1], "" +} + +// ----------------------------------------------------------------------- +// DeepEquals checker. + +type deepEqualsChecker struct { + *CheckerInfo +} + +// The DeepEquals checker verifies that the obtained value is deep-equal to +// the expected value. The check will work correctly even when facing +// slices, interfaces, and values of different types (which always fail +// the test). +// +// For example: +// +// c.Assert(value, DeepEquals, 42) +// c.Assert(array, DeepEquals, []string{"hi", "there"}) +// +var DeepEquals Checker = &deepEqualsChecker{ + &CheckerInfo{Name: "DeepEquals", Params: []string{"obtained", "expected"}}, +} + +func (checker *deepEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) { + return reflect.DeepEqual(params[0], params[1]), "" +} + +// ----------------------------------------------------------------------- +// HasLen checker. + +type hasLenChecker struct { + *CheckerInfo +} + +// The HasLen checker verifies that the obtained value has the +// provided length. In many cases this is superior to using Equals +// in conjuction with the len function because in case the check +// fails the value itself will be printed, instead of its length, +// providing more details for figuring the problem. +// +// For example: +// +// c.Assert(list, HasLen, 5) +// +var HasLen Checker = &hasLenChecker{ + &CheckerInfo{Name: "HasLen", Params: []string{"obtained", "n"}}, +} + +func (checker *hasLenChecker) Check(params []interface{}, names []string) (result bool, error string) { + n, ok := params[1].(int) + if !ok { + return false, "n must be an int" + } + value := reflect.ValueOf(params[0]) + switch value.Kind() { + case reflect.Map, reflect.Array, reflect.Slice, reflect.Chan, reflect.String: + default: + return false, "obtained value type has no length" + } + return value.Len() == n, "" +} + +// ----------------------------------------------------------------------- +// ErrorMatches checker. + +type errorMatchesChecker struct { + *CheckerInfo +} + +// The ErrorMatches checker verifies that the error value +// is non nil and matches the regular expression provided. +// +// For example: +// +// c.Assert(err, ErrorMatches, "perm.*denied") +// +var ErrorMatches Checker = errorMatchesChecker{ + &CheckerInfo{Name: "ErrorMatches", Params: []string{"value", "regex"}}, +} + +func (checker errorMatchesChecker) Check(params []interface{}, names []string) (result bool, errStr string) { + if params[0] == nil { + return false, "Error value is nil" + } + err, ok := params[0].(error) + if !ok { + return false, "Value is not an error" + } + params[0] = err.Error() + names[0] = "error" + return matches(params[0], params[1]) +} + +// ----------------------------------------------------------------------- +// Matches checker. + +type matchesChecker struct { + *CheckerInfo +} + +// The Matches checker verifies that the string provided as the obtained +// value (or the string resulting from obtained.String()) matches the +// regular expression provided. +// +// For example: +// +// c.Assert(err, Matches, "perm.*denied") +// +var Matches Checker = &matchesChecker{ + &CheckerInfo{Name: "Matches", Params: []string{"value", "regex"}}, +} + +func (checker *matchesChecker) Check(params []interface{}, names []string) (result bool, error string) { + return matches(params[0], params[1]) +} + +func matches(value, regex interface{}) (result bool, error string) { + reStr, ok := regex.(string) + if !ok { + return false, "Regex must be a string" + } + valueStr, valueIsStr := value.(string) + if !valueIsStr { + if valueWithStr, valueHasStr := value.(fmt.Stringer); valueHasStr { + valueStr, valueIsStr = valueWithStr.String(), true + } + } + if valueIsStr { + matches, err := regexp.MatchString("^"+reStr+"$", valueStr) + if err != nil { + return false, "Can't compile regex: " + err.Error() + } + return matches, "" + } + return false, "Obtained value is not a string and has no .String()" +} + +// ----------------------------------------------------------------------- +// Panics checker. + +type panicsChecker struct { + *CheckerInfo +} + +// The Panics checker verifies that calling the provided zero-argument +// function will cause a panic which is deep-equal to the provided value. +// +// For example: +// +// c.Assert(func() { f(1, 2) }, Panics, &SomeErrorType{"BOOM"}). +// +// +var Panics Checker = &panicsChecker{ + &CheckerInfo{Name: "Panics", Params: []string{"function", "expected"}}, +} + +func (checker *panicsChecker) Check(params []interface{}, names []string) (result bool, error string) { + f := reflect.ValueOf(params[0]) + if f.Kind() != reflect.Func || f.Type().NumIn() != 0 { + return false, "Function must take zero arguments" + } + defer func() { + // If the function has not panicked, then don't do the check. + if error != "" { + return + } + params[0] = recover() + names[0] = "panic" + result = reflect.DeepEqual(params[0], params[1]) + }() + f.Call(nil) + return false, "Function has not panicked" +} + +type panicMatchesChecker struct { + *CheckerInfo +} + +// The PanicMatches checker verifies that calling the provided zero-argument +// function will cause a panic with an error value matching +// the regular expression provided. +// +// For example: +// +// c.Assert(func() { f(1, 2) }, PanicMatches, `open.*: no such file or directory`). +// +// +var PanicMatches Checker = &panicMatchesChecker{ + &CheckerInfo{Name: "PanicMatches", Params: []string{"function", "expected"}}, +} + +func (checker *panicMatchesChecker) Check(params []interface{}, names []string) (result bool, errmsg string) { + f := reflect.ValueOf(params[0]) + if f.Kind() != reflect.Func || f.Type().NumIn() != 0 { + return false, "Function must take zero arguments" + } + defer func() { + // If the function has not panicked, then don't do the check. + if errmsg != "" { + return + } + obtained := recover() + names[0] = "panic" + if e, ok := obtained.(error); ok { + params[0] = e.Error() + } else if _, ok := obtained.(string); ok { + params[0] = obtained + } else { + errmsg = "Panic value is not a string or an error" + return + } + result, errmsg = matches(params[0], params[1]) + }() + f.Call(nil) + return false, "Function has not panicked" +} + +// ----------------------------------------------------------------------- +// FitsTypeOf checker. + +type fitsTypeChecker struct { + *CheckerInfo +} + +// The FitsTypeOf checker verifies that the obtained value is +// assignable to a variable with the same type as the provided +// sample value. +// +// For example: +// +// c.Assert(value, FitsTypeOf, int64(0)) +// c.Assert(value, FitsTypeOf, os.Error(nil)) +// +var FitsTypeOf Checker = &fitsTypeChecker{ + &CheckerInfo{Name: "FitsTypeOf", Params: []string{"obtained", "sample"}}, +} + +func (checker *fitsTypeChecker) Check(params []interface{}, names []string) (result bool, error string) { + obtained := reflect.ValueOf(params[0]) + sample := reflect.ValueOf(params[1]) + if !obtained.IsValid() { + return false, "" + } + if !sample.IsValid() { + return false, "Invalid sample value" + } + return obtained.Type().AssignableTo(sample.Type()), "" +} + +// ----------------------------------------------------------------------- +// Implements checker. + +type implementsChecker struct { + *CheckerInfo +} + +// The Implements checker verifies that the obtained value +// implements the interface specified via a pointer to an interface +// variable. +// +// For example: +// +// var e os.Error +// c.Assert(err, Implements, &e) +// +var Implements Checker = &implementsChecker{ + &CheckerInfo{Name: "Implements", Params: []string{"obtained", "ifaceptr"}}, +} + +func (checker *implementsChecker) Check(params []interface{}, names []string) (result bool, error string) { + obtained := reflect.ValueOf(params[0]) + ifaceptr := reflect.ValueOf(params[1]) + if !obtained.IsValid() { + return false, "" + } + if !ifaceptr.IsValid() || ifaceptr.Kind() != reflect.Ptr || ifaceptr.Elem().Kind() != reflect.Interface { + return false, "ifaceptr should be a pointer to an interface variable" + } + return obtained.Type().Implements(ifaceptr.Elem().Type()), "" +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go new file mode 100644 index 000000000..5c6974746 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go @@ -0,0 +1,272 @@ +package check_test + +import ( + "errors" + "gopkg.in/check.v1" + "reflect" + "runtime" +) + +type CheckersS struct{} + +var _ = check.Suite(&CheckersS{}) + +func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) { + info := checker.Info() + if info.Name != name { + c.Fatalf("Got name %s, expected %s", info.Name, name) + } + if !reflect.DeepEqual(info.Params, paramNames) { + c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames) + } +} + +func testCheck(c *check.C, checker check.Checker, result bool, error string, params ...interface{}) ([]interface{}, []string) { + info := checker.Info() + if len(params) != len(info.Params) { + c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params)) + } + names := append([]string{}, info.Params...) + result_, error_ := checker.Check(params, names) + if result_ != result || error_ != error { + c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)", + info.Name, params, result_, error_, result, error) + } + return params, names +} + +func (s *CheckersS) TestComment(c *check.C) { + bug := check.Commentf("a %d bc", 42) + comment := bug.CheckCommentString() + if comment != "a 42 bc" { + c.Fatalf("Commentf returned %#v", comment) + } +} + +func (s *CheckersS) TestIsNil(c *check.C) { + testInfo(c, check.IsNil, "IsNil", []string{"value"}) + + testCheck(c, check.IsNil, true, "", nil) + testCheck(c, check.IsNil, false, "", "a") + + testCheck(c, check.IsNil, true, "", (chan int)(nil)) + testCheck(c, check.IsNil, false, "", make(chan int)) + testCheck(c, check.IsNil, true, "", (error)(nil)) + testCheck(c, check.IsNil, false, "", errors.New("")) + testCheck(c, check.IsNil, true, "", ([]int)(nil)) + testCheck(c, check.IsNil, false, "", make([]int, 1)) + testCheck(c, check.IsNil, false, "", int(0)) +} + +func (s *CheckersS) TestNotNil(c *check.C) { + testInfo(c, check.NotNil, "NotNil", []string{"value"}) + + testCheck(c, check.NotNil, false, "", nil) + testCheck(c, check.NotNil, true, "", "a") + + testCheck(c, check.NotNil, false, "", (chan int)(nil)) + testCheck(c, check.NotNil, true, "", make(chan int)) + testCheck(c, check.NotNil, false, "", (error)(nil)) + testCheck(c, check.NotNil, true, "", errors.New("")) + testCheck(c, check.NotNil, false, "", ([]int)(nil)) + testCheck(c, check.NotNil, true, "", make([]int, 1)) +} + +func (s *CheckersS) TestNot(c *check.C) { + testInfo(c, check.Not(check.IsNil), "Not(IsNil)", []string{"value"}) + + testCheck(c, check.Not(check.IsNil), false, "", nil) + testCheck(c, check.Not(check.IsNil), true, "", "a") +} + +type simpleStruct struct { + i int +} + +func (s *CheckersS) TestEquals(c *check.C) { + testInfo(c, check.Equals, "Equals", []string{"obtained", "expected"}) + + // The simplest. + testCheck(c, check.Equals, true, "", 42, 42) + testCheck(c, check.Equals, false, "", 42, 43) + + // Different native types. + testCheck(c, check.Equals, false, "", int32(42), int64(42)) + + // With nil. + testCheck(c, check.Equals, false, "", 42, nil) + + // Slices + testCheck(c, check.Equals, false, "runtime error: comparing uncomparable type []uint8", []byte{1, 2}, []byte{1, 2}) + + // Struct values + testCheck(c, check.Equals, true, "", simpleStruct{1}, simpleStruct{1}) + testCheck(c, check.Equals, false, "", simpleStruct{1}, simpleStruct{2}) + + // Struct pointers + testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{1}) + testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{2}) +} + +func (s *CheckersS) TestDeepEquals(c *check.C) { + testInfo(c, check.DeepEquals, "DeepEquals", []string{"obtained", "expected"}) + + // The simplest. + testCheck(c, check.DeepEquals, true, "", 42, 42) + testCheck(c, check.DeepEquals, false, "", 42, 43) + + // Different native types. + testCheck(c, check.DeepEquals, false, "", int32(42), int64(42)) + + // With nil. + testCheck(c, check.DeepEquals, false, "", 42, nil) + + // Slices + testCheck(c, check.DeepEquals, true, "", []byte{1, 2}, []byte{1, 2}) + testCheck(c, check.DeepEquals, false, "", []byte{1, 2}, []byte{1, 3}) + + // Struct values + testCheck(c, check.DeepEquals, true, "", simpleStruct{1}, simpleStruct{1}) + testCheck(c, check.DeepEquals, false, "", simpleStruct{1}, simpleStruct{2}) + + // Struct pointers + testCheck(c, check.DeepEquals, true, "", &simpleStruct{1}, &simpleStruct{1}) + testCheck(c, check.DeepEquals, false, "", &simpleStruct{1}, &simpleStruct{2}) +} + +func (s *CheckersS) TestHasLen(c *check.C) { + testInfo(c, check.HasLen, "HasLen", []string{"obtained", "n"}) + + testCheck(c, check.HasLen, true, "", "abcd", 4) + testCheck(c, check.HasLen, true, "", []int{1, 2}, 2) + testCheck(c, check.HasLen, false, "", []int{1, 2}, 3) + + testCheck(c, check.HasLen, false, "n must be an int", []int{1, 2}, "2") + testCheck(c, check.HasLen, false, "obtained value type has no length", nil, 2) +} + +func (s *CheckersS) TestErrorMatches(c *check.C) { + testInfo(c, check.ErrorMatches, "ErrorMatches", []string{"value", "regex"}) + + testCheck(c, check.ErrorMatches, false, "Error value is nil", nil, "some error") + testCheck(c, check.ErrorMatches, false, "Value is not an error", 1, "some error") + testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "some error") + testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "so.*or") + + // Verify params mutation + params, names := testCheck(c, check.ErrorMatches, false, "", errors.New("some error"), "other error") + c.Assert(params[0], check.Equals, "some error") + c.Assert(names[0], check.Equals, "error") +} + +func (s *CheckersS) TestMatches(c *check.C) { + testInfo(c, check.Matches, "Matches", []string{"value", "regex"}) + + // Simple matching + testCheck(c, check.Matches, true, "", "abc", "abc") + testCheck(c, check.Matches, true, "", "abc", "a.c") + + // Must match fully + testCheck(c, check.Matches, false, "", "abc", "ab") + testCheck(c, check.Matches, false, "", "abc", "bc") + + // String()-enabled values accepted + testCheck(c, check.Matches, true, "", reflect.ValueOf("abc"), "a.c") + testCheck(c, check.Matches, false, "", reflect.ValueOf("abc"), "a.d") + + // Some error conditions. + testCheck(c, check.Matches, false, "Obtained value is not a string and has no .String()", 1, "a.c") + testCheck(c, check.Matches, false, "Can't compile regex: error parsing regexp: missing closing ]: `[c$`", "abc", "a[c") +} + +func (s *CheckersS) TestPanics(c *check.C) { + testInfo(c, check.Panics, "Panics", []string{"function", "expected"}) + + // Some errors. + testCheck(c, check.Panics, false, "Function has not panicked", func() bool { return false }, "BOOM") + testCheck(c, check.Panics, false, "Function must take zero arguments", 1, "BOOM") + + // Plain strings. + testCheck(c, check.Panics, true, "", func() { panic("BOOM") }, "BOOM") + testCheck(c, check.Panics, false, "", func() { panic("KABOOM") }, "BOOM") + testCheck(c, check.Panics, true, "", func() bool { panic("BOOM") }, "BOOM") + + // Error values. + testCheck(c, check.Panics, true, "", func() { panic(errors.New("BOOM")) }, errors.New("BOOM")) + testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM")) + + type deep struct{ i int } + // Deep value + testCheck(c, check.Panics, true, "", func() { panic(&deep{99}) }, &deep{99}) + + // Verify params/names mutation + params, names := testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM")) + c.Assert(params[0], check.ErrorMatches, "KABOOM") + c.Assert(names[0], check.Equals, "panic") + + // Verify a nil panic + testCheck(c, check.Panics, true, "", func() { panic(nil) }, nil) + testCheck(c, check.Panics, false, "", func() { panic(nil) }, "NOPE") +} + +func (s *CheckersS) TestPanicMatches(c *check.C) { + testInfo(c, check.PanicMatches, "PanicMatches", []string{"function", "expected"}) + + // Error matching. + testCheck(c, check.PanicMatches, true, "", func() { panic(errors.New("BOOM")) }, "BO.M") + testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BO.M") + + // Some errors. + testCheck(c, check.PanicMatches, false, "Function has not panicked", func() bool { return false }, "BOOM") + testCheck(c, check.PanicMatches, false, "Function must take zero arguments", 1, "BOOM") + + // Plain strings. + testCheck(c, check.PanicMatches, true, "", func() { panic("BOOM") }, "BO.M") + testCheck(c, check.PanicMatches, false, "", func() { panic("KABOOM") }, "BOOM") + testCheck(c, check.PanicMatches, true, "", func() bool { panic("BOOM") }, "BO.M") + + // Verify params/names mutation + params, names := testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BOOM") + c.Assert(params[0], check.Equals, "KABOOM") + c.Assert(names[0], check.Equals, "panic") + + // Verify a nil panic + testCheck(c, check.PanicMatches, false, "Panic value is not a string or an error", func() { panic(nil) }, "") +} + +func (s *CheckersS) TestFitsTypeOf(c *check.C) { + testInfo(c, check.FitsTypeOf, "FitsTypeOf", []string{"obtained", "sample"}) + + // Basic types + testCheck(c, check.FitsTypeOf, true, "", 1, 0) + testCheck(c, check.FitsTypeOf, false, "", 1, int64(0)) + + // Aliases + testCheck(c, check.FitsTypeOf, false, "", 1, errors.New("")) + testCheck(c, check.FitsTypeOf, false, "", "error", errors.New("")) + testCheck(c, check.FitsTypeOf, true, "", errors.New("error"), errors.New("")) + + // Structures + testCheck(c, check.FitsTypeOf, false, "", 1, simpleStruct{}) + testCheck(c, check.FitsTypeOf, false, "", simpleStruct{42}, &simpleStruct{}) + testCheck(c, check.FitsTypeOf, true, "", simpleStruct{42}, simpleStruct{}) + testCheck(c, check.FitsTypeOf, true, "", &simpleStruct{42}, &simpleStruct{}) + + // Some bad values + testCheck(c, check.FitsTypeOf, false, "Invalid sample value", 1, interface{}(nil)) + testCheck(c, check.FitsTypeOf, false, "", interface{}(nil), 0) +} + +func (s *CheckersS) TestImplements(c *check.C) { + testInfo(c, check.Implements, "Implements", []string{"obtained", "ifaceptr"}) + + var e error + var re runtime.Error + testCheck(c, check.Implements, true, "", errors.New(""), &e) + testCheck(c, check.Implements, false, "", errors.New(""), &re) + + // Some bad values + testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, errors.New("")) + testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, interface{}(nil)) + testCheck(c, check.Implements, false, "", interface{}(nil), &e) +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/export_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/export_test.go new file mode 100644 index 000000000..0e6cfe0f2 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/export_test.go @@ -0,0 +1,9 @@ +package check + +func PrintLine(filename string, line int) (string, error) { + return printLine(filename, line) +} + +func Indent(s, with string) string { + return indent(s, with) +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go new file mode 100644 index 000000000..2bff9e163 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go @@ -0,0 +1,484 @@ +// Tests for the behavior of the test fixture system. + +package check_test + +import ( + . "gopkg.in/check.v1" +) + +// ----------------------------------------------------------------------- +// Fixture test suite. + +type FixtureS struct{} + +var fixtureS = Suite(&FixtureS{}) + +func (s *FixtureS) TestCountSuite(c *C) { + suitesRun += 1 +} + +// ----------------------------------------------------------------------- +// Basic fixture ordering verification. + +func (s *FixtureS) TestOrder(c *C) { + helper := FixtureHelper{} + Run(&helper, nil) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) +} + +// ----------------------------------------------------------------------- +// Check the behavior when panics occur within tests and fixtures. + +func (s *FixtureS) TestPanicOnTest(c *C) { + helper := FixtureHelper{panicOn: "Test1"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: FixtureHelper.Test1\n\n" + + "\\.\\.\\. Panic: Test1 \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.Test1\n" + + "(.|\n)*$" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnSetUpTest(c *C) { + helper := FixtureHelper{panicOn: "SetUpTest"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "TearDownTest") + c.Check(helper.calls[3], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 4) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper\\.SetUpTest\n\n" + + "\\.\\.\\. Panic: SetUpTest \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.SetUpTest\n" + + "(.|\n)*" + + "\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper\\.Test1\n\n" + + "\\.\\.\\. Panic: Fixture has panicked " + + "\\(see related PANIC\\)\n$" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnTearDownTest(c *C) { + helper := FixtureHelper{panicOn: "TearDownTest"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 5) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper.TearDownTest\n\n" + + "\\.\\.\\. Panic: TearDownTest \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.TearDownTest\n" + + "(.|\n)*" + + "\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper\\.Test1\n\n" + + "\\.\\.\\. Panic: Fixture has panicked " + + "\\(see related PANIC\\)\n$" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnSetUpSuite(c *C) { + helper := FixtureHelper{panicOn: "SetUpSuite"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 2) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper.SetUpSuite\n\n" + + "\\.\\.\\. Panic: SetUpSuite \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.SetUpSuite\n" + + "(.|\n)*$" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnTearDownSuite(c *C) { + helper := FixtureHelper{panicOn: "TearDownSuite"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper.TearDownSuite\n\n" + + "\\.\\.\\. Panic: TearDownSuite \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.TearDownSuite\n" + + "(.|\n)*$" + + c.Check(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// A wrong argument on a test or fixture will produce a nice error. + +func (s *FixtureS) TestPanicOnWrongTestArg(c *C) { + helper := WrongTestArgHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "TearDownTest") + c.Check(helper.calls[3], Equals, "SetUpTest") + c.Check(helper.calls[4], Equals, "Test2") + c.Check(helper.calls[5], Equals, "TearDownTest") + c.Check(helper.calls[6], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 7) + + expected := "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongTestArgHelper\\.Test1\n\n" + + "\\.\\.\\. Panic: WrongTestArgHelper\\.Test1 argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnWrongSetUpTestArg(c *C) { + helper := WrongSetUpTestArgHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(len(helper.calls), Equals, 0) + + expected := + "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongSetUpTestArgHelper\\.SetUpTest\n\n" + + "\\.\\.\\. Panic: WrongSetUpTestArgHelper\\.SetUpTest argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnWrongSetUpSuiteArg(c *C) { + helper := WrongSetUpSuiteArgHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(len(helper.calls), Equals, 0) + + expected := + "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongSetUpSuiteArgHelper\\.SetUpSuite\n\n" + + "\\.\\.\\. Panic: WrongSetUpSuiteArgHelper\\.SetUpSuite argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// Nice errors also when tests or fixture have wrong arg count. + +func (s *FixtureS) TestPanicOnWrongTestArgCount(c *C) { + helper := WrongTestArgCountHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "TearDownTest") + c.Check(helper.calls[3], Equals, "SetUpTest") + c.Check(helper.calls[4], Equals, "Test2") + c.Check(helper.calls[5], Equals, "TearDownTest") + c.Check(helper.calls[6], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 7) + + expected := "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongTestArgCountHelper\\.Test1\n\n" + + "\\.\\.\\. Panic: WrongTestArgCountHelper\\.Test1 argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnWrongSetUpTestArgCount(c *C) { + helper := WrongSetUpTestArgCountHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(len(helper.calls), Equals, 0) + + expected := + "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongSetUpTestArgCountHelper\\.SetUpTest\n\n" + + "\\.\\.\\. Panic: WrongSetUpTestArgCountHelper\\.SetUpTest argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnWrongSetUpSuiteArgCount(c *C) { + helper := WrongSetUpSuiteArgCountHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(len(helper.calls), Equals, 0) + + expected := + "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongSetUpSuiteArgCountHelper\\.SetUpSuite\n\n" + + "\\.\\.\\. Panic: WrongSetUpSuiteArgCountHelper" + + "\\.SetUpSuite argument should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// Helper test suites with wrong function arguments. + +type WrongTestArgHelper struct { + FixtureHelper +} + +func (s *WrongTestArgHelper) Test1(t int) { +} + +type WrongSetUpTestArgHelper struct { + FixtureHelper +} + +func (s *WrongSetUpTestArgHelper) SetUpTest(t int) { +} + +type WrongSetUpSuiteArgHelper struct { + FixtureHelper +} + +func (s *WrongSetUpSuiteArgHelper) SetUpSuite(t int) { +} + +type WrongTestArgCountHelper struct { + FixtureHelper +} + +func (s *WrongTestArgCountHelper) Test1(c *C, i int) { +} + +type WrongSetUpTestArgCountHelper struct { + FixtureHelper +} + +func (s *WrongSetUpTestArgCountHelper) SetUpTest(c *C, i int) { +} + +type WrongSetUpSuiteArgCountHelper struct { + FixtureHelper +} + +func (s *WrongSetUpSuiteArgCountHelper) SetUpSuite(c *C, i int) { +} + +// ----------------------------------------------------------------------- +// Ensure fixture doesn't run without tests. + +type NoTestsHelper struct { + hasRun bool +} + +func (s *NoTestsHelper) SetUpSuite(c *C) { + s.hasRun = true +} + +func (s *NoTestsHelper) TearDownSuite(c *C) { + s.hasRun = true +} + +func (s *FixtureS) TestFixtureDoesntRunWithoutTests(c *C) { + helper := NoTestsHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.hasRun, Equals, false) +} + +// ----------------------------------------------------------------------- +// Verify that checks and assertions work correctly inside the fixture. + +type FixtureCheckHelper struct { + fail string + completed bool +} + +func (s *FixtureCheckHelper) SetUpSuite(c *C) { + switch s.fail { + case "SetUpSuiteAssert": + c.Assert(false, Equals, true) + case "SetUpSuiteCheck": + c.Check(false, Equals, true) + } + s.completed = true +} + +func (s *FixtureCheckHelper) SetUpTest(c *C) { + switch s.fail { + case "SetUpTestAssert": + c.Assert(false, Equals, true) + case "SetUpTestCheck": + c.Check(false, Equals, true) + } + s.completed = true +} + +func (s *FixtureCheckHelper) Test(c *C) { + // Do nothing. +} + +func (s *FixtureS) TestSetUpSuiteCheck(c *C) { + helper := FixtureCheckHelper{fail: "SetUpSuiteCheck"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Assert(output.value, Matches, + "\n---+\n"+ + "FAIL: fixture_test\\.go:[0-9]+: "+ + "FixtureCheckHelper\\.SetUpSuite\n\n"+ + "fixture_test\\.go:[0-9]+:\n"+ + " c\\.Check\\(false, Equals, true\\)\n"+ + "\\.+ obtained bool = false\n"+ + "\\.+ expected bool = true\n\n") + c.Assert(helper.completed, Equals, true) +} + +func (s *FixtureS) TestSetUpSuiteAssert(c *C) { + helper := FixtureCheckHelper{fail: "SetUpSuiteAssert"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Assert(output.value, Matches, + "\n---+\n"+ + "FAIL: fixture_test\\.go:[0-9]+: "+ + "FixtureCheckHelper\\.SetUpSuite\n\n"+ + "fixture_test\\.go:[0-9]+:\n"+ + " c\\.Assert\\(false, Equals, true\\)\n"+ + "\\.+ obtained bool = false\n"+ + "\\.+ expected bool = true\n\n") + c.Assert(helper.completed, Equals, false) +} + +// ----------------------------------------------------------------------- +// Verify that logging within SetUpTest() persists within the test log itself. + +type FixtureLogHelper struct { + c *C +} + +func (s *FixtureLogHelper) SetUpTest(c *C) { + s.c = c + c.Log("1") +} + +func (s *FixtureLogHelper) Test(c *C) { + c.Log("2") + s.c.Log("3") + c.Log("4") + c.Fail() +} + +func (s *FixtureLogHelper) TearDownTest(c *C) { + s.c.Log("5") +} + +func (s *FixtureS) TestFixtureLogging(c *C) { + helper := FixtureLogHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Assert(output.value, Matches, + "\n---+\n"+ + "FAIL: fixture_test\\.go:[0-9]+: "+ + "FixtureLogHelper\\.Test\n\n"+ + "1\n2\n3\n4\n5\n") +} + +// ----------------------------------------------------------------------- +// Skip() within fixture methods. + +func (s *FixtureS) TestSkipSuite(c *C) { + helper := FixtureHelper{skip: true, skipOnN: 0} + output := String{} + result := Run(&helper, &RunConf{Output: &output}) + c.Assert(output.value, Equals, "") + c.Assert(helper.calls[0], Equals, "SetUpSuite") + c.Assert(helper.calls[1], Equals, "TearDownSuite") + c.Assert(len(helper.calls), Equals, 2) + c.Assert(result.Skipped, Equals, 2) +} + +func (s *FixtureS) TestSkipTest(c *C) { + helper := FixtureHelper{skip: true, skipOnN: 1} + output := String{} + result := Run(&helper, &RunConf{Output: &output}) + c.Assert(helper.calls[0], Equals, "SetUpSuite") + c.Assert(helper.calls[1], Equals, "SetUpTest") + c.Assert(helper.calls[2], Equals, "SetUpTest") + c.Assert(helper.calls[3], Equals, "Test2") + c.Assert(helper.calls[4], Equals, "TearDownTest") + c.Assert(helper.calls[5], Equals, "TearDownSuite") + c.Assert(len(helper.calls), Equals, 6) + c.Assert(result.Skipped, Equals, 1) +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go new file mode 100644 index 000000000..8ecf7915f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go @@ -0,0 +1,335 @@ +// These tests check that the foundations of gocheck are working properly. +// They already assume that fundamental failing is working already, though, +// since this was tested in bootstrap_test.go. Even then, some care may +// still have to be taken when using external functions, since they should +// of course not rely on functionality tested here. + +package check_test + +import ( + "fmt" + "gopkg.in/check.v1" + "log" + "os" + "regexp" + "strings" +) + +// ----------------------------------------------------------------------- +// Foundation test suite. + +type FoundationS struct{} + +var foundationS = check.Suite(&FoundationS{}) + +func (s *FoundationS) TestCountSuite(c *check.C) { + suitesRun += 1 +} + +func (s *FoundationS) TestErrorf(c *check.C) { + // Do not use checkState() here. It depends on Errorf() working. + expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ + " c.Errorf(\"Error %%v!\", \"message\")\n"+ + "... Error: Error message!\n\n", + getMyLine()+1) + c.Errorf("Error %v!", "message") + failed := c.Failed() + c.Succeed() + if log := c.GetTestLog(); log != expectedLog { + c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog) + c.Fail() + } + if !failed { + c.Logf("Errorf() didn't put the test in a failed state") + c.Fail() + } +} + +func (s *FoundationS) TestError(c *check.C) { + expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ + " c\\.Error\\(\"Error \", \"message!\"\\)\n"+ + "\\.\\.\\. Error: Error message!\n\n", + getMyLine()+1) + c.Error("Error ", "message!") + checkState(c, nil, + &expectedState{ + name: "Error(`Error `, `message!`)", + failed: true, + log: expectedLog, + }) +} + +func (s *FoundationS) TestFailNow(c *check.C) { + defer (func() { + if !c.Failed() { + c.Error("FailNow() didn't fail the test") + } else { + c.Succeed() + if c.GetTestLog() != "" { + c.Error("Something got logged:\n" + c.GetTestLog()) + } + } + })() + + c.FailNow() + c.Log("FailNow() didn't stop the test") +} + +func (s *FoundationS) TestSucceedNow(c *check.C) { + defer (func() { + if c.Failed() { + c.Error("SucceedNow() didn't succeed the test") + } + if c.GetTestLog() != "" { + c.Error("Something got logged:\n" + c.GetTestLog()) + } + })() + + c.Fail() + c.SucceedNow() + c.Log("SucceedNow() didn't stop the test") +} + +func (s *FoundationS) TestFailureHeader(c *check.C) { + output := String{} + failHelper := FailHelper{} + check.Run(&failHelper, &check.RunConf{Output: &output}) + header := fmt.Sprintf(""+ + "\n-----------------------------------"+ + "-----------------------------------\n"+ + "FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n", + failHelper.testLine) + if strings.Index(output.value, header) == -1 { + c.Errorf(""+ + "Failure didn't print a proper header.\n"+ + "... Got:\n%s... Expected something with:\n%s", + output.value, header) + } +} + +func (s *FoundationS) TestFatal(c *check.C) { + var line int + defer (func() { + if !c.Failed() { + c.Error("Fatal() didn't fail the test") + } else { + c.Succeed() + expected := fmt.Sprintf("foundation_test.go:%d:\n"+ + " c.Fatal(\"Die \", \"now!\")\n"+ + "... Error: Die now!\n\n", + line) + if c.GetTestLog() != expected { + c.Error("Incorrect log:", c.GetTestLog()) + } + } + })() + + line = getMyLine() + 1 + c.Fatal("Die ", "now!") + c.Log("Fatal() didn't stop the test") +} + +func (s *FoundationS) TestFatalf(c *check.C) { + var line int + defer (func() { + if !c.Failed() { + c.Error("Fatalf() didn't fail the test") + } else { + c.Succeed() + expected := fmt.Sprintf("foundation_test.go:%d:\n"+ + " c.Fatalf(\"Die %%s!\", \"now\")\n"+ + "... Error: Die now!\n\n", + line) + if c.GetTestLog() != expected { + c.Error("Incorrect log:", c.GetTestLog()) + } + } + })() + + line = getMyLine() + 1 + c.Fatalf("Die %s!", "now") + c.Log("Fatalf() didn't stop the test") +} + +func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) { + log := fmt.Sprintf(""+ + "foundation_test.go:%d:\n"+ + " result := c.Check\\(10, check.Equals, 20\\)\n"+ + "\\.\\.\\. obtained int = 10\n"+ + "\\.\\.\\. expected int = 20\n\n", + getMyLine()+1) + result := c.Check(10, check.Equals, 20) + checkState(c, result, + &expectedState{ + name: "Check(10, Equals, 20)", + result: false, + failed: true, + log: log, + }) +} + +func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) { + result, line := checkEqualWrapper(c, 10, 20) + testLine := getMyLine() - 1 + log := fmt.Sprintf(""+ + "foundation_test.go:%d:\n"+ + " result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+ + "check_test.go:%d:\n"+ + " return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+ + "\\.\\.\\. obtained int = 10\n"+ + "\\.\\.\\. expected int = 20\n\n", + testLine, line) + checkState(c, result, + &expectedState{ + name: "Check(10, Equals, 20)", + result: false, + failed: true, + log: log, + }) +} + +// ----------------------------------------------------------------------- +// ExpectFailure() inverts the logic of failure. + +type ExpectFailureSucceedHelper struct{} + +func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) { + c.ExpectFailure("It booms!") + c.Error("Boom!") +} + +type ExpectFailureFailHelper struct{} + +func (s *ExpectFailureFailHelper) TestFail(c *check.C) { + c.ExpectFailure("Bug #XYZ") +} + +func (s *FoundationS) TestExpectFailureFail(c *check.C) { + helper := ExpectFailureFailHelper{} + output := String{} + result := check.Run(&helper, &check.RunConf{Output: &output}) + + expected := "" + + "^\n-+\n" + + "FAIL: foundation_test\\.go:[0-9]+:" + + " ExpectFailureFailHelper\\.TestFail\n\n" + + "\\.\\.\\. Error: Test succeeded, but was expected to fail\n" + + "\\.\\.\\. Reason: Bug #XYZ\n$" + + matched, err := regexp.MatchString(expected, output.value) + if err != nil { + c.Error("Bad expression: ", expected) + } else if !matched { + c.Error("ExpectFailure() didn't log properly:\n", output.value) + } + + c.Assert(result.ExpectedFailures, check.Equals, 0) +} + +func (s *FoundationS) TestExpectFailureSucceed(c *check.C) { + helper := ExpectFailureSucceedHelper{} + output := String{} + result := check.Run(&helper, &check.RunConf{Output: &output}) + + c.Assert(output.value, check.Equals, "") + c.Assert(result.ExpectedFailures, check.Equals, 1) +} + +func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) { + helper := ExpectFailureSucceedHelper{} + output := String{} + result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) + + expected := "" + + "FAIL EXPECTED: foundation_test\\.go:[0-9]+:" + + " ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n" + + matched, err := regexp.MatchString(expected, output.value) + if err != nil { + c.Error("Bad expression: ", expected) + } else if !matched { + c.Error("ExpectFailure() didn't log properly:\n", output.value) + } + + c.Assert(result.ExpectedFailures, check.Equals, 1) +} + +// ----------------------------------------------------------------------- +// Skip() allows stopping a test without positive/negative results. + +type SkipTestHelper struct{} + +func (s *SkipTestHelper) TestFail(c *check.C) { + c.Skip("Wrong platform or whatever") + c.Error("Boom!") +} + +func (s *FoundationS) TestSkip(c *check.C) { + helper := SkipTestHelper{} + output := String{} + check.Run(&helper, &check.RunConf{Output: &output}) + + if output.value != "" { + c.Error("Skip() logged something:\n", output.value) + } +} + +func (s *FoundationS) TestSkipVerbose(c *check.C) { + helper := SkipTestHelper{} + output := String{} + check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) + + expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" + + " \\(Wrong platform or whatever\\)" + matched, err := regexp.MatchString(expected, output.value) + if err != nil { + c.Error("Bad expression: ", expected) + } else if !matched { + c.Error("Skip() didn't log properly:\n", output.value) + } +} + +// ----------------------------------------------------------------------- +// Check minimum *log.Logger interface provided by *check.C. + +type minLogger interface { + Output(calldepth int, s string) error +} + +func (s *BootstrapS) TestMinLogger(c *check.C) { + var logger minLogger + logger = log.New(os.Stderr, "", 0) + logger = c + logger.Output(0, "Hello there") + expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n` + output := c.GetTestLog() + c.Assert(output, check.Matches, expected) +} + +// ----------------------------------------------------------------------- +// Ensure that suites with embedded types are working fine, including the +// the workaround for issue 906. + +type EmbeddedInternalS struct { + called bool +} + +type EmbeddedS struct { + EmbeddedInternalS +} + +var embeddedS = check.Suite(&EmbeddedS{}) + +func (s *EmbeddedS) TestCountSuite(c *check.C) { + suitesRun += 1 +} + +func (s *EmbeddedInternalS) TestMethod(c *check.C) { + c.Error("TestMethod() of the embedded type was called!?") +} + +func (s *EmbeddedS) TestMethod(c *check.C) { + // http://code.google.com/p/go/issues/detail?id=906 + c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner? + s.called = true +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/helpers.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/helpers.go new file mode 100644 index 000000000..4b6c26da4 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/helpers.go @@ -0,0 +1,231 @@ +package check + +import ( + "fmt" + "strings" + "time" +) + +// TestName returns the current test name in the form "SuiteName.TestName" +func (c *C) TestName() string { + return c.testName +} + +// ----------------------------------------------------------------------- +// Basic succeeding/failing logic. + +// Failed returns whether the currently running test has already failed. +func (c *C) Failed() bool { + return c.status == failedSt +} + +// Fail marks the currently running test as failed. +// +// Something ought to have been previously logged so the developer can tell +// what went wrong. The higher level helper functions will fail the test +// and do the logging properly. +func (c *C) Fail() { + c.status = failedSt +} + +// FailNow marks the currently running test as failed and stops running it. +// Something ought to have been previously logged so the developer can tell +// what went wrong. The higher level helper functions will fail the test +// and do the logging properly. +func (c *C) FailNow() { + c.Fail() + c.stopNow() +} + +// Succeed marks the currently running test as succeeded, undoing any +// previous failures. +func (c *C) Succeed() { + c.status = succeededSt +} + +// SucceedNow marks the currently running test as succeeded, undoing any +// previous failures, and stops running the test. +func (c *C) SucceedNow() { + c.Succeed() + c.stopNow() +} + +// ExpectFailure informs that the running test is knowingly broken for +// the provided reason. If the test does not fail, an error will be reported +// to raise attention to this fact. This method is useful to temporarily +// disable tests which cover well known problems until a better time to +// fix the problem is found, without forgetting about the fact that a +// failure still exists. +func (c *C) ExpectFailure(reason string) { + if reason == "" { + panic("Missing reason why the test is expected to fail") + } + c.mustFail = true + c.reason = reason +} + +// Skip skips the running test for the provided reason. If run from within +// SetUpTest, the individual test being set up will be skipped, and if run +// from within SetUpSuite, the whole suite is skipped. +func (c *C) Skip(reason string) { + if reason == "" { + panic("Missing reason why the test is being skipped") + } + c.reason = reason + c.status = skippedSt + c.stopNow() +} + +// ----------------------------------------------------------------------- +// Basic logging. + +// GetTestLog returns the current test error output. +func (c *C) GetTestLog() string { + return c.logb.String() +} + +// Log logs some information into the test error output. +// The provided arguments are assembled together into a string with fmt.Sprint. +func (c *C) Log(args ...interface{}) { + c.log(args...) +} + +// Log logs some information into the test error output. +// The provided arguments are assembled together into a string with fmt.Sprintf. +func (c *C) Logf(format string, args ...interface{}) { + c.logf(format, args...) +} + +// Output enables *C to be used as a logger in functions that require only +// the minimum interface of *log.Logger. +func (c *C) Output(calldepth int, s string) error { + d := time.Now().Sub(c.startTime) + msec := d / time.Millisecond + sec := d / time.Second + min := d / time.Minute + + c.Logf("[LOG] %d:%02d.%03d %s", min, sec%60, msec%1000, s) + return nil +} + +// Error logs an error into the test error output and marks the test as failed. +// The provided arguments are assembled together into a string with fmt.Sprint. +func (c *C) Error(args ...interface{}) { + c.logCaller(1) + c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...))) + c.logNewLine() + c.Fail() +} + +// Errorf logs an error into the test error output and marks the test as failed. +// The provided arguments are assembled together into a string with fmt.Sprintf. +func (c *C) Errorf(format string, args ...interface{}) { + c.logCaller(1) + c.logString(fmt.Sprintf("Error: "+format, args...)) + c.logNewLine() + c.Fail() +} + +// Fatal logs an error into the test error output, marks the test as failed, and +// stops the test execution. The provided arguments are assembled together into +// a string with fmt.Sprint. +func (c *C) Fatal(args ...interface{}) { + c.logCaller(1) + c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...))) + c.logNewLine() + c.FailNow() +} + +// Fatlaf logs an error into the test error output, marks the test as failed, and +// stops the test execution. The provided arguments are assembled together into +// a string with fmt.Sprintf. +func (c *C) Fatalf(format string, args ...interface{}) { + c.logCaller(1) + c.logString(fmt.Sprint("Error: ", fmt.Sprintf(format, args...))) + c.logNewLine() + c.FailNow() +} + +// ----------------------------------------------------------------------- +// Generic checks and assertions based on checkers. + +// Check verifies if the first value matches the expected value according +// to the provided checker. If they do not match, an error is logged, the +// test is marked as failed, and the test execution continues. +// +// Some checkers may not need the expected argument (e.g. IsNil). +// +// Extra arguments provided to the function are logged next to the reported +// problem when the matching fails. +func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool { + return c.internalCheck("Check", obtained, checker, args...) +} + +// Assert ensures that the first value matches the expected value according +// to the provided checker. If they do not match, an error is logged, the +// test is marked as failed, and the test execution stops. +// +// Some checkers may not need the expected argument (e.g. IsNil). +// +// Extra arguments provided to the function are logged next to the reported +// problem when the matching fails. +func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) { + if !c.internalCheck("Assert", obtained, checker, args...) { + c.stopNow() + } +} + +func (c *C) internalCheck(funcName string, obtained interface{}, checker Checker, args ...interface{}) bool { + if checker == nil { + c.logCaller(2) + c.logString(fmt.Sprintf("%s(obtained, nil!?, ...):", funcName)) + c.logString("Oops.. you've provided a nil checker!") + c.logNewLine() + c.Fail() + return false + } + + // If the last argument is a bug info, extract it out. + var comment CommentInterface + if len(args) > 0 { + if c, ok := args[len(args)-1].(CommentInterface); ok { + comment = c + args = args[:len(args)-1] + } + } + + params := append([]interface{}{obtained}, args...) + info := checker.Info() + + if len(params) != len(info.Params) { + names := append([]string{info.Params[0], info.Name}, info.Params[1:]...) + c.logCaller(2) + c.logString(fmt.Sprintf("%s(%s):", funcName, strings.Join(names, ", "))) + c.logString(fmt.Sprintf("Wrong number of parameters for %s: want %d, got %d", info.Name, len(names), len(params)+1)) + c.logNewLine() + c.Fail() + return false + } + + // Copy since it may be mutated by Check. + names := append([]string{}, info.Params...) + + // Do the actual check. + result, error := checker.Check(params, names) + if !result || error != "" { + c.logCaller(2) + for i := 0; i != len(params); i++ { + c.logValue(names[i], params[i]) + } + if comment != nil { + c.logString(comment.CheckCommentString()) + } + if error != "" { + c.logString(error) + } + c.logNewLine() + c.Fail() + return false + } + return true +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go new file mode 100644 index 000000000..4baa656ba --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go @@ -0,0 +1,519 @@ +// These tests verify the inner workings of the helper methods associated +// with check.T. + +package check_test + +import ( + "gopkg.in/check.v1" + "os" + "reflect" + "runtime" + "sync" +) + +var helpersS = check.Suite(&HelpersS{}) + +type HelpersS struct{} + +func (s *HelpersS) TestCountSuite(c *check.C) { + suitesRun += 1 +} + +// ----------------------------------------------------------------------- +// Fake checker and bug info to verify the behavior of Assert() and Check(). + +type MyChecker struct { + info *check.CheckerInfo + params []interface{} + names []string + result bool + error string +} + +func (checker *MyChecker) Info() *check.CheckerInfo { + if checker.info == nil { + return &check.CheckerInfo{Name: "MyChecker", Params: []string{"myobtained", "myexpected"}} + } + return checker.info +} + +func (checker *MyChecker) Check(params []interface{}, names []string) (bool, string) { + rparams := checker.params + rnames := checker.names + checker.params = append([]interface{}{}, params...) + checker.names = append([]string{}, names...) + if rparams != nil { + copy(params, rparams) + } + if rnames != nil { + copy(names, rnames) + } + return checker.result, checker.error +} + +type myCommentType string + +func (c myCommentType) CheckCommentString() string { + return string(c) +} + +func myComment(s string) myCommentType { + return myCommentType(s) +} + +// ----------------------------------------------------------------------- +// Ensure a real checker actually works fine. + +func (s *HelpersS) TestCheckerInterface(c *check.C) { + testHelperSuccess(c, "Check(1, Equals, 1)", true, func() interface{} { + return c.Check(1, check.Equals, 1) + }) +} + +// ----------------------------------------------------------------------- +// Tests for Check(), mostly the same as for Assert() following these. + +func (s *HelpersS) TestCheckSucceedWithExpected(c *check.C) { + checker := &MyChecker{result: true} + testHelperSuccess(c, "Check(1, checker, 2)", true, func() interface{} { + return c.Check(1, checker, 2) + }) + if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) { + c.Fatalf("Bad params for check: %#v", checker.params) + } +} + +func (s *HelpersS) TestCheckSucceedWithoutExpected(c *check.C) { + checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + testHelperSuccess(c, "Check(1, checker)", true, func() interface{} { + return c.Check(1, checker) + }) + if !reflect.DeepEqual(checker.params, []interface{}{1}) { + c.Fatalf("Bad params for check: %#v", checker.params) + } +} + +func (s *HelpersS) TestCheckFailWithExpected(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n\n" + testHelperFailure(c, "Check(1, checker, 2)", false, false, log, + func() interface{} { + return c.Check(1, checker, 2) + }) +} + +func (s *HelpersS) TestCheckFailWithExpectedAndComment(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n" + + "\\.+ Hello world!\n\n" + testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log, + func() interface{} { + return c.Check(1, checker, 2, myComment("Hello world!")) + }) +} + +func (s *HelpersS) TestCheckFailWithExpectedAndStaticComment(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " // Nice leading comment\\.\n" + + " return c\\.Check\\(1, checker, 2\\) // Hello there\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n\n" + testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log, + func() interface{} { + // Nice leading comment. + return c.Check(1, checker, 2) // Hello there + }) +} + +func (s *HelpersS) TestCheckFailWithoutExpected(c *check.C) { + checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker\\)\n" + + "\\.+ myvalue int = 1\n\n" + testHelperFailure(c, "Check(1, checker)", false, false, log, + func() interface{} { + return c.Check(1, checker) + }) +} + +func (s *HelpersS) TestCheckFailWithoutExpectedAndMessage(c *check.C) { + checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" + + "\\.+ myvalue int = 1\n" + + "\\.+ Hello world!\n\n" + testHelperFailure(c, "Check(1, checker, msg)", false, false, log, + func() interface{} { + return c.Check(1, checker, myComment("Hello world!")) + }) +} + +func (s *HelpersS) TestCheckWithMissingExpected(c *check.C) { + checker := &MyChecker{result: true} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker\\)\n" + + "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" + + "\\.+ Wrong number of parameters for MyChecker: " + + "want 3, got 2\n\n" + testHelperFailure(c, "Check(1, checker, !?)", false, false, log, + func() interface{} { + return c.Check(1, checker) + }) +} + +func (s *HelpersS) TestCheckWithTooManyExpected(c *check.C) { + checker := &MyChecker{result: true} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2, 3\\)\n" + + "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" + + "\\.+ Wrong number of parameters for MyChecker: " + + "want 3, got 4\n\n" + testHelperFailure(c, "Check(1, checker, 2, 3)", false, false, log, + func() interface{} { + return c.Check(1, checker, 2, 3) + }) +} + +func (s *HelpersS) TestCheckWithError(c *check.C) { + checker := &MyChecker{result: false, error: "Some not so cool data provided!"} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n" + + "\\.+ Some not so cool data provided!\n\n" + testHelperFailure(c, "Check(1, checker, 2)", false, false, log, + func() interface{} { + return c.Check(1, checker, 2) + }) +} + +func (s *HelpersS) TestCheckWithNilChecker(c *check.C) { + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, nil\\)\n" + + "\\.+ Check\\(obtained, nil!\\?, \\.\\.\\.\\):\n" + + "\\.+ Oops\\.\\. you've provided a nil checker!\n\n" + testHelperFailure(c, "Check(obtained, nil)", false, false, log, + func() interface{} { + return c.Check(1, nil) + }) +} + +func (s *HelpersS) TestCheckWithParamsAndNamesMutation(c *check.C) { + checker := &MyChecker{result: false, params: []interface{}{3, 4}, names: []string{"newobtained", "newexpected"}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2\\)\n" + + "\\.+ newobtained int = 3\n" + + "\\.+ newexpected int = 4\n\n" + testHelperFailure(c, "Check(1, checker, 2) with mutation", false, false, log, + func() interface{} { + return c.Check(1, checker, 2) + }) +} + +// ----------------------------------------------------------------------- +// Tests for Assert(), mostly the same as for Check() above. + +func (s *HelpersS) TestAssertSucceedWithExpected(c *check.C) { + checker := &MyChecker{result: true} + testHelperSuccess(c, "Assert(1, checker, 2)", nil, func() interface{} { + c.Assert(1, checker, 2) + return nil + }) + if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) { + c.Fatalf("Bad params for check: %#v", checker.params) + } +} + +func (s *HelpersS) TestAssertSucceedWithoutExpected(c *check.C) { + checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + testHelperSuccess(c, "Assert(1, checker)", nil, func() interface{} { + c.Assert(1, checker) + return nil + }) + if !reflect.DeepEqual(checker.params, []interface{}{1}) { + c.Fatalf("Bad params for check: %#v", checker.params) + } +} + +func (s *HelpersS) TestAssertFailWithExpected(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker, 2\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n\n" + testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log, + func() interface{} { + c.Assert(1, checker, 2) + return nil + }) +} + +func (s *HelpersS) TestAssertFailWithExpectedAndMessage(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n" + + "\\.+ Hello world!\n\n" + testHelperFailure(c, "Assert(1, checker, 2, msg)", nil, true, log, + func() interface{} { + c.Assert(1, checker, 2, myComment("Hello world!")) + return nil + }) +} + +func (s *HelpersS) TestAssertFailWithoutExpected(c *check.C) { + checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker\\)\n" + + "\\.+ myvalue int = 1\n\n" + testHelperFailure(c, "Assert(1, checker)", nil, true, log, + func() interface{} { + c.Assert(1, checker) + return nil + }) +} + +func (s *HelpersS) TestAssertFailWithoutExpectedAndMessage(c *check.C) { + checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" + + "\\.+ myvalue int = 1\n" + + "\\.+ Hello world!\n\n" + testHelperFailure(c, "Assert(1, checker, msg)", nil, true, log, + func() interface{} { + c.Assert(1, checker, myComment("Hello world!")) + return nil + }) +} + +func (s *HelpersS) TestAssertWithMissingExpected(c *check.C) { + checker := &MyChecker{result: true} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker\\)\n" + + "\\.+ Assert\\(myobtained, MyChecker, myexpected\\):\n" + + "\\.+ Wrong number of parameters for MyChecker: " + + "want 3, got 2\n\n" + testHelperFailure(c, "Assert(1, checker, !?)", nil, true, log, + func() interface{} { + c.Assert(1, checker) + return nil + }) +} + +func (s *HelpersS) TestAssertWithError(c *check.C) { + checker := &MyChecker{result: false, error: "Some not so cool data provided!"} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker, 2\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n" + + "\\.+ Some not so cool data provided!\n\n" + testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log, + func() interface{} { + c.Assert(1, checker, 2) + return nil + }) +} + +func (s *HelpersS) TestAssertWithNilChecker(c *check.C) { + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, nil\\)\n" + + "\\.+ Assert\\(obtained, nil!\\?, \\.\\.\\.\\):\n" + + "\\.+ Oops\\.\\. you've provided a nil checker!\n\n" + testHelperFailure(c, "Assert(obtained, nil)", nil, true, log, + func() interface{} { + c.Assert(1, nil) + return nil + }) +} + +// ----------------------------------------------------------------------- +// Ensure that values logged work properly in some interesting cases. + +func (s *HelpersS) TestValueLoggingWithArrays(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + + " return c\\.Check\\(\\[\\]byte{1, 2}, checker, \\[\\]byte{1, 3}\\)\n" + + "\\.+ myobtained \\[\\]uint8 = \\[\\]byte{0x1, 0x2}\n" + + "\\.+ myexpected \\[\\]uint8 = \\[\\]byte{0x1, 0x3}\n\n" + testHelperFailure(c, "Check([]byte{1}, chk, []byte{3})", false, false, log, + func() interface{} { + return c.Check([]byte{1, 2}, checker, []byte{1, 3}) + }) +} + +func (s *HelpersS) TestValueLoggingWithMultiLine(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + + " return c\\.Check\\(\"a\\\\nb\\\\n\", checker, \"a\\\\nb\\\\nc\"\\)\n" + + "\\.+ myobtained string = \"\" \\+\n" + + "\\.+ \"a\\\\n\" \\+\n" + + "\\.+ \"b\\\\n\"\n" + + "\\.+ myexpected string = \"\" \\+\n" + + "\\.+ \"a\\\\n\" \\+\n" + + "\\.+ \"b\\\\n\" \\+\n" + + "\\.+ \"c\"\n\n" + testHelperFailure(c, `Check("a\nb\n", chk, "a\nb\nc")`, false, false, log, + func() interface{} { + return c.Check("a\nb\n", checker, "a\nb\nc") + }) +} + +func (s *HelpersS) TestValueLoggingWithMultiLineException(c *check.C) { + // If the newline is at the end of the string, don't log as multi-line. + checker := &MyChecker{result: false} + log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + + " return c\\.Check\\(\"a b\\\\n\", checker, \"a\\\\nb\"\\)\n" + + "\\.+ myobtained string = \"a b\\\\n\"\n" + + "\\.+ myexpected string = \"\" \\+\n" + + "\\.+ \"a\\\\n\" \\+\n" + + "\\.+ \"b\"\n\n" + testHelperFailure(c, `Check("a b\n", chk, "a\nb")`, false, false, log, + func() interface{} { + return c.Check("a b\n", checker, "a\nb") + }) +} + +// ----------------------------------------------------------------------- +// MakeDir() tests. + +type MkDirHelper struct { + path1 string + path2 string + isDir1 bool + isDir2 bool + isDir3 bool + isDir4 bool +} + +func (s *MkDirHelper) SetUpSuite(c *check.C) { + s.path1 = c.MkDir() + s.isDir1 = isDir(s.path1) +} + +func (s *MkDirHelper) Test(c *check.C) { + s.path2 = c.MkDir() + s.isDir2 = isDir(s.path2) +} + +func (s *MkDirHelper) TearDownSuite(c *check.C) { + s.isDir3 = isDir(s.path1) + s.isDir4 = isDir(s.path2) +} + +func (s *HelpersS) TestMkDir(c *check.C) { + helper := MkDirHelper{} + output := String{} + check.Run(&helper, &check.RunConf{Output: &output}) + c.Assert(output.value, check.Equals, "") + c.Check(helper.isDir1, check.Equals, true) + c.Check(helper.isDir2, check.Equals, true) + c.Check(helper.isDir3, check.Equals, true) + c.Check(helper.isDir4, check.Equals, true) + c.Check(helper.path1, check.Not(check.Equals), + helper.path2) + c.Check(isDir(helper.path1), check.Equals, false) + c.Check(isDir(helper.path2), check.Equals, false) +} + +func isDir(path string) bool { + if stat, err := os.Stat(path); err == nil { + return stat.IsDir() + } + return false +} + +// Concurrent logging should not corrupt the underling buffer. +// Use go test -race to detect the race in this test. +func (s *HelpersS) TestConcurrentLogging(c *check.C) { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(runtime.NumCPU())) + var start, stop sync.WaitGroup + start.Add(1) + for i, n := 0, runtime.NumCPU()*2; i < n; i++ { + stop.Add(1) + go func(i int) { + start.Wait() + for j := 0; j < 30; j++ { + c.Logf("Worker %d: line %d", i, j) + } + stop.Done() + }(i) + } + start.Done() + stop.Wait() +} + +// ----------------------------------------------------------------------- +// Test the TestName function + +type TestNameHelper struct { + name1 string + name2 string + name3 string + name4 string + name5 string +} + +func (s *TestNameHelper) SetUpSuite(c *check.C) { s.name1 = c.TestName() } +func (s *TestNameHelper) SetUpTest(c *check.C) { s.name2 = c.TestName() } +func (s *TestNameHelper) Test(c *check.C) { s.name3 = c.TestName() } +func (s *TestNameHelper) TearDownTest(c *check.C) { s.name4 = c.TestName() } +func (s *TestNameHelper) TearDownSuite(c *check.C) { s.name5 = c.TestName() } + +func (s *HelpersS) TestTestName(c *check.C) { + helper := TestNameHelper{} + output := String{} + check.Run(&helper, &check.RunConf{Output: &output}) + c.Check(helper.name1, check.Equals, "") + c.Check(helper.name2, check.Equals, "TestNameHelper.Test") + c.Check(helper.name3, check.Equals, "TestNameHelper.Test") + c.Check(helper.name4, check.Equals, "TestNameHelper.Test") + c.Check(helper.name5, check.Equals, "") +} + +// ----------------------------------------------------------------------- +// A couple of helper functions to test helper functions. :-) + +func testHelperSuccess(c *check.C, name string, expectedResult interface{}, closure func() interface{}) { + var result interface{} + defer (func() { + if err := recover(); err != nil { + panic(err) + } + checkState(c, result, + &expectedState{ + name: name, + result: expectedResult, + failed: false, + log: "", + }) + })() + result = closure() +} + +func testHelperFailure(c *check.C, name string, expectedResult interface{}, shouldStop bool, log string, closure func() interface{}) { + var result interface{} + defer (func() { + if err := recover(); err != nil { + panic(err) + } + checkState(c, result, + &expectedState{ + name: name, + result: expectedResult, + failed: true, + log: log, + }) + })() + result = closure() + if shouldStop { + c.Logf("%s didn't stop when it should", name) + } +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/printer.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/printer.go new file mode 100644 index 000000000..e0f7557b5 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/printer.go @@ -0,0 +1,168 @@ +package check + +import ( + "bytes" + "go/ast" + "go/parser" + "go/printer" + "go/token" + "os" +) + +func indent(s, with string) (r string) { + eol := true + for i := 0; i != len(s); i++ { + c := s[i] + switch { + case eol && c == '\n' || c == '\r': + case c == '\n' || c == '\r': + eol = true + case eol: + eol = false + s = s[:i] + with + s[i:] + i += len(with) + } + } + return s +} + +func printLine(filename string, line int) (string, error) { + fset := token.NewFileSet() + file, err := os.Open(filename) + if err != nil { + return "", err + } + fnode, err := parser.ParseFile(fset, filename, file, parser.ParseComments) + if err != nil { + return "", err + } + config := &printer.Config{Mode: printer.UseSpaces, Tabwidth: 4} + lp := &linePrinter{fset: fset, fnode: fnode, line: line, config: config} + ast.Walk(lp, fnode) + result := lp.output.Bytes() + // Comments leave \n at the end. + n := len(result) + for n > 0 && result[n-1] == '\n' { + n-- + } + return string(result[:n]), nil +} + +type linePrinter struct { + config *printer.Config + fset *token.FileSet + fnode *ast.File + line int + output bytes.Buffer + stmt ast.Stmt +} + +func (lp *linePrinter) emit() bool { + if lp.stmt != nil { + lp.trim(lp.stmt) + lp.printWithComments(lp.stmt) + lp.stmt = nil + return true + } + return false +} + +func (lp *linePrinter) printWithComments(n ast.Node) { + nfirst := lp.fset.Position(n.Pos()).Line + nlast := lp.fset.Position(n.End()).Line + for _, g := range lp.fnode.Comments { + cfirst := lp.fset.Position(g.Pos()).Line + clast := lp.fset.Position(g.End()).Line + if clast == nfirst-1 && lp.fset.Position(n.Pos()).Column == lp.fset.Position(g.Pos()).Column { + for _, c := range g.List { + lp.output.WriteString(c.Text) + lp.output.WriteByte('\n') + } + } + if cfirst >= nfirst && cfirst <= nlast && n.End() <= g.List[0].Slash { + // The printer will not include the comment if it starts past + // the node itself. Trick it into printing by overlapping the + // slash with the end of the statement. + g.List[0].Slash = n.End() - 1 + } + } + node := &printer.CommentedNode{n, lp.fnode.Comments} + lp.config.Fprint(&lp.output, lp.fset, node) +} + +func (lp *linePrinter) Visit(n ast.Node) (w ast.Visitor) { + if n == nil { + if lp.output.Len() == 0 { + lp.emit() + } + return nil + } + first := lp.fset.Position(n.Pos()).Line + last := lp.fset.Position(n.End()).Line + if first <= lp.line && last >= lp.line { + // Print the innermost statement containing the line. + if stmt, ok := n.(ast.Stmt); ok { + if _, ok := n.(*ast.BlockStmt); !ok { + lp.stmt = stmt + } + } + if first == lp.line && lp.emit() { + return nil + } + return lp + } + return nil +} + +func (lp *linePrinter) trim(n ast.Node) bool { + stmt, ok := n.(ast.Stmt) + if !ok { + return true + } + line := lp.fset.Position(n.Pos()).Line + if line != lp.line { + return false + } + switch stmt := stmt.(type) { + case *ast.IfStmt: + stmt.Body = lp.trimBlock(stmt.Body) + case *ast.SwitchStmt: + stmt.Body = lp.trimBlock(stmt.Body) + case *ast.TypeSwitchStmt: + stmt.Body = lp.trimBlock(stmt.Body) + case *ast.CaseClause: + stmt.Body = lp.trimList(stmt.Body) + case *ast.CommClause: + stmt.Body = lp.trimList(stmt.Body) + case *ast.BlockStmt: + stmt.List = lp.trimList(stmt.List) + } + return true +} + +func (lp *linePrinter) trimBlock(stmt *ast.BlockStmt) *ast.BlockStmt { + if !lp.trim(stmt) { + return lp.emptyBlock(stmt) + } + stmt.Rbrace = stmt.Lbrace + return stmt +} + +func (lp *linePrinter) trimList(stmts []ast.Stmt) []ast.Stmt { + for i := 0; i != len(stmts); i++ { + if !lp.trim(stmts[i]) { + stmts[i] = lp.emptyStmt(stmts[i]) + break + } + } + return stmts +} + +func (lp *linePrinter) emptyStmt(n ast.Node) *ast.ExprStmt { + return &ast.ExprStmt{&ast.Ellipsis{n.Pos(), nil}} +} + +func (lp *linePrinter) emptyBlock(n ast.Node) *ast.BlockStmt { + p := n.Pos() + return &ast.BlockStmt{p, []ast.Stmt{lp.emptyStmt(n)}, p} +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go new file mode 100644 index 000000000..538b2d52e --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go @@ -0,0 +1,104 @@ +package check_test + +import ( + . "gopkg.in/check.v1" +) + +var _ = Suite(&PrinterS{}) + +type PrinterS struct{} + +func (s *PrinterS) TestCountSuite(c *C) { + suitesRun += 1 +} + +var printTestFuncLine int + +func init() { + printTestFuncLine = getMyLine() + 3 +} + +func printTestFunc() { + println(1) // Comment1 + if 2 == 2 { // Comment2 + println(3) // Comment3 + } + switch 5 { + case 6: println(6) // Comment6 + println(7) + } + switch interface{}(9).(type) {// Comment9 + case int: println(10) + println(11) + } + select { + case <-(chan bool)(nil): println(14) + println(15) + default: println(16) + println(17) + } + println(19, + 20) + _ = func() { println(21) + println(22) + } + println(24, func() { + println(25) + }) + // Leading comment + // with multiple lines. + println(29) // Comment29 +} + +var printLineTests = []struct { + line int + output string +}{ + {1, "println(1) // Comment1"}, + {2, "if 2 == 2 { // Comment2\n ...\n}"}, + {3, "println(3) // Comment3"}, + {5, "switch 5 {\n...\n}"}, + {6, "case 6:\n println(6) // Comment6\n ..."}, + {7, "println(7)"}, + {9, "switch interface{}(9).(type) { // Comment9\n...\n}"}, + {10, "case int:\n println(10)\n ..."}, + {14, "case <-(chan bool)(nil):\n println(14)\n ..."}, + {15, "println(15)"}, + {16, "default:\n println(16)\n ..."}, + {17, "println(17)"}, + {19, "println(19,\n 20)"}, + {20, "println(19,\n 20)"}, + {21, "_ = func() {\n println(21)\n println(22)\n}"}, + {22, "println(22)"}, + {24, "println(24, func() {\n println(25)\n})"}, + {25, "println(25)"}, + {26, "println(24, func() {\n println(25)\n})"}, + {29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"}, +} + +func (s *PrinterS) TestPrintLine(c *C) { + for _, test := range printLineTests { + output, err := PrintLine("printer_test.go", printTestFuncLine+test.line) + c.Assert(err, IsNil) + c.Assert(output, Equals, test.output) + } +} + +var indentTests = []struct { + in, out string +}{ + {"", ""}, + {"\n", "\n"}, + {"a", ">>>a"}, + {"a\n", ">>>a\n"}, + {"a\nb", ">>>a\n>>>b"}, + {" ", ">>> "}, +} + +func (s *PrinterS) TestIndent(c *C) { + for _, test := range indentTests { + out := Indent(test.in, ">>>") + c.Assert(out, Equals, test.out) + } + +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/run.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/run.go new file mode 100644 index 000000000..da8fd7987 --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/run.go @@ -0,0 +1,175 @@ +package check + +import ( + "bufio" + "flag" + "fmt" + "os" + "testing" + "time" +) + +// ----------------------------------------------------------------------- +// Test suite registry. + +var allSuites []interface{} + +// Suite registers the given value as a test suite to be run. Any methods +// starting with the Test prefix in the given value will be considered as +// a test method. +func Suite(suite interface{}) interface{} { + allSuites = append(allSuites, suite) + return suite +} + +// ----------------------------------------------------------------------- +// Public running interface. + +var ( + oldFilterFlag = flag.String("gocheck.f", "", "Regular expression selecting which tests and/or suites to run") + oldVerboseFlag = flag.Bool("gocheck.v", false, "Verbose mode") + oldStreamFlag = flag.Bool("gocheck.vv", false, "Super verbose mode (disables output caching)") + oldBenchFlag = flag.Bool("gocheck.b", false, "Run benchmarks") + oldBenchTime = flag.Duration("gocheck.btime", 1*time.Second, "approximate run time for each benchmark") + oldListFlag = flag.Bool("gocheck.list", false, "List the names of all tests that will be run") + oldWorkFlag = flag.Bool("gocheck.work", false, "Display and do not remove the test working directory") + + newFilterFlag = flag.String("check.f", "", "Regular expression selecting which tests and/or suites to run") + newVerboseFlag = flag.Bool("check.v", false, "Verbose mode") + newStreamFlag = flag.Bool("check.vv", false, "Super verbose mode (disables output caching)") + newBenchFlag = flag.Bool("check.b", false, "Run benchmarks") + newBenchTime = flag.Duration("check.btime", 1*time.Second, "approximate run time for each benchmark") + newBenchMem = flag.Bool("check.bmem", false, "Report memory benchmarks") + newListFlag = flag.Bool("check.list", false, "List the names of all tests that will be run") + newWorkFlag = flag.Bool("check.work", false, "Display and do not remove the test working directory") +) + +// TestingT runs all test suites registered with the Suite function, +// printing results to stdout, and reporting any failures back to +// the "testing" package. +func TestingT(testingT *testing.T) { + benchTime := *newBenchTime + if benchTime == 1*time.Second { + benchTime = *oldBenchTime + } + conf := &RunConf{ + Filter: *oldFilterFlag + *newFilterFlag, + Verbose: *oldVerboseFlag || *newVerboseFlag, + Stream: *oldStreamFlag || *newStreamFlag, + Benchmark: *oldBenchFlag || *newBenchFlag, + BenchmarkTime: benchTime, + BenchmarkMem: *newBenchMem, + KeepWorkDir: *oldWorkFlag || *newWorkFlag, + } + if *oldListFlag || *newListFlag { + w := bufio.NewWriter(os.Stdout) + for _, name := range ListAll(conf) { + fmt.Fprintln(w, name) + } + w.Flush() + return + } + result := RunAll(conf) + println(result.String()) + if !result.Passed() { + testingT.Fail() + } +} + +// RunAll runs all test suites registered with the Suite function, using the +// provided run configuration. +func RunAll(runConf *RunConf) *Result { + result := Result{} + for _, suite := range allSuites { + result.Add(Run(suite, runConf)) + } + return &result +} + +// Run runs the provided test suite using the provided run configuration. +func Run(suite interface{}, runConf *RunConf) *Result { + runner := newSuiteRunner(suite, runConf) + return runner.run() +} + +// ListAll returns the names of all the test functions registered with the +// Suite function that will be run with the provided run configuration. +func ListAll(runConf *RunConf) []string { + var names []string + for _, suite := range allSuites { + names = append(names, List(suite, runConf)...) + } + return names +} + +// List returns the names of the test functions in the given +// suite that will be run with the provided run configuration. +func List(suite interface{}, runConf *RunConf) []string { + var names []string + runner := newSuiteRunner(suite, runConf) + for _, t := range runner.tests { + names = append(names, t.String()) + } + return names +} + +// ----------------------------------------------------------------------- +// Result methods. + +func (r *Result) Add(other *Result) { + r.Succeeded += other.Succeeded + r.Skipped += other.Skipped + r.Failed += other.Failed + r.Panicked += other.Panicked + r.FixturePanicked += other.FixturePanicked + r.ExpectedFailures += other.ExpectedFailures + r.Missed += other.Missed + if r.WorkDir != "" && other.WorkDir != "" { + r.WorkDir += ":" + other.WorkDir + } else if other.WorkDir != "" { + r.WorkDir = other.WorkDir + } +} + +func (r *Result) Passed() bool { + return (r.Failed == 0 && r.Panicked == 0 && + r.FixturePanicked == 0 && r.Missed == 0 && + r.RunError == nil) +} + +func (r *Result) String() string { + if r.RunError != nil { + return "ERROR: " + r.RunError.Error() + } + + var value string + if r.Failed == 0 && r.Panicked == 0 && r.FixturePanicked == 0 && + r.Missed == 0 { + value = "OK: " + } else { + value = "OOPS: " + } + value += fmt.Sprintf("%d passed", r.Succeeded) + if r.Skipped != 0 { + value += fmt.Sprintf(", %d skipped", r.Skipped) + } + if r.ExpectedFailures != 0 { + value += fmt.Sprintf(", %d expected failures", r.ExpectedFailures) + } + if r.Failed != 0 { + value += fmt.Sprintf(", %d FAILED", r.Failed) + } + if r.Panicked != 0 { + value += fmt.Sprintf(", %d PANICKED", r.Panicked) + } + if r.FixturePanicked != 0 { + value += fmt.Sprintf(", %d FIXTURE-PANICKED", r.FixturePanicked) + } + if r.Missed != 0 { + value += fmt.Sprintf(", %d MISSED", r.Missed) + } + if r.WorkDir != "" { + value += "\nWORK=" + r.WorkDir + } + return value +} diff --git a/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go new file mode 100644 index 000000000..f41fffc3f --- /dev/null +++ b/pkg/api/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go @@ -0,0 +1,419 @@ +// These tests verify the test running logic. + +package check_test + +import ( + "errors" + . "gopkg.in/check.v1" + "os" + "sync" +) + +var runnerS = Suite(&RunS{}) + +type RunS struct{} + +func (s *RunS) TestCountSuite(c *C) { + suitesRun += 1 +} + +// ----------------------------------------------------------------------- +// Tests ensuring result counting works properly. + +func (s *RunS) TestSuccess(c *C) { + output := String{} + result := Run(&SuccessHelper{}, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 1) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 0) + c.Check(result.Missed, Equals, 0) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestFailure(c *C) { + output := String{} + result := Run(&FailHelper{}, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 0) + c.Check(result.Failed, Equals, 1) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 0) + c.Check(result.Missed, Equals, 0) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestFixture(c *C) { + output := String{} + result := Run(&FixtureHelper{}, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 2) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 0) + c.Check(result.Missed, Equals, 0) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestPanicOnTest(c *C) { + output := String{} + helper := &FixtureHelper{panicOn: "Test1"} + result := Run(helper, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 1) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 1) + c.Check(result.FixturePanicked, Equals, 0) + c.Check(result.Missed, Equals, 0) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestPanicOnSetUpTest(c *C) { + output := String{} + helper := &FixtureHelper{panicOn: "SetUpTest"} + result := Run(helper, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 0) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 1) + c.Check(result.Missed, Equals, 2) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestPanicOnSetUpSuite(c *C) { + output := String{} + helper := &FixtureHelper{panicOn: "SetUpSuite"} + result := Run(helper, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 0) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 1) + c.Check(result.Missed, Equals, 2) + c.Check(result.RunError, IsNil) +} + +// ----------------------------------------------------------------------- +// Check result aggregation. + +func (s *RunS) TestAdd(c *C) { + result := &Result{ + Succeeded: 1, + Skipped: 2, + Failed: 3, + Panicked: 4, + FixturePanicked: 5, + Missed: 6, + ExpectedFailures: 7, + } + result.Add(&Result{ + Succeeded: 10, + Skipped: 20, + Failed: 30, + Panicked: 40, + FixturePanicked: 50, + Missed: 60, + ExpectedFailures: 70, + }) + c.Check(result.Succeeded, Equals, 11) + c.Check(result.Skipped, Equals, 22) + c.Check(result.Failed, Equals, 33) + c.Check(result.Panicked, Equals, 44) + c.Check(result.FixturePanicked, Equals, 55) + c.Check(result.Missed, Equals, 66) + c.Check(result.ExpectedFailures, Equals, 77) + c.Check(result.RunError, IsNil) +} + +// ----------------------------------------------------------------------- +// Check the Passed() method. + +func (s *RunS) TestPassed(c *C) { + c.Assert((&Result{}).Passed(), Equals, true) + c.Assert((&Result{Succeeded: 1}).Passed(), Equals, true) + c.Assert((&Result{Skipped: 1}).Passed(), Equals, true) + c.Assert((&Result{Failed: 1}).Passed(), Equals, false) + c.Assert((&Result{Panicked: 1}).Passed(), Equals, false) + c.Assert((&Result{FixturePanicked: 1}).Passed(), Equals, false) + c.Assert((&Result{Missed: 1}).Passed(), Equals, false) + c.Assert((&Result{RunError: errors.New("!")}).Passed(), Equals, false) +} + +// ----------------------------------------------------------------------- +// Check that result printing is working correctly. + +func (s *RunS) TestPrintSuccess(c *C) { + result := &Result{Succeeded: 5} + c.Check(result.String(), Equals, "OK: 5 passed") +} + +func (s *RunS) TestPrintFailure(c *C) { + result := &Result{Failed: 5} + c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FAILED") +} + +func (s *RunS) TestPrintSkipped(c *C) { + result := &Result{Skipped: 5} + c.Check(result.String(), Equals, "OK: 0 passed, 5 skipped") +} + +func (s *RunS) TestPrintExpectedFailures(c *C) { + result := &Result{ExpectedFailures: 5} + c.Check(result.String(), Equals, "OK: 0 passed, 5 expected failures") +} + +func (s *RunS) TestPrintPanicked(c *C) { + result := &Result{Panicked: 5} + c.Check(result.String(), Equals, "OOPS: 0 passed, 5 PANICKED") +} + +func (s *RunS) TestPrintFixturePanicked(c *C) { + result := &Result{FixturePanicked: 5} + c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FIXTURE-PANICKED") +} + +func (s *RunS) TestPrintMissed(c *C) { + result := &Result{Missed: 5} + c.Check(result.String(), Equals, "OOPS: 0 passed, 5 MISSED") +} + +func (s *RunS) TestPrintAll(c *C) { + result := &Result{Succeeded: 1, Skipped: 2, ExpectedFailures: 3, + Panicked: 4, FixturePanicked: 5, Missed: 6} + c.Check(result.String(), Equals, + "OOPS: 1 passed, 2 skipped, 3 expected failures, 4 PANICKED, "+ + "5 FIXTURE-PANICKED, 6 MISSED") +} + +func (s *RunS) TestPrintRunError(c *C) { + result := &Result{Succeeded: 1, Failed: 1, + RunError: errors.New("Kaboom!")} + c.Check(result.String(), Equals, "ERROR: Kaboom!") +} + +// ----------------------------------------------------------------------- +// Verify that the method pattern flag works correctly. + +func (s *RunS) TestFilterTestName(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "Test[91]"} + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 5) +} + +func (s *RunS) TestFilterTestNameWithAll(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: ".*"} + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) +} + +func (s *RunS) TestFilterSuiteName(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "FixtureHelper"} + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) +} + +func (s *RunS) TestFilterSuiteNameAndTestName(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "FixtureHelper\\.Test2"} + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test2") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 5) +} + +func (s *RunS) TestFilterAllOut(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "NotFound"} + Run(&helper, &runConf) + c.Check(len(helper.calls), Equals, 0) +} + +func (s *RunS) TestRequirePartialMatch(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "est"} + Run(&helper, &runConf) + c.Check(len(helper.calls), Equals, 8) +} + +func (s *RunS) TestFilterError(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "]["} + result := Run(&helper, &runConf) + c.Check(result.String(), Equals, + "ERROR: Bad filter expression: error parsing regexp: missing closing ]: `[`") + c.Check(len(helper.calls), Equals, 0) +} + +// ----------------------------------------------------------------------- +// Verify that List works correctly. + +func (s *RunS) TestListFiltered(c *C) { + names := List(&FixtureHelper{}, &RunConf{Filter: "1"}) + c.Assert(names, DeepEquals, []string{ + "FixtureHelper.Test1", + }) +} + +func (s *RunS) TestList(c *C) { + names := List(&FixtureHelper{}, &RunConf{}) + c.Assert(names, DeepEquals, []string{ + "FixtureHelper.Test1", + "FixtureHelper.Test2", + }) +} + +// ----------------------------------------------------------------------- +// Verify that verbose mode prints tests which pass as well. + +func (s *RunS) TestVerboseMode(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Verbose: true} + Run(&helper, &runConf) + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t *[.0-9]+s\n" + + "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n" + + c.Assert(output.value, Matches, expected) +} + +func (s *RunS) TestVerboseModeWithFailBeforePass(c *C) { + helper := FixtureHelper{panicOn: "Test1"} + output := String{} + runConf := RunConf{Output: &output, Verbose: true} + Run(&helper, &runConf) + + expected := "(?s).*PANIC.*\n-+\n" + // Should have an extra line. + "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n" + + c.Assert(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// Verify the stream output mode. In this mode there's no output caching. + +type StreamHelper struct { + l2 sync.Mutex + l3 sync.Mutex +} + +func (s *StreamHelper) SetUpSuite(c *C) { + c.Log("0") +} + +func (s *StreamHelper) Test1(c *C) { + c.Log("1") + s.l2.Lock() + s.l3.Lock() + go func() { + s.l2.Lock() // Wait for "2". + c.Log("3") + s.l3.Unlock() + }() +} + +func (s *StreamHelper) Test2(c *C) { + c.Log("2") + s.l2.Unlock() + s.l3.Lock() // Wait for "3". + c.Fail() + c.Log("4") +} + +func (s *RunS) TestStreamMode(c *C) { + helper := &StreamHelper{} + output := String{} + runConf := RunConf{Output: &output, Stream: true} + Run(helper, &runConf) + + expected := "START: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\n0\n" + + "PASS: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\t *[.0-9]+s\n\n" + + "START: run_test\\.go:[0-9]+: StreamHelper\\.Test1\n1\n" + + "PASS: run_test\\.go:[0-9]+: StreamHelper\\.Test1\t *[.0-9]+s\n\n" + + "START: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n2\n3\n4\n" + + "FAIL: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n\n" + + c.Assert(output.value, Matches, expected) +} + +type StreamMissHelper struct{} + +func (s *StreamMissHelper) SetUpSuite(c *C) { + c.Log("0") + c.Fail() +} + +func (s *StreamMissHelper) Test1(c *C) { + c.Log("1") +} + +func (s *RunS) TestStreamModeWithMiss(c *C) { + helper := &StreamMissHelper{} + output := String{} + runConf := RunConf{Output: &output, Stream: true} + Run(helper, &runConf) + + expected := "START: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n0\n" + + "FAIL: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n\n" + + "START: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n" + + "MISS: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n\n" + + c.Assert(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// Verify that that the keep work dir request indeed does so. + +type WorkDirSuite struct {} + +func (s *WorkDirSuite) Test(c *C) { + c.MkDir() +} + +func (s *RunS) TestKeepWorkDir(c *C) { + output := String{} + runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true} + result := Run(&WorkDirSuite{}, &runConf) + + c.Assert(result.String(), Matches, ".*\nWORK=" + result.WorkDir) + + stat, err := os.Stat(result.WorkDir) + c.Assert(err, IsNil) + c.Assert(stat.IsDir(), Equals, true) +} From 717913bc8a01e5a949d13898e7603e9329f0db41 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 3 Apr 2015 18:59:35 -0700 Subject: [PATCH 3/3] Remove mxj, Update gopkg.in/check.v1 --- Godeps/Godeps.json | 10 +- .../src/github.com/clbanning/mxj/LICENSE | 55 - .../src/github.com/clbanning/mxj/anyxml.go | 177 --- .../github.com/clbanning/mxj/anyxml_test.go | 110 -- .../src/github.com/clbanning/mxj/bulk_test.go | 107 -- .../github.com/clbanning/mxj/bulkraw_test.go | 113 -- .../src/github.com/clbanning/mxj/data_test.go | 38 - .../src/github.com/clbanning/mxj/doc.go | 84 -- .../github.com/clbanning/mxj/example_test.go | 344 ------ .../github.com/clbanning/mxj/examples/README | 124 -- .../clbanning/mxj/examples/books.go | 71 -- .../clbanning/mxj/examples/getmetrics1.go | 176 --- .../clbanning/mxj/examples/getmetrics2.go | 173 --- .../clbanning/mxj/examples/getmetrics3.go | 180 --- .../clbanning/mxj/examples/getmetrics4.go | 179 --- .../clbanning/mxj/examples/gonuts1.go | 82 -- .../clbanning/mxj/examples/gonuts1a.go | 68 -- .../clbanning/mxj/examples/gonuts2.go | 240 ---- .../clbanning/mxj/examples/gonuts3.go | 47 - .../clbanning/mxj/examples/gonuts4.go | 50 - .../clbanning/mxj/examples/gonuts5.go | 75 -- .../clbanning/mxj/examples/gonuts5a.go | 75 -- .../clbanning/mxj/examples/gonuts6.go | 43 - .../clbanning/mxj/examples/metrics_data.zip | Bin 983854 -> 0 bytes .../src/github.com/clbanning/mxj/files.go | 299 ----- .../clbanning/mxj/files_test.badjson | 2 - .../clbanning/mxj/files_test.badxml | 9 - .../github.com/clbanning/mxj/files_test.go | 168 --- .../github.com/clbanning/mxj/files_test.json | 2 - .../github.com/clbanning/mxj/files_test.xml | 9 - .../clbanning/mxj/files_test_dup.json | 1 - .../clbanning/mxj/files_test_dup.xml | 1 - .../clbanning/mxj/files_test_indent.json | 12 - .../clbanning/mxj/files_test_indent.xml | 8 - .../src/github.com/clbanning/mxj/j2x/j2x.go | 178 --- .../github.com/clbanning/mxj/j2x/j2x_test.go | 67 -- .../src/github.com/clbanning/mxj/j2x_test.go | 29 - .../src/github.com/clbanning/mxj/json.go | 319 ----- .../src/github.com/clbanning/mxj/json_test.go | 137 --- .../src/github.com/clbanning/mxj/keyvalues.go | 620 ---------- .../clbanning/mxj/keyvalues_test.go | 412 ------- .../src/github.com/clbanning/mxj/leafnode.go | 82 -- .../github.com/clbanning/mxj/leafnode_test.go | 97 -- .../src/github.com/clbanning/mxj/mxj.go | 107 -- .../src/github.com/clbanning/mxj/mxj_test.go | 38 - .../src/github.com/clbanning/mxj/newmap.go | 183 --- .../github.com/clbanning/mxj/newmap_test.go | 114 -- .../src/github.com/clbanning/mxj/readme.md | 113 -- .../github.com/clbanning/mxj/seqnum_test.go | 52 - .../src/github.com/clbanning/mxj/struct.go | 40 - .../github.com/clbanning/mxj/struct_test.go | 84 -- .../github.com/clbanning/mxj/updatevalues.go | 249 ---- .../clbanning/mxj/updatevalues_test.go | 187 --- .../src/github.com/clbanning/mxj/x2j/x2j.go | 184 --- .../src/github.com/clbanning/mxj/xml.go | 838 ------------- .../clbanning/mxj/xml_marshal/README | 26 - .../mxj/xml_marshal/example_test.go.v1_2 | 211 ---- .../clbanning/mxj/xml_marshal/marshal.go.v1_2 | 1034 ----------------- .../src/github.com/clbanning/mxj/xml_test.go | 207 ---- .../src/github.com/fatih/structs/.gitignore | 23 - .../src/github.com/fatih/structs/.travis.yml | 11 - .../src/github.com/fatih/structs/LICENSE | 21 - .../src/github.com/fatih/structs/README.md | 159 --- .../src/github.com/fatih/structs/field.go | 126 -- .../github.com/fatih/structs/field_test.go | 324 ------ .../src/github.com/fatih/structs/structs.go | 422 ------- .../fatih/structs/structs_example_test.go | 351 ------ .../github.com/fatih/structs/structs_test.go | 847 -------------- .../src/github.com/fatih/structs/tags.go | 32 - .../src/github.com/fatih/structs/tags_test.go | 46 - .../src/gopkg.in/check.v1/benchmark_test.go | 2 +- .../src/gopkg.in/check.v1/printer_test.go | 145 ++- .../src/gopkg.in/check.v1/run_test.go | 4 +- 73 files changed, 74 insertions(+), 11179 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/LICENSE delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/anyxml.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/anyxml_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/bulk_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/bulkraw_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/data_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/doc.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/example_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/README delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/books.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics1.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics2.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics3.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics4.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts1.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts1a.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts2.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts3.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts4.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts5.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts5a.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts6.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/examples/metrics_data.zip delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test.badjson delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test.badxml delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test.json delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test.xml delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test_dup.json delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test_dup.xml delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test_indent.json delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/files_test_indent.xml delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/j2x/j2x.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/j2x/j2x_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/j2x_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/json.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/json_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/keyvalues.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/keyvalues_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/leafnode.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/leafnode_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/mxj.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/mxj_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/newmap.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/newmap_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/readme.md delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/seqnum_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/struct.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/struct_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/updatevalues.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/updatevalues_test.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/x2j/x2j.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/xml.go delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/xml_marshal/README delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/xml_marshal/example_test.go.v1_2 delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/xml_marshal/marshal.go.v1_2 delete mode 100644 Godeps/_workspace/src/github.com/clbanning/mxj/xml_test.go delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/.gitignore delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/.travis.yml delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/LICENSE delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/README.md delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/field.go delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/field_test.go delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/structs.go delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/structs_example_test.go delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/structs_test.go delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/tags.go delete mode 100644 Godeps/_workspace/src/github.com/fatih/structs/tags_test.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 299d7b306..0eae7e597 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,18 +1,10 @@ { "ImportPath": "github.com/minio-io/minio", - "GoVersion": "go1.4.2", + "GoVersion": "go1.4", "Packages": [ "./..." ], "Deps": [ - { - "ImportPath": "github.com/clbanning/mxj", - "Rev": "e11b85050263aff26728fb9863bf2ebaf6591279" - }, - { - "ImportPath": "github.com/fatih/structs", - "Rev": "c00d27128bb88e9c1adab1a53cda9c72c6d1ff9b" - }, { "ImportPath": "github.com/gorilla/context", "Rev": "50c25fb3b2b3b3cc724e9b6ac75fb44b3bccd0da" diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/LICENSE b/Godeps/_workspace/src/github.com/clbanning/mxj/LICENSE deleted file mode 100644 index 67563f958..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Copyright (c) 2012-2014 Charles Banning . All rights reserved. - -The MIT License (MIT) - -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. - -=============================================================================== - -Go Language Copyright & License - - -Copyright 2009 The Go Authors. All rights reserved. -Use of this source code is governed by a BSD-style -license that can be found in the LICENSE file. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/anyxml.go b/Godeps/_workspace/src/github.com/clbanning/mxj/anyxml.go deleted file mode 100644 index 5579e1036..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/anyxml.go +++ /dev/null @@ -1,177 +0,0 @@ -package mxj - -import ( - "encoding/xml" - "reflect" -) - -const ( - DefaultElementTag = "element" -) - -// Encode arbitrary value as XML. -// -// Note: unmarshaling the resultant -// XML may not return the original value, since tag labels may have been injected -// to create the XML representation of the value. -/* - Encode an arbitrary JSON object. - package main - - import ( - "encoding/json" - "fmt" - "github/clbanning/mxj" - ) - - func main() { - jsondata := []byte(`[ - { "somekey":"somevalue" }, - "string", - 3.14159265, - true - ]`) - var i interface{} - err := json.Unmarshal(jsondata, &i) - if err != nil { - // do something - } - x, err := anyxml.XmlIndent(i, "", " ", "mydoc") - if err != nil { - // do something else - } - fmt.Println(string(x)) - } - - output: - - somevalue - string - 3.14159265 - true - -*/ -// Alternative values for DefaultRootTag and DefaultElementTag can be set as: -// AnyXmlIndent( v, myRootTag, myElementTag). -func AnyXml(v interface{}, tags ...string) ([]byte, error) { - if reflect.TypeOf(v).Kind() == reflect.Struct { - return xml.Marshal(v) - } - - var err error - s := new(string) - p := new(pretty) - - var rt, et string - if len(tags) == 1 || len(tags) == 2 { - rt = tags[0] - } else { - rt = DefaultRootTag - } - if len(tags) == 2 { - et = tags[1] - } else { - et = DefaultElementTag - } - - var ss string - var b []byte - switch v.(type) { - case []interface{}: - ss = "<" + rt + ">" - for _, vv := range v.([]interface{}) { - switch vv.(type) { - case map[string]interface{}: - m := vv.(map[string]interface{}) - if len(m) == 1 { - for tag, val := range m { - err = mapToXmlIndent(false, s, tag, val, p) - } - } else { - err = mapToXmlIndent(false, s, et, vv, p) - } - default: - err = mapToXmlIndent(false, s, et, vv, p) - } - if err != nil { - break - } - } - ss += *s + "" - b = []byte(ss) - case map[string]interface{}: - m := Map(v.(map[string]interface{})) - b, err = m.Xml(rt) - default: - err = mapToXmlIndent(false, s, rt, v, p) - b = []byte(*s) - } - - return b, err -} - -// Encode an arbitrary value as a pretty XML string. -// Alternative values for DefaultRootTag and DefaultElementTag can be set as: -// AnyXmlIndent( v, "", " ", myRootTag, myElementTag). -func AnyXmlIndent(v interface{}, prefix, indent string, tags ...string) ([]byte, error) { - if reflect.TypeOf(v).Kind() == reflect.Struct { - return xml.MarshalIndent(v, prefix, indent) - } - - var err error - s := new(string) - p := new(pretty) - p.indent = indent - p.padding = prefix - - var rt, et string - if len(tags) == 1 || len(tags) == 2 { - rt = tags[0] - } else { - rt = DefaultRootTag - } - if len(tags) == 2 { - et = tags[1] - } else { - et = DefaultElementTag - } - - var ss string - var b []byte - switch v.(type) { - case []interface{}: - ss = "<" + rt + ">\n" - p.Indent() - for _, vv := range v.([]interface{}) { - switch vv.(type) { - case map[string]interface{}: - m := vv.(map[string]interface{}) - if len(m) == 1 { - for tag, val := range m { - err = mapToXmlIndent(true, s, tag, val, p) - } - } else { - p.start = 1 // we 1 tag in - err = mapToXmlIndent(true, s, et, vv, p) - *s += "\n" - } - default: - p.start = 0 // in case trailing p.start = 1 - err = mapToXmlIndent(true, s, et, vv, p) - } - if err != nil { - break - } - } - ss += *s + "" - b = []byte(ss) - case map[string]interface{}: - m := Map(v.(map[string]interface{})) - b, err = m.XmlIndent(prefix, indent, rt) - default: - err = mapToXmlIndent(true, s, rt, v, p) - b = []byte(*s) - } - - return b, err -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/anyxml_test.go b/Godeps/_workspace/src/github.com/clbanning/mxj/anyxml_test.go deleted file mode 100644 index df7228286..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/anyxml_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package mxj - -import ( - "encoding/json" - "fmt" - "testing" -) - -func TestAnyXmlHeader(t *testing.T) { - fmt.Println("\n---------------- anyxml_test.go ...\n") -} - -var anydata = []byte(`[ - { - "somekey": "somevalue" - }, - { - "somekey": "somevalue" - }, - { - "somekey": "somevalue", - "someotherkey": "someothervalue" - }, - "string", - 3.14159265, - true -]`) - -type MyStruct struct { - Somekey string `xml:"somekey"` - B float32 `xml:"floatval"` -} - -func TestAnyXml(t *testing.T) { - var i interface{} - err := json.Unmarshal(anydata, &i) - if err != nil { - t.Fatal(err) - } - x, err := AnyXml(i) - if err != nil { - t.Fatal(err) - } - fmt.Println("[]->x:", string(x)) - - a := []interface{}{"try", "this", 3.14159265, true} - x, err = AnyXml(a) - if err != nil { - t.Fatal(err) - } - fmt.Println("a->x:", string(x)) - - x, err = AnyXml(a, "myRootTag", "myElementTag") - if err != nil { - t.Fatal(err) - } - fmt.Println("a->x:", string(x)) - - x, err = AnyXml(3.14159625) - if err != nil { - t.Fatal(err) - } - fmt.Println("f->x:", string(x)) - - s := MyStruct{"somevalue", 3.14159625} - x, err = AnyXml(s) - if err != nil { - t.Fatal(err) - } - fmt.Println("s->x:", string(x)) -} - -func TestAnyXmlIndent(t *testing.T) { - var i interface{} - err := json.Unmarshal(anydata, &i) - if err != nil { - t.Fatal(err) - } - x, err := AnyXmlIndent(i, "", " ") - if err != nil { - t.Fatal(err) - } - fmt.Println("[]->x:\n", string(x)) - - a := []interface{}{"try", "this", 3.14159265, true} - x, err = AnyXmlIndent(a, "", " ") - if err != nil { - t.Fatal(err) - } - fmt.Println("a->x:\n", string(x)) - - x, err = AnyXmlIndent(3.14159625, "", " ") - if err != nil { - t.Fatal(err) - } - fmt.Println("f->x:\n", string(x)) - - x, err = AnyXmlIndent(3.14159625, "", " ", "myRootTag", "myElementTag") - if err != nil { - t.Fatal(err) - } - fmt.Println("f->x:\n", string(x)) - - s := MyStruct{"somevalue", 3.14159625} - x, err = AnyXmlIndent(s, "", " ") - if err != nil { - t.Fatal(err) - } - fmt.Println("s->x:\n", string(x)) -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/bulk_test.go b/Godeps/_workspace/src/github.com/clbanning/mxj/bulk_test.go deleted file mode 100644 index bb64f9c00..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/bulk_test.go +++ /dev/null @@ -1,107 +0,0 @@ -// bulk_test.go - uses Handler and Writer functions to process some streams as a demo. - -package mxj - -import ( - "bytes" - "fmt" - "testing" -) - -func TestBulkHeader(t *testing.T) { - fmt.Println("\n---------------- bulk_test.go ...\n") -} - -var jsonWriter = new(bytes.Buffer) -var xmlWriter = new(bytes.Buffer) - -var jsonErrLog = new(bytes.Buffer) -var xmlErrLog = new(bytes.Buffer) - -func TestXmlReader(t *testing.T) { - // create Reader for xmldata - xmlReader := bytes.NewReader(xmldata) - - // read XML from Readerand pass Map value with the raw XML to handler - err := HandleXmlReader(xmlReader, bxmaphandler, bxerrhandler) - if err != nil { - t.Fatal("err:", err.Error()) - } - - // get the JSON - j := make([]byte, jsonWriter.Len()) - _, _ = jsonWriter.Read(j) - - // get the errors - e := make([]byte, xmlErrLog.Len()) - _, _ = xmlErrLog.Read(e) - - // print the input - fmt.Println("XmlReader, xmldata:\n", string(xmldata)) - // print the result - fmt.Println("XmlReader, result :\n", string(j)) - // print the errors - fmt.Println("XmlReader, errors :\n", string(e)) -} - -func bxmaphandler(m Map) bool { - j, err := m.JsonIndent("", " ", true) - if err != nil { - return false - } - - _, _ = jsonWriter.Write(j) - // put in a NL to pretty up printing the Writer - _, _ = jsonWriter.Write([]byte("\n")) - return true -} - -func bxerrhandler(err error) bool { - // write errors to file - _, _ = xmlErrLog.Write([]byte(err.Error())) - _, _ = xmlErrLog.Write([]byte("\n")) // pretty up - return true -} - -func TestJsonReader(t *testing.T) { - jsonReader := bytes.NewReader(jsondata) - - // read all the JSON - err := HandleJsonReader(jsonReader, bjmaphandler, bjerrhandler) - if err != nil { - t.Fatal("err:", err.Error()) - } - - // get the XML - x := make([]byte, xmlWriter.Len()) - _, _ = xmlWriter.Read(x) - - // get the errors - e := make([]byte, jsonErrLog.Len()) - _, _ = jsonErrLog.Read(e) - - // print the input - fmt.Println("JsonReader, jsondata:\n", string(jsondata)) - // print the result - fmt.Println("JsonReader, result :\n", string(x)) - // print the errors - fmt.Println("JsonReader, errors :\n", string(e)) -} - -func bjmaphandler(m Map) bool { - x, err := m.XmlIndent(" ", " ") - if err != nil { - return false - } - _, _ = xmlWriter.Write(x) - // put in a NL to pretty up printing the Writer - _, _ = xmlWriter.Write([]byte("\n")) - return true -} - -func bjerrhandler(err error) bool { - // write errors to file - _, _ = jsonErrLog.Write([]byte(err.Error())) - _, _ = jsonErrLog.Write([]byte("\n")) // pretty up - return true -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/bulkraw_test.go b/Godeps/_workspace/src/github.com/clbanning/mxj/bulkraw_test.go deleted file mode 100644 index 61c61fd5f..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/bulkraw_test.go +++ /dev/null @@ -1,113 +0,0 @@ -// bulk_test.go - uses Handler and Writer functions to process some streams as a demo. - -package mxj - -import ( - "bytes" - "fmt" - "testing" -) - -func TestBulkRawHeader(t *testing.T) { - fmt.Println("\n---------------- bulkraw_test.go ...\n") -} - -// use data from bulk_test.go - -var jsonWriterRaw = new(bytes.Buffer) -var xmlWriterRaw = new(bytes.Buffer) - -var jsonErrLogRaw = new(bytes.Buffer) -var xmlErrLogRaw = new(bytes.Buffer) - -func TestXmlReaderRaw(t *testing.T) { - // create Reader for xmldata - xmlReader := bytes.NewReader(xmldata) - - // read XML from Reader and pass Map value with the raw XML to handler - err := HandleXmlReaderRaw(xmlReader, bxmaphandlerRaw, bxerrhandlerRaw) - if err != nil { - t.Fatal("err:", err.Error()) - } - - // get the JSON - j := make([]byte, jsonWriterRaw.Len()) - _, _ = jsonWriterRaw.Read(j) - - // get the errors - e := make([]byte, xmlErrLogRaw.Len()) - _, _ = xmlErrLogRaw.Read(e) - - // print the input - fmt.Println("XmlReaderRaw, xmldata:\n", string(xmldata)) - // print the result - fmt.Println("XmlReaderRaw, result :\n", string(j)) - // print the errors - fmt.Println("XmlReaderRaw, errors :\n", string(e)) -} - -func bxmaphandlerRaw(m Map, raw []byte) bool { - j, err := m.JsonIndent("", " ", true) - if err != nil { - return false - } - - _, _ = jsonWriterRaw.Write(j) - // put in a NL to pretty up printing the Writer - _, _ = jsonWriterRaw.Write([]byte("\n")) - return true -} - -func bxerrhandlerRaw(err error, raw []byte) bool { - // write errors to file - _, _ = xmlErrLogRaw.Write([]byte(err.Error())) - _, _ = xmlErrLogRaw.Write([]byte("\n")) // pretty up - _, _ = xmlErrLogRaw.Write(raw) - _, _ = xmlErrLogRaw.Write([]byte("\n")) // pretty up - return true -} - -func TestJsonReaderRaw(t *testing.T) { - jsonReader := bytes.NewReader(jsondata) - - // read all the JSON - err := HandleJsonReaderRaw(jsonReader, bjmaphandlerRaw, bjerrhandlerRaw) - if err != nil { - t.Fatal("err:", err.Error()) - } - - // get the XML - x := make([]byte, xmlWriterRaw.Len()) - _, _ = xmlWriterRaw.Read(x) - - // get the errors - e := make([]byte, jsonErrLogRaw.Len()) - _, _ = jsonErrLogRaw.Read(e) - - // print the input - fmt.Println("JsonReaderRaw, jsondata:\n", string(jsondata)) - // print the result - fmt.Println("JsonReaderRaw, result :\n", string(x)) - // print the errors - fmt.Println("JsonReaderRaw, errors :\n", string(e)) -} - -func bjmaphandlerRaw(m Map, raw []byte) bool { - x, err := m.XmlIndent(" ", " ") - if err != nil { - return false - } - _, _ = xmlWriterRaw.Write(x) - // put in a NL to pretty up printing the Writer - _, _ = xmlWriterRaw.Write([]byte("\n")) - return true -} - -func bjerrhandlerRaw(err error, raw []byte) bool { - // write errors to file - _, _ = jsonErrLogRaw.Write([]byte(err.Error())) - _, _ = jsonErrLogRaw.Write([]byte("\n")) // pretty up, Error() from json.Unmarshal !NL - _, _ = jsonErrLogRaw.Write(raw) - _, _ = jsonErrLogRaw.Write([]byte("\n")) // pretty up - return true -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/data_test.go b/Godeps/_workspace/src/github.com/clbanning/mxj/data_test.go deleted file mode 100644 index 357513f66..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/data_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package mxj - -var xmldata = []byte(` - - William H. Gaddis - The Recognitions - One of the seminal American novels of the 20th century. - - - William H. Gaddis - JR - Won the National Book Award. - - - Austin Tappan Wright - Islandia - An example of earlier 20th century American utopian fiction. - - - John Hawkes - The Beetle Leg - A lyrical novel about the construction of Ft. Peck Dam in Montana. - - - - T.E. - Porter - - King's Day - A magical novella. -`) - -var jsondata = []byte(` - {"book":{"author":"William H. Gaddis","review":"One of the great seminal American novels of the 20th century.","title":"The Recognitions"}} -{"book":{"author":"Austin Tappan Wright","review":"An example of earlier 20th century American utopian fiction.","title":"Islandia"}} -{"book":{"author":"John Hawkes","review":"A lyrical novel about the construction of Ft. Peck Dam in Montana.","title":"The Beetle Leg"}} -{"book":{"author":{"first_name":"T.E.","last_name":"Porter"},"review":"A magical novella.","title":"King's Day"}} -{ "here":"we", "put":"in", "an":error }`) diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/doc.go b/Godeps/_workspace/src/github.com/clbanning/mxj/doc.go deleted file mode 100644 index 4db312c6e..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/doc.go +++ /dev/null @@ -1,84 +0,0 @@ -// mxj - A collection of map[string]interface{} and associated XML and JSON utilities. -// Copyright 2012-2014 Charles Banning. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -/* -Marshal/Unmarshal XML to/from JSON and map[string]interface{} values, and extract/modify values from maps by key or key-path, including wildcards. - -mxj supplants the legacy x2j and j2x packages. If you want the old syntax, use mxj/x2j or mxj/j2x packages. - -Note: this library was designed for processing ad hoc anonymous messages. Bulk processing large data sets may be much more efficiently performed using the encoding/xml or encoding/json packages from Go's standard library directly. - -Note: - 2014-08-02: AnyXml() and AnyXmlIndent() will try to marshal arbitrary values to XML. - -SUMMARY - - type Map map[string]interface{} - - Create a Map value, 'm', from any map[string]interface{} value, 'v': - m := Map(v) - - Unmarshal / marshal XML as a Map value, 'm': - m, err := NewMapXml(xmlValue) // unmarshal - xmlValue, err := m.Xml() // marshal - - Unmarshal XML from an io.Reader as a Map value, 'm': - m, err := NewMapReader(xmlReader) // repeated calls, as with an os.File Reader, will process stream - m, raw, err := NewMapReaderRaw(xmlReader) // 'raw' is the raw XML that was decoded - - Marshal Map value, 'm', to an XML Writer (io.Writer): - err := m.XmlWriter(xmlWriter) - raw, err := m.XmlWriterRaw(xmlWriter) // 'raw' is the raw XML that was written on xmlWriter - - Also, for prettified output: - xmlValue, err := m.XmlIndent(prefix, indent, ...) - err := m.XmlIndentWriter(xmlWriter, prefix, indent, ...) - raw, err := m.XmlIndentWriterRaw(xmlWriter, prefix, indent, ...) - - Bulk process XML with error handling (note: handlers must return a boolean value): - err := HandleXmlReader(xmlReader, mapHandler(Map), errHandler(error)) - err := HandleXmlReaderRaw(xmlReader, mapHandler(Map, []byte), errHandler(error, []byte)) - - Converting XML to JSON: see Examples for NewMapXml and HandleXmlReader. - - There are comparable functions and methods for JSON processing. - - Arbitrary structure values can be decoded to / encoded from Map values: - m, err := NewMapStruct(structVal) - err := m.Struct(structPointer) - - To work with XML tag values, JSON or Map key values or structure field values, decode the XML, JSON - or structure to a Map value, 'm', or cast a map[string]interface{} value to a Map value, 'm', then: - paths := m.PathsForKey(key) - path := m.PathForKeyShortest(key) - values, err := m.ValuesForKey(key, subkeys) - values, err := m.ValuesForPath(path, subkeys) // 'path' can be dot-notation with wildcards and indexed arrays. - count, err := m.UpdateValuesForPath(newVal, path, subkeys) - - Get everything at once, irrespective of path depth: - leafnodes := m.LeafNodes() - leafvalues := m.LeafValues() - - A new Map with whatever keys are desired can be created from the current Map and then encoded in XML - or JSON. (Note: keys can use dot-notation. 'oldKey' can also use wildcards and indexed arrays.) - newMap := m.NewMap("oldKey_1:newKey_1", "oldKey_2:newKey_2", ..., "oldKey_N:newKey_N") - newXml := newMap.Xml() // for example - newJson := newMap.Json() // ditto - -XML PARSING CONVENTIONS - - - Attributes are parsed to map[string]interface{} values by prefixing a hyphen, '-', - to the attribute label. (PrependAttrWithHyphen(false) will override this.) - - If the element is a simple element and has attributes, the element value - is given the key '#text' for its map[string]interface{} representation. - -XML ENCODING CONVENTIONS - - - 'nil' Map values, which may represent 'null' JSON values, are encoded as "". - NOTE: the operation is not symmetric as "" elements are decoded as 'tag:""' Map values, - which, then, encode in JSON as '"tag":""' values.. - -*/ -package mxj diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/example_test.go b/Godeps/_workspace/src/github.com/clbanning/mxj/example_test.go deleted file mode 100644 index 81fb28612..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/example_test.go +++ /dev/null @@ -1,344 +0,0 @@ -// note - "// Output:" is a key for "go test" to match function ouput with the lines that follow. -// It is also use by "godoc" to build the Output block of the function / method documentation. -// To skip processing Example* functions, use: go test -run "Test*" -// or make sure example function output matches // Output: documentation EXACTLY. - -package mxj_test - -import ( - "bytes" - "fmt" - "github.com/clbanning/mxj" - "io" -) - -func ExampleHandleXmlReader() { - /* - Bulk processing XML to JSON seems to be a common requirement. - See: bulk_test.go for working example. - Run "go test" in package directory then scroll back to find output. - - The logic is as follows. - - // need somewhere to write the JSON. - var jsonWriter io.Writer - - // probably want to log any errors in reading the XML stream - var xmlErrLogger io.Writer - - // func to handle Map value from XML Reader - func maphandler(m mxj.Map) bool { - // marshal Map as JSON - jsonVal, err := m.Json() - if err != nil { - // log error - return false // stops further processing of XML Reader - } - - // write JSON somewhere - _, err = jsonWriter.Write(jsonVal) - if err != nil { - // log error - return false // stops further processing of XML Reader - } - - // continue - get next XML from Reader - return true - } - - // func to handle error from unmarshaling XML Reader - func errhandler(errVal error) bool { - // log error somewhere - _, err := xmlErrLogger.Write([]byte(errVal.Error())) - if err != nil { - // log error - return false // stops further processing of XML Reader - } - - // continue processing - return true - } - - // func that starts bulk processing of the XML - ... - // set up io.Reader for XML data - perhaps an os.File - ... - err := mxj.HandleXmlReader(xmlReader, maphandler, errhandler) - if err != nil { - // handle error - } - ... - */ -} - -func ExampleHandleXmlReaderRaw() { - /* - See: bulkraw_test.go for working example. - Run "go test" in package directory then scroll back to find output. - - Basic logic for bulk XML to JSON processing is in HandleXmlReader example; - the only major difference is in handler function signatures so they are passed - the raw XML. (Read documentation on NewXmlReader regarding performance.) - */ -} - -func ExampleHandleJsonReader() { - /* - See: bulk_test.go for working example. - Run "go test" in package directory then scroll back to find output. - - Basic logic for bulk JSON to XML processing is similar to that for - bulk XML to JSON processing as outlined in the HandleXmlReader example. - The test case is also a good example. - */ -} - -func ExampleHandleJsonReaderRaw() { - /* - See: bulkraw_test.go for working example. - Run "go test" in package directory then scroll back to find output. - - Basic logic for bulk JSON to XML processing is similar to that for - bulk XML to JSON processing as outlined in the HandleXmlReader example. - The test case is also a good example. - */ -} - -/* -func ExampleNewMapXmlReaderRaw() { - // in an http.Handler - - mapVal, raw, err := mxj.NewMapXmlReader(req.Body) - if err != nil { - // handle error - } - logger.Print(string(*raw)) - // do something with mapVal - -} -*/ - -func ExampleNewMapStruct() { - type str struct { - IntVal int `json:"int"` - StrVal string `json:"str"` - FloatVal float64 `json:"float"` - BoolVal bool `json:"bool"` - private string - } - strVal := str{IntVal: 4, StrVal: "now's the time", FloatVal: 3.14159, BoolVal: true, private: "Skies are blue"} - - mapVal, merr := mxj.NewMapStruct(strVal) - if merr != nil { - // handle error - } - - fmt.Printf("strVal: %#v\n", strVal) - fmt.Printf("mapVal: %#v\n", mapVal) - // Note: example output is conformed to pass "go test". "mxj_test" is example_test.go package name. - - // Output: - // strVal: mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:"Skies are blue"} - // mapVal: mxj.Map{"int":4, "str":"now's the time", "float":3.14159, "bool":true} -} - -func ExampleMap_Struct() { - type str struct { - IntVal int `json:"int"` - StrVal string `json:"str"` - FloatVal float64 `json:"float"` - BoolVal bool `json:"bool"` - private string - } - - mapVal := mxj.Map{"int": 4, "str": "now's the time", "float": 3.14159, "bool": true, "private": "Somewhere over the rainbow"} - - var strVal str - mverr := mapVal.Struct(&strVal) - if mverr != nil { - // handle error - } - - fmt.Printf("mapVal: %#v\n", mapVal) - fmt.Printf("strVal: %#v\n", strVal) - // Note: example output is conformed to pass "go test". "mxj_test" is example_test.go package name. - - // Output: - // mapVal: mxj.Map{"int":4, "str":"now's the time", "float":3.14159, "bool":true, "private":"Somewhere over the rainbow"} - // strVal: mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:""} -} - -func ExampleMap_ValuesForKeyPath() { - // a snippet from examples/gonuts1.go - // How to compensate for irregular tag labels in data. - // Need to extract from an XML stream the values for "netid" and "idnet". - // Solution: use a wildcard path "data.*" to anonymize the "netid" and "idnet" tags. - - var msg1 = []byte(` - - - - no - default:text - default:word - - -`) - - var msg2 = []byte(` - - - - yes - default:text - default:word - - -`) - - // let's create a message stream - buf := new(bytes.Buffer) - // load a couple of messages into it - _, _ = buf.Write(msg1) - _, _ = buf.Write(msg2) - - n := 0 - for { - n++ - // Read the stream as Map values - quit on io.EOF. - // Get the raw XML as well as the Map value. - m, merr := mxj.NewMapXmlReader(buf) - if merr != nil && merr != io.EOF { - // handle error - for demo we just print it and continue - fmt.Printf("msg: %d - merr: %s\n", n, merr.Error()) - continue - } else if merr == io.EOF { - break - } - - // get the values for "netid" or "idnet" key using path == "data.*" - values, _ := m.ValuesForPath("data.*") - fmt.Println("\nmsg:", n, "> path == data.* - got array of values, len:", len(values)) - for i, val := range values { - fmt.Println("ValuesForPath result array member -", i, ":", val) - fmt.Println(" k:v pairs for array member:", i) - for key, val := range val.(map[string]interface{}) { - // You'd probably want to process the value, as appropriate. - // Here we just print it out. - fmt.Println("\t\t", key, ":", val) - } - } - } - // Output: - // msg: 1 > path == data.* - got array of values, len: 1 - // ValuesForPath result array member - 0 : map[disable:no text1:default:text word1:default:word] - // k:v pairs for array member: 0 - // disable : no - // text1 : default:text - // word1 : default:word - // - // msg: 2 > path == data.* - got array of values, len: 1 - // ValuesForPath result array member - 0 : map[disable:yes text1:default:text word1:default:word] - // k:v pairs for array member: 0 - // disable : yes - // text1 : default:text - // word1 : default:word -} - -func ExampleMap_UpdateValuesForPath() { - /* - - var biblioDoc = []byte(` - - - William Gaddis - - - The Recognitions - 1955 - A novel that changed the face of American literature. - - - JR - 1975 - Winner of National Book Award for Fiction. - - - - `) - - ... - m, merr := mxj.NewMapXml(biblioDoc) - if merr != nil { - // handle error - } - - // change 'review' for a book - count, err := m.UpdateValuesForPath("review:National Book Award winner." "*.*.*.*", "title:JR") - if err != nil { - // handle error - } - ... - - // change 'date' value from string type to float64 type - // Note: the following is equivalent to m, merr := NewMapXml(biblioDoc, mxj.Cast). - path := m.PathForKeyShortest("date") - v, err := m.ValuesForPath(path) - if err != nil { - // handle error - } - var total int - for _, vv := range v { - oldVal := "date:" + vv.(string) - newVal := "date:" + vv.(string) + ":num" - n, err := m.UpdateValuesForPath(newVal, path, oldVal) - if err != nil { - // handle error - } - total += n - } - ... - */ -} - -func ExampleMap_Copy() { - // Hand-crafted Map values that include structures do NOT Copy() as expected, - // since to simulate a deep copy the original Map value is JSON encoded then decoded. - - type str struct { - IntVal int `json:"int"` - StrVal string `json:"str"` - FloatVal float64 `json:"float"` - BoolVal bool `json:"bool"` - private string - } - s := str{IntVal: 4, StrVal: "now's the time", FloatVal: 3.14159, BoolVal: true, private: "Skies are blue"} - m := make(map[string]interface{}, 0) - m["struct"] = interface{}(s) - m["struct_ptr"] = interface{}(&s) - m["misc"] = interface{}(`Now is the time`) - - mv := mxj.Map(m) - cp, _ := mv.Copy() - - fmt.Printf("mv:%s\n", mv.StringIndent(2)) - fmt.Printf("cp:%s\n", cp.StringIndent(2)) - - // Output: - // mv: - // struct :[unknown] mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:"Skies are blue"} - // struct_ptr :[unknown] &mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:"Skies are blue"} - // misc :[string] Now is the time - // cp: - // misc :[string] Now is the time - // struct : - // int :[float64] 4.00e+00 - // str :[string] now's the time - // float :[float64] 3.14e+00 - // bool :[bool] true - // struct_ptr : - // int :[float64] 4.00e+00 - // str :[string] now's the time - // float :[float64] 3.14e+00 - // bool :[bool] true -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/README b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/README deleted file mode 100644 index e14580f7b..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/README +++ /dev/null @@ -1,124 +0,0 @@ -Examples of using ValuesFromTagPath(). - -A number of interesting examples have shown up in the gonuts discussion group -that could be handled - after a fashion - using the ValuesFromTagPath() function. - -gonuts1.go - - -Here we see that the message stream has a problem with multiple tag spellings, -though the message structure remains constant. In this example we 'anonymize' -the tag for the variant spellings. - values := m.ValuesForPath("data.*) - where '*' is any possible spelling - "netid" or "idnet" - and the result is a list with 1 member of map[string]interface{} type. - -Once we've retrieved the Map, we can parse it using the known keys - "disable", -"text1" and "word1". - - -gonuts1a.go - (03-mar-14) - -Here we just permute the tag labels using m.NewMap() to make all the messages -consistent. Then they can be decoded into a single structure definition. - - -gonuts2.go - - -This is an interesting case where there was a need to handle messages with lists -of "ClaimStatusCodeRecord" entries as well as messages with NONE. (Here we see -some of the vagaries of dealing with mixed messages that are verging on becoming -anonymous.) - - msg1 - the message with two ClaimStatusCodeRecord entries - msg2 - the message with one ClaimStatusCodeRecord entry - msg3 - the message with NO ClaimStatusCodeRecord entries - -ValuesForPath options: - - path == "Envelope.Body.GetClaimStatusCodesResponse.GetClaimStatusCodesResult.ClaimStatusCodeRecord" - for msg == msg1: - returns: a list - []interface{} - with two values of map[string]interface{} type - for msg == msg2: - returns: a list - []interface{} - with one map[string]interface{} type - for msg == msg3: - returns 'nil' - no values - - path == "*.*.*.*.*" - for msg == msg1: - returns: a list - []interface{} - with two values of map[string]interface{} type - - path == "*.*.*.*.*.Description - for msg == msg1: - returns: a list - []interface{} - with two values of string type, the individual - values from parsing the two map[string]interface{} values where key=="Description" - - path == "*.*.*.*.*.*" - for msg == msg1: - returns: a list - []interface{} - with six values of string type, the individual - values from parsing all keys in the two map[string]interface{} values - -Think of the wildcard character "*" as anonymizing the tag in the position of the path where -it occurs. The books.go example has a range of use cases. - - -gonuts3.go - - -Uses the ValuesForKey method to extract a list of image "src" file names that are encoded as -attribute values. - - -gonuts4.go - - -Here we use the ValuesForPath to extract attribute values for country names. The attribute -is included in the 'path' argument by prepending it with a hyphen: ""doc.some_tag.geoInfo.country.-name". - - -gonuts5.go (10-mar-14) - - -Extract a node of values using ValuesForPath based on name="list3-1-1-1". Then get the values -for the 'int' entries based on attribute 'name' values - mv.ValuesForKey("int", "-name:"+n). - -gonuts5a.go (10-mar-14) - - -Extract a node of values using ValuesForPath based on name="list3-1-1-1". Then get the values -for the 'int' entries based on attribute 'name' values - mv.ValuesForKey("*", "-name:"+n). -(Same as gonuts5.go but with wildcarded key value, since we're matching elements on subkey.) - - -EAT YOUR OWN DOG FOOD ... - -I needed to convert a large (14.9 MB) XML data set from an Eclipse metrics report on an -application that had 355,100 lines of code in 211 packages into CSV data sets. The report -included application-, package-, class- and method-level metrics reported in an element, -"Value", with varying attributes. - - - - - -In addition, the metrics were reported with two different "Metric" compound elements: - - - - - ... - - - ... - - - - ... - - -Using the mxj package seemed a more straightforward approach than using Go vernacular -and the standard xml package. I wrote the program getmetrics.go to do this. Here are -three version to illustrate using - getmetrics1.go - pass os.File handle for metrics_data.xml to NewMapXmlReader. - getmetrics2.go - load metrics_data.xml into an in-memory buffer, then pass it to NewMapXml. - getmetrics3.go - demonstrates overhead of extracting the raw XML while decoding with NewMapXmlReaderRaw. - -To run example getmetrics1.go, extract a 120,000+ row data set from metrics_data.zip. Then: - go run getmetrics1.go -file=metrics_data.xml - - diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/books.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/books.go deleted file mode 100644 index e703d8395..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/books.go +++ /dev/null @@ -1,71 +0,0 @@ -// Note: this illustrates ValuesForKey() and ValuesForPath() methods - -package main - -import ( - "fmt" - "github.com/clbanning/mxj" - "log" -) - -var xmldata = []byte(` - - - William H. Gaddis - The Recognitions - One of the great seminal American novels of the 20th century. - - - Austin Tappan Wright - Islandia - An example of earlier 20th century American utopian fiction. - - - John Hawkes - The Beetle Leg - A lyrical novel about the construction of Ft. Peck Dam in Montana. - - - T.E. Porter - King's Day - A magical novella. - - -`) - -func main() { - fmt.Println(string(xmldata)) - - m, err := mxj.NewMapXml(xmldata) - if err != nil { - log.Fatal("err:", err.Error()) - } - - v, _ := m.ValuesForKey("books") - fmt.Println("path: books; len(v):", len(v)) - fmt.Printf("\t%+v\n", v) - - v, _ = m.ValuesForPath("books.book") - fmt.Println("path: books.book; len(v):", len(v)) - for _, vv := range v { - fmt.Printf("\t%+v\n", vv) - } - - v, _ = m.ValuesForPath("books.*") - fmt.Println("path: books.*; len(v):", len(v)) - for _, vv := range v { - fmt.Printf("\t%+v\n", vv) - } - - v, _ = m.ValuesForPath("books.*.title") - fmt.Println("path: books.*.title len(v):", len(v)) - for _, vv := range v { - fmt.Printf("\t%+v\n", vv) - } - - v, _ = m.ValuesForPath("books.*.*") - fmt.Println("path: books.*.*; len(v):", len(v)) - for _, vv := range v { - fmt.Printf("\t%+v\n", vv) - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics1.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics1.go deleted file mode 100644 index c4e680382..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics1.go +++ /dev/null @@ -1,176 +0,0 @@ -// getmetrics1.go - transform Eclipse Metrics (v3) XML report into CSV files for each metric -// Uses NewMapXmlReader on os.File without copying the raw XML into a buffer while decoding.. -// Shows no significant overhead for not first buffering large XML file as in getmetrics2.go. - -/* -I needed to convert a large (14.9 MB) XML data set from an Eclipse metrics report on an -application that had 355,100 lines of code in 211 packages into CSV data sets. The report -included application-, package-, class- and method-level metrics reported in an element, -"Value", with varying attributes. - - - - - -In addition, the metrics were reported with two different "Metric" compound elements: - - - - - ... - - - ... - - - - ... - - -To run this example, extract the metrics_data.xml file from metrics_data.zip, then: - > go run getmetrics1 -file=metrics_data.xml - -The output will be a set of "csv" files. -*/ - -package main - -import ( - "flag" - "fmt" - "github.com/clbanning/mxj" - "log" - "os" - "time" -) - -func main() { - var file string - flag.StringVar(&file, "file", "", "file to process") - flag.Parse() - - fh, fherr := os.Open(file) - if fherr != nil { - fmt.Println("fherr:", fherr.Error()) - return - } - defer fh.Close() - fmt.Println(time.Now().String(), "... File Opened:", file) - - /* - // Get the XML data set from the file. - fs, _ := fh.Stat() - xmldata := make([]byte, fs.Size()) - n, frerr := fh.Read(xmldata) - if frerr != nil { - fmt.Println("frerr:", frerr.Error()) - return - } - if int64(n) != fs.Size() { - fmt.Println("n:", n, "fs.Size():", fs.Size()) - return - } - fmt.Println(time.Now().String(), "... File Read - size:", fs.Size()) - - // load XML into a Map value - m, merr := mxj.NewMapXml(xmldata) - */ - // Consume the file using os.File Reader. - // Note: there is a single record with root tag of "Metrics". - m, merr := mxj.NewMapXmlReader(fh) - if merr != nil { - log.Fatal("merr:", merr.Error()) - } - fmt.Println(time.Now().String(), "... XML Unmarshaled - len:", len(m)) - - // Get just the key values of interest. - // Could also use m.ValuesForKey("Metric"), - // since there's just the one path. - metricVals, err := m.ValuesForPath("Metrics.Metric") - if err != nil { - log.Fatal("err:", err.Error()) - } - fmt.Println(time.Now().String(), "... ValuesFromKeyPath - len:", len(metricVals)) - - // now just manipulate Map entries returned as []interface{} array. - for _, v := range metricVals { - aMetricVal := v.(map[string]interface{}) - - // create file to hold csv data sets - id := aMetricVal["-id"].(string) - desc := aMetricVal["-description"].(string) - mf, mferr := os.OpenFile(id+".csv", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666) - if mferr != nil { - fmt.Println("mferr:", mferr.Error()) - return - } - - fmt.Print(time.Now().String(), " id: ", id, " desc: ", desc) - mf.WriteString(id + "," + desc + "\n") - - // rescan looking for keys with data: Values or Value - for key, val := range aMetricVal { - switch key { - case "Values": - // extract the list of "Value" from map - values := val.(map[string]interface{})["Value"].([]interface{}) - fmt.Println(" len(Values):", len(values)) - - // first line in file is the metric label values (keys) - var gotKeys bool - for _, vval := range values { - valueEntry := vval.(map[string]interface{}) - - // no guarantee that range on map will follow any sequence - lv := len(valueEntry) - type ev [2]string - list := make([]ev, lv) - var i int - for k, v := range valueEntry { - list[i][0] = k - list[i][1] = v.(string) - i++ - } - - // extract keys as column header on first pass - if !gotKeys { - // print out the keys - var gotFirstKey bool - // for kk, _ := range valueEntry { - for i := 0; i < lv; i++ { - if gotFirstKey { - mf.WriteString(",") - } else { - gotFirstKey = true - } - // strip prepended hyphen - mf.WriteString((list[i][0])[1:]) - } - mf.WriteString("\n") - gotKeys = true - } - - // print out values - var gotFirstVal bool - // for _, vv := range valueEntry { - for i := 0; i < lv; i++ { - if gotFirstVal { - mf.WriteString(",") - } else { - gotFirstVal = true - } - mf.WriteString(list[i][1]) - } - - // terminate row of data - mf.WriteString("\n") - } - case "Value": - vv := val.(map[string]interface{}) - fmt.Println(" len(Value):", len(vv)) - mf.WriteString("value\n" + vv["-value"].(string) + "\n") - } - } - mf.Close() - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics2.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics2.go deleted file mode 100644 index 65d6c9513..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics2.go +++ /dev/null @@ -1,173 +0,0 @@ -// getmetrics2.go - transform Eclipse Metrics (v3) XML report into CSV files for each metric -// Uses an in-memory buffer for the XML data and direct XML decoding of the buffer into a Map. -// Not significantly faster than getmetrics1.go that uses an io.Reader (os.File) to directly -// decode the XML from the file. - -/* -I needed to convert a large (14.9 MB) XML data set from an Eclipse metrics report on an -application that had 355,100 lines of code in 211 packages into CSV data sets. The report -included application-, package-, class- and method-level metrics reported in an element, -"Value", with varying attributes. - - - - - -In addition, the metrics were reported with two different "Metric" compound elements: - - - - - ... - - - ... - - - - ... - - -To run this example, extract the metrics_data.xml file from metrics_data.zip, then: - > go run getmetrics -file=metrics_data.xml - -The output will be a set of "csv" files. -*/ - -package main - -import ( - "flag" - "fmt" - "github.com/clbanning/mxj" - "log" - "os" - "time" -) - -func main() { - var file string - flag.StringVar(&file, "file", "", "file to process") - flag.Parse() - - fh, fherr := os.Open(file) - if fherr != nil { - fmt.Println("fherr:", fherr.Error()) - return - } - defer fh.Close() - fmt.Println(time.Now().String(), "... File Opened:", file) - - // Get the XML data set from the file. - fs, _ := fh.Stat() - xmldata := make([]byte, fs.Size()) - n, frerr := fh.Read(xmldata) - if frerr != nil { - fmt.Println("frerr:", frerr.Error()) - return - } - if int64(n) != fs.Size() { - fmt.Println("n:", n, "fs.Size():", fs.Size()) - return - } - fmt.Println(time.Now().String(), "... File Read - size:", fs.Size()) - - // load XML into a Map value - // Note: there is a single record with root tag of "Metrics". - m, merr := mxj.NewMapXml(xmldata) - if merr != nil { - log.Fatal("merr:", merr.Error()) - } - fmt.Println(time.Now().String(), "... XML Unmarshaled - len:", len(m)) - - // Get just the key values of interest. - // Could also use m.ValuesForKey("Metric"), - // since there's just the one path. - metricVals, err := m.ValuesForPath("Metrics.Metric") - if err != nil { - log.Fatal("err:", err.Error()) - } - fmt.Println(time.Now().String(), "... ValuesFromKeyPath - len:", len(metricVals)) - - // now just manipulate Map entries returned as []interface{} array. - for _, v := range metricVals { - aMetricVal := v.(map[string]interface{}) - - // create file to hold csv data sets - id := aMetricVal["-id"].(string) - desc := aMetricVal["-description"].(string) - mf, mferr := os.OpenFile(id+".csv", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666) - if mferr != nil { - fmt.Println("mferr:", mferr.Error()) - return - } - - fmt.Print(time.Now().String(), " id: ", id, " desc: ", desc) - mf.WriteString(id + "," + desc + "\n") - - // rescan looking for keys with data: Values or Value - for key, val := range aMetricVal { - switch key { - case "Values": - // extract the list of "Value" from map - values := val.(map[string]interface{})["Value"].([]interface{}) - fmt.Println(" len(Values):", len(values)) - - // first line in file is the metric label values (keys) - var gotKeys bool - for _, vval := range values { - valueEntry := vval.(map[string]interface{}) - - // no guarantee that range on map will follow any sequence - lv := len(valueEntry) - type ev [2]string - list := make([]ev, lv) - var i int - for k, v := range valueEntry { - list[i][0] = k - list[i][1] = v.(string) - i++ - } - - // extract keys as column header on first pass - if !gotKeys { - // print out the keys - var gotFirstKey bool - // for kk, _ := range valueEntry { - for i := 0; i < lv; i++ { - if gotFirstKey { - mf.WriteString(",") - } else { - gotFirstKey = true - } - // strip prepended hyphen - mf.WriteString((list[i][0])[1:]) - } - mf.WriteString("\n") - gotKeys = true - } - - // print out values - var gotFirstVal bool - // for _, vv := range valueEntry { - for i := 0; i < lv; i++ { - if gotFirstVal { - mf.WriteString(",") - } else { - gotFirstVal = true - } - mf.WriteString(list[i][1]) - } - - // terminate row of data - mf.WriteString("\n") - } - case "Value": - vv := val.(map[string]interface{}) - fmt.Println(" len(Value):", len(vv)) - mf.WriteString("value\n" + vv["-value"].(string) + "\n") - } - } - mf.Close() - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics3.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics3.go deleted file mode 100644 index a914d5491..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics3.go +++ /dev/null @@ -1,180 +0,0 @@ -// getmetrics3.go - transform Eclipse Metrics (v3) XML report into CSV files for each metric -// Uses NewMapXmlReaderRaw that requires loading raw XML into a []byte buffer using a ByteReader. -// Show's performance impact of copying the raw XML while simultaneously decoding it from on os.File -// Reader. (vs. getmetrics1.go) If you're processing a file and need a copy of the raw XML and SPEED, -// should buffer the file in memory and decode using mxj.NewMapXmlReaderRaw as in getmetrics4.go. - -/* -I needed to convert a large (14.9 MB) XML data set from an Eclipse metrics report on an -application that had 355,100 lines of code in 211 packages into CSV data sets. The report -included application-, package-, class- and method-level metrics reported in an element, -"Value", with varying attributes. - - - - - -In addition, the metrics were reported with two different "Metric" compound elements: - - - - - ... - - - ... - - - - ... - - -To run this example, extract the metrics_data.xml file from metrics_data.zip, then: - > go run getmetrics3 -file=metrics_data.xml - -The output will be a set of "csv" files. -*/ - -package main - -import ( - "flag" - "fmt" - "github.com/clbanning/mxj" - "log" - "os" - "time" -) - -func main() { - var file string - flag.StringVar(&file, "file", "", "file to process") - flag.Parse() - - fh, fherr := os.Open(file) - if fherr != nil { - fmt.Println("fherr:", fherr.Error()) - return - } - defer fh.Close() - fmt.Println(time.Now().String(), "... File Opened:", file) - - /* - // Get the XML data set from the file. - fs, _ := fh.Stat() - xmldata := make([]byte, fs.Size()) - n, frerr := fh.Read(xmldata) - if frerr != nil { - fmt.Println("frerr:", frerr.Error()) - return - } - if int64(n) != fs.Size() { - fmt.Println("n:", n, "fs.Size():", fs.Size()) - return - } - fmt.Println(time.Now().String(), "... File Read - size:", fs.Size()) - - // load XML into a Map value - m, merr := mxj.NewMapXml(xmldata) - */ - // Consume the file using os.File Reader. - // Note: there is a single record with root tag of "Metrics". - // Also: this is MUCH slower than using buffer or not loading raw XML. - m, raw, merr := mxj.NewMapXmlReaderRaw(fh) - if merr != nil { - log.Fatal("merr:", merr.Error()) - } - fmt.Println(time.Now().String(), "... XML Unmarshaled - len:", len(m)) - fmt.Println("raw XML buffer size (should be same as File size):", len(*raw)) - - // Get just the key values of interest. - // Could also use m.ValuesForKey("Metric"), - // since there's just the one path. - metricVals, err := m.ValuesForPath("Metrics.Metric") - if err != nil { - log.Fatal("err:", err.Error()) - } - fmt.Println(time.Now().String(), "... ValuesFromKeyPath - len:", len(metricVals)) - - // now just manipulate Map entries returned as []interface{} array. - for _, v := range metricVals { - aMetricVal := v.(map[string]interface{}) - - // create file to hold csv data sets - id := aMetricVal["-id"].(string) - desc := aMetricVal["-description"].(string) - mf, mferr := os.OpenFile(id+".csv", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666) - if mferr != nil { - fmt.Println("mferr:", mferr.Error()) - return - } - - fmt.Print(time.Now().String(), " id: ", id, " desc: ", desc) - mf.WriteString(id + "," + desc + "\n") - - // rescan looking for keys with data: Values or Value - for key, val := range aMetricVal { - switch key { - case "Values": - // extract the list of "Value" from map - values := val.(map[string]interface{})["Value"].([]interface{}) - fmt.Println(" len(Values):", len(values)) - - // first line in file is the metric label values (keys) - var gotKeys bool - for _, vval := range values { - valueEntry := vval.(map[string]interface{}) - - // no guarantee that range on map will follow any sequence - lv := len(valueEntry) - type ev [2]string - list := make([]ev, lv) - var i int - for k, v := range valueEntry { - list[i][0] = k - list[i][1] = v.(string) - i++ - } - - // extract keys as column header on first pass - if !gotKeys { - // print out the keys - var gotFirstKey bool - // for kk, _ := range valueEntry { - for i := 0; i < lv; i++ { - if gotFirstKey { - mf.WriteString(",") - } else { - gotFirstKey = true - } - // strip prepended hyphen - mf.WriteString((list[i][0])[1:]) - } - mf.WriteString("\n") - gotKeys = true - } - - // print out values - var gotFirstVal bool - // for _, vv := range valueEntry { - for i := 0; i < lv; i++ { - if gotFirstVal { - mf.WriteString(",") - } else { - gotFirstVal = true - } - mf.WriteString(list[i][1]) - } - - // terminate row of data - mf.WriteString("\n") - } - case "Value": - vv := val.(map[string]interface{}) - fmt.Println(" len(Value):", len(vv)) - mf.WriteString("value\n" + vv["-value"].(string) + "\n") - } - } - mf.Close() - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics4.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics4.go deleted file mode 100644 index 2cf663817..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/getmetrics4.go +++ /dev/null @@ -1,179 +0,0 @@ -// getmetrics2.go - transform Eclipse Metrics (v3) XML report into CSV files for each metric -// Uses an in-memory buffer for the XML data and direct XML decoding of the buffer into a Map. -// Then XML buffer is decoded into a Map while the raw XML is copied using NewMapXmlReaderRaw() -// to illustrate processing overhead relative to getmetrics2.go. Not a practical example, -// but confirms the getmetrics1.go vs. getmetrics3.go use case. - -/* -I needed to convert a large (14.9 MB) XML data set from an Eclipse metrics report on an -application that had 355,100 lines of code in 211 packages into CSV data sets. The report -included application-, package-, class- and method-level metrics reported in an element, -"Value", with varying attributes. - - - - - -In addition, the metrics were reported with two different "Metric" compound elements: - - - - - ... - - - ... - - - - ... - - -To run this example, extract the metrics_data.xml file from metrics_data.zip, then: - > go run getmetrics -file=metrics_data.xml - -The output will be a set of "csv" files. -*/ - -package main - -import ( - "bytes" - "flag" - "fmt" - "github.com/clbanning/mxj" - "log" - "os" - "time" -) - -func main() { - var file string - flag.StringVar(&file, "file", "", "file to process") - flag.Parse() - - fh, fherr := os.Open(file) - if fherr != nil { - fmt.Println("fherr:", fherr.Error()) - return - } - defer fh.Close() - fmt.Println(time.Now().String(), "... File Opened:", file) - - // Get the XML data set from the file. - fs, _ := fh.Stat() - xmldata := make([]byte, fs.Size()) - n, frerr := fh.Read(xmldata) - if frerr != nil { - fmt.Println("frerr:", frerr.Error()) - return - } - if int64(n) != fs.Size() { - fmt.Println("n:", n, "fs.Size():", fs.Size()) - return - } - fmt.Println(time.Now().String(), "... File Read - size:", fs.Size()) - - // wrap the buffer in an io.Reader - xmlReader := bytes.NewBuffer(xmldata) - - // load XML into a Map value - // Note: there is a single record with root tag of "Metrics". - m, raw, merr := mxj.NewMapXmlReaderRaw(xmlReader) // don't catch the pointer to raw XML - if merr != nil { - log.Fatal("merr:", merr.Error()) - } - fmt.Println(time.Now().String(), "... XML Unmarshaled - len:", len(m)) - fmt.Println("raw XML buffer size (should be same as File size):", len(*raw)) - - // Get just the key values of interest. - // Could also use m.ValuesForKey("Metric"), - // since there's just the one path. - metricVals, err := m.ValuesForPath("Metrics.Metric") - if err != nil { - log.Fatal("err:", err.Error()) - } - fmt.Println(time.Now().String(), "... ValuesFromKeyPath - len:", len(metricVals)) - - // now just manipulate Map entries returned as []interface{} array. - for _, v := range metricVals { - aMetricVal := v.(map[string]interface{}) - - // create file to hold csv data sets - id := aMetricVal["-id"].(string) - desc := aMetricVal["-description"].(string) - mf, mferr := os.OpenFile(id+".csv", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666) - if mferr != nil { - fmt.Println("mferr:", mferr.Error()) - return - } - - fmt.Print(time.Now().String(), " id: ", id, " desc: ", desc) - mf.WriteString(id + "," + desc + "\n") - - // rescan looking for keys with data: Values or Value - for key, val := range aMetricVal { - switch key { - case "Values": - // extract the list of "Value" from map - values := val.(map[string]interface{})["Value"].([]interface{}) - fmt.Println(" len(Values):", len(values)) - - // first line in file is the metric label values (keys) - var gotKeys bool - for _, vval := range values { - valueEntry := vval.(map[string]interface{}) - - // no guarantee that range on map will follow any sequence - lv := len(valueEntry) - type ev [2]string - list := make([]ev, lv) - var i int - for k, v := range valueEntry { - list[i][0] = k - list[i][1] = v.(string) - i++ - } - - // extract keys as column header on first pass - if !gotKeys { - // print out the keys - var gotFirstKey bool - // for kk, _ := range valueEntry { - for i := 0; i < lv; i++ { - if gotFirstKey { - mf.WriteString(",") - } else { - gotFirstKey = true - } - // strip prepended hyphen - mf.WriteString((list[i][0])[1:]) - } - mf.WriteString("\n") - gotKeys = true - } - - // print out values - var gotFirstVal bool - // for _, vv := range valueEntry { - for i := 0; i < lv; i++ { - if gotFirstVal { - mf.WriteString(",") - } else { - gotFirstVal = true - } - mf.WriteString(list[i][1]) - } - - // terminate row of data - mf.WriteString("\n") - } - case "Value": - vv := val.(map[string]interface{}) - fmt.Println(" len(Value):", len(vv)) - mf.WriteString("value\n" + vv["-value"].(string) + "\n") - } - } - mf.Close() - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts1.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts1.go deleted file mode 100644 index a0c5d6fce..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts1.go +++ /dev/null @@ -1,82 +0,0 @@ -// https://groups.google.com/forum/#!searchin/golang-nuts/idnet$20netid/golang-nuts/guM3ZHHqSF0/K1pBpMqQSSwJ -// http://play.golang.org/p/BFFDxphKYK - -package main - -import ( - "bytes" - "fmt" - "github.com/clbanning/mxj" - "io" -) - -// Demo how to compensate for irregular tag labels in data. -// Need to extract from an XML stream the values for "netid" and "idnet". -// Solution: use a wildcard path "data.*" to anonymize the "netid" and "idnet" tags. - -var msg1 = []byte(` - - - - no - default:text - default:word - - -`) - -var msg2 = []byte(` - - - - yes - default:text - default:word - - -`) - -func main() { - // let's create a message stream - buf := new(bytes.Buffer) - // load a couple of messages into it - _, _ = buf.Write(msg1) - _, _ = buf.Write(msg2) - - n := 0 - for { - n++ - // read the stream as Map values - quit on io.EOF - m, raw, merr := mxj.NewMapXmlReaderRaw(buf) - if merr != nil && merr != io.EOF { - // handle error - for demo we just print it and continue - fmt.Printf("msg: %d - merr: %s\n", n, merr.Error()) - continue - } else if merr == io.EOF { - break - } - fmt.Println("\nMessage to parse:", string(*raw)) - fmt.Println("Map value for XML message:", m.StringIndent()) - - // get the values for "netid" or "idnet" key using path == "data.*" - values, _ := m.ValuesForPath("data.*") - fmt.Println("\nmsg:", n, "> path == data.* - got array of values, len:", len(values)) - for i, val := range values { - fmt.Println("ValuesForPath result array member -", i, ":", val) - fmt.Println(" k:v pairs for array member:", i) - for key, val := range val.(map[string]interface{}) { - // You'd probably want to process the value, as appropriate. - // Here we just print it out. - fmt.Println("\t\t", key, ":", val) - } - } - - // This shows what happens if you wildcard the value keys for "idnet" and "netid" - values, _ = m.ValuesForPath("data.*.*") - fmt.Println("\npath == data.*.* - got an array of values, len(v):", len(values)) - fmt.Println("(Note: values returned by ValuesForPath are at maximum depth of the tree. So just have values.)") - for i, val := range values { - fmt.Println("ValuesForPath array member -", i, ":", val) - } - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts1a.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts1a.go deleted file mode 100644 index fbe58ffad..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts1a.go +++ /dev/null @@ -1,68 +0,0 @@ -// https://groups.google.com/forum/#!searchin/golang-nuts/idnet$20netid/golang-nuts/guM3ZHHqSF0/K1pBpMqQSSwJ -// http://play.golang.org/p/BFFDxphKYK - -package main - -import ( - "bytes" - "fmt" - "github.com/clbanning/mxj" - "io" -) - -// Demo how to re-label a key using mv.NewMap(). -// Need to normalize from an XML stream the tags "netid" and "idnet". -// Solution: make everything "netid". - -var msg1 = []byte(` - - - - no - default:text - default:word - - -`) - -var msg2 = []byte(` - - - - yes - default:text - default:word - - -`) - -func main() { - // let's create a message stream - buf := new(bytes.Buffer) - // load a couple of messages into it - _, _ = buf.Write(msg1) - _, _ = buf.Write(msg2) - - n := 0 - for { - n++ - // read the stream as Map values - quit on io.EOF - m, raw, merr := mxj.NewMapXmlReaderRaw(buf) - if merr != nil && merr != io.EOF { - // handle error - for demo we just print it and continue - fmt.Printf("msg: %d - merr: %s\n", n, merr.Error()) - continue - } else if merr == io.EOF { - break - } - - // the first keypair retains values if data correct - // the second keypair relabels "idnet" to "netid" - n, _ := m.NewMap("data.netid", "data.idnet:data.netid") - x, _ := n.XmlIndent("", " ") - - fmt.Println("original value:", string(raw)) - fmt.Println("new value:") - fmt.Println(string(x)) - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts2.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts2.go deleted file mode 100644 index 6bd0bab73..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts2.go +++ /dev/null @@ -1,240 +0,0 @@ -// https://groups.google.com/forum/#!topic/golang-nuts/V83jUKluLnM -// http://play.golang.org/p/alWGk4MDBc - -// Here messsages come in one of three forms: -// ... list of ClaimStatusCodeRecord ... -// ... one instance of ClaimStatusCodeRecord ... -// ... empty element ... -// ValueForPath - -package main - -import ( - "fmt" - "github.com/clbanning/mxj" -) - -var xmlmsg1 = []byte(` - - - - -true -A -Initial Claim Review/Screening - - -true -B -Initial Contact Made w/ Provider - - - - - -`) - -var xmlmsg2 = []byte(` - - - - -true -A -Initial Claim Review/Screening - - - - - -`) - -var xmlmsg3 = []byte(` - - - - - - - -`) - -func main() { - xmldata := [][]byte{xmlmsg1, xmlmsg2, xmlmsg3} - fullPath(xmldata) - partPath1(xmlmsg1) - partPath2(xmlmsg1) - partPath3(xmlmsg1) - partPath4(xmlmsg1) - partPath5(xmlmsg1) - partPath6(xmlmsg1) -} - -func fullPath(xmldata [][]byte) { - for i, msg := range xmldata { - fmt.Println("\ndoc:", i) - fmt.Println(string(msg)) - // decode the XML - m, _ := mxj.NewMapXml(msg) - - // get the value for the key path of interest - path := "Envelope.Body.GetClaimStatusCodesResponse.GetClaimStatusCodesResult.ClaimStatusCodeRecord" - values, err := m.ValueForPath(path) - if err != nil { - fmt.Println("err:", err.Error()) - return - } - if values == nil { - fmt.Println("path:", path) - fmt.Println("No ClaimStatusCodesResult code records.") - continue - } - fmt.Println("\nPath:", path) - fmt.Println("Number of code records:", len(values)) - fmt.Println("values:", values, "\n") - for _, v := range values { - switch v.(type) { - case map[string]interface{}: - fmt.Println("map[string]interface{}:", v.(map[string]interface{})) - case []map[string]interface{}: - fmt.Println("[]map[string]interface{}:", v.([]map[string]interface{})) - case []interface{}: - fmt.Println("[]interface{}:", v.([]interface{})) - case interface{}: - fmt.Println("interface{}:", v.(interface{})) - } - } - } -} - -func partPath1(msg []byte) { - fmt.Println("\nmsg:", string(msg)) - m, _ := mxj.NewMapXml(msg) - fmt.Println("m:", m.StringIndent()) - path := "Envelope.Body.*.*.ClaimStatusCodeRecord" - values, err := m.ValueForPath(path) - if err != nil { - fmt.Println("err:", err.Error()) - return - } - if values == nil { - fmt.Println("path:", path) - fmt.Println("No ClaimStatusCodesResult code records.") - return - } - fmt.Println("\nPath:", path) - fmt.Println("Number of code records:", len(values)) - for n, v := range values { - fmt.Printf("\t#%d: %v\n", n, v) - } -} - -func partPath2(msg []byte) { - fmt.Println("\nmsg:", string(msg)) - m, _ := mxj.NewMapXml(msg) - fmt.Println("m:", m.StringIndent()) - path := "Envelope.Body.*.*.*" - values, err := m.ValueForPath(path) - if err != nil { - fmt.Println("err:", err.Error()) - return - } - if values == nil { - fmt.Println("path:", path) - fmt.Println("No ClaimStatusCodesResult code records.") - return - } - fmt.Println("\nPath:", path) - fmt.Println("Number of code records:", len(values)) - for n, v := range values { - fmt.Printf("\t#%d: %v\n", n, v) - } -} - -func partPath3(msg []byte) { - fmt.Println("\nmsg:", string(msg)) - m, _ := mxj.NewMapXml(msg) - fmt.Println("m:", m.StringIndent()) - path := "*.*.*.*.*" - values, err := m.ValueForPath(path) - if err != nil { - fmt.Println("err:", err.Error()) - return - } - if values == nil { - fmt.Println("path:", path) - fmt.Println("No ClaimStatusCodesResult code records.") - return - } - fmt.Println("\nPath:", path) - fmt.Println("Number of code records:", len(values)) - for n, v := range values { - fmt.Printf("\t#%d: %v\n", n, v) - } -} - -func partPath4(msg []byte) { - fmt.Println("\nmsg:", string(msg)) - m, _ := mxj.NewMapXml(msg) - fmt.Println("m:", m.StringIndent()) - path := "*.*.*.*.*.Description" - values, err := m.ValueForPath(path) - if err != nil { - fmt.Println("err:", err.Error()) - return - } - if values == nil { - fmt.Println("path:", path) - fmt.Println("No ClaimStatusCodesResult code records.") - return - } - fmt.Println("\nPath:", path) - fmt.Println("Number of code records:", len(values)) - for n, v := range values { - fmt.Printf("\t#%d: %v\n", n, v) - } -} - -func partPath5(msg []byte) { - fmt.Println("\nmsg:", string(msg)) - m, _ := mxj.NewMapXml(msg) - fmt.Println("m:", m.StringIndent()) - path := "*.*.*.*.*.*" - values, err := m.ValueForPath(path) - if err != nil { - fmt.Println("err:", err.Error()) - return - } - if values == nil { - fmt.Println("path:", path) - fmt.Println("No ClaimStatusCodesResult code records.") - return - } - fmt.Println("\nPath:", path) - fmt.Println("Number of code records:", len(values)) - for n, v := range values { - fmt.Printf("\t#%d: %v\n", n, v) - } -} - -func partPath6(msg []byte) { - fmt.Println("\nmsg:", string(msg)) - m, _ := mxj.NewMapXml(msg) - fmt.Println("m:", m.StringIndent()) - path := "*.*.*.*.*.*.*" - values, err := m.ValueForPath(path) - if err != nil { - fmt.Println("err:", err.Error()) - return - } - if values == nil { - fmt.Println("path:", path) - fmt.Println("No ClaimStatusCodesResult code records.") - return - } - fmt.Println("\nPath:", path) - fmt.Println("Number of code records:", len(values)) - for n, v := range values { - fmt.Printf("\t#%d: %v\n", n, v) - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts3.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts3.go deleted file mode 100644 index 5bfe0628c..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts3.go +++ /dev/null @@ -1,47 +0,0 @@ -// https://groups.google.com/forum/#!topic/golang-nuts/cok6xasvI3w -// retrieve 'src' values from 'image' tags - -package main - -import ( - "fmt" - "github.com/clbanning/mxj" -) - -var xmldata = []byte(` - - - - - something else - - - - - - - -`) - -func main() { - fmt.Println("xmldata:", string(xmldata)) - - // get all image tag values - []interface{} - m, merr := mxj.NewMapXml(xmldata) - if merr != nil { - fmt.Println("merr:", merr.Error()) - return - } - - // grab all values for attribute "src" - // Note: attributes are prepended with a hyphen, '-'. - sources, err := m.ValuesForKey("-src") - if err != nil { - fmt.Println("err:", err.Error()) - return - } - - for _, src := range sources { - fmt.Println(src) - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts4.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts4.go deleted file mode 100644 index 5ad4f9df3..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts4.go +++ /dev/null @@ -1,50 +0,0 @@ -// https://groups.google.com/forum/#!topic/golang-nuts/-N9Toa6qlu8 -// shows that you can extract attribute values directly from tag/key path. -// NOTE: attribute values are encoded by prepending a hyphen, '-'. - -package main - -import ( - "fmt" - "github.com/clbanning/mxj" -) - -var xmldata = []byte(` - - - - - - - - - - - - - - - - - - `) - -func main() { - fmt.Println("xmldata:", string(xmldata)) - - m, merr := mxj.NewMapXml(xmldata) - if merr != nil { - fmt.Println("merr:", merr) - return - } - - // Attributes are keys with prepended hyphen, '-'. - values, err := m.ValuesForPath("doc.some_tag.geoInfo.country.-name") - if err != nil { - fmt.Println("err:", err.Error()) - } - - for _, v := range values { - fmt.Println("v:", v) - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts5.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts5.go deleted file mode 100644 index a1b8d16a5..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts5.go +++ /dev/null @@ -1,75 +0,0 @@ -// gonuts5.go - from https://groups.google.com/forum/#!topic/golang-nuts/MWoYY19of3o -// problem is to extract entries from by "int name=" - -package main - -import ( - "fmt" - "github.com/clbanning/mxj" -) - -var xmlData = []byte(` - - - - - - - 1 - - - - 1 - 2 - 3 - 4 - 5 - - - - - 1 - 2 - 3 - 4 - 5 - - - - -`) - -func main() { - // parse XML into a Map - m, merr := mxj.NewMapXml(xmlData) - if merr != nil { - fmt.Println("merr:", merr.Error()) - return - } - - // extract the 'list3-1-1-1' node - there'll be just 1? - // NOTE: attribute keys are prepended with '-' - lstVal, lerr := m.ValuesForPath("*.*.*.*.*", "-name:list3-1-1-1") - if lerr != nil { - fmt.Println("ierr:", lerr.Error()) - return - } - - // assuming just one value returned - create a new Map - mv := mxj.Map(lstVal[0].(map[string]interface{})) - - // extract the 'int' values by 'name' attribute: "-name" - // interate over list of 'name' values of interest - var names = []string{"field1", "field2", "field3", "field4", "field5"} - for _, n := range names { - vals, verr := mv.ValuesForKey("int", "-name:"+n) - if verr != nil { - fmt.Println("verr:", verr.Error(), len(vals)) - return - } - - // values for simple elements have key '#text' - // NOTE: there can be only one value for key '#text' - fmt.Println(n, ":", vals[0].(map[string]interface{})["#text"]) - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts5a.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts5a.go deleted file mode 100644 index de60688fa..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts5a.go +++ /dev/null @@ -1,75 +0,0 @@ -// gonuts5.go - from https://groups.google.com/forum/#!topic/golang-nuts/MWoYY19of3o -// problem is to extract entries from by "int name=" - -package main - -import ( - "fmt" - "github.com/clbanning/mxj" -) - -var xmlData = []byte(` - - - - - - - 1 - - - - 1 - 2 - 3 - 4 - 5 - - - - - 1 - 2 - 3 - 4 - 5 - - - - -`) - -func main() { - // parse XML into a Map - m, merr := mxj.NewMapXml(xmlData) - if merr != nil { - fmt.Println("merr:", merr.Error()) - return - } - - // extract the 'list3-1-1-1' node - there'll be just 1? - // NOTE: attribute keys are prepended with '-' - lstVal, lerr := m.ValuesForPath("*.*.*.*.*", "-name:list3-1-1-1") - if lerr != nil { - fmt.Println("ierr:", lerr.Error()) - return - } - - // assuming just one value returned - create a new Map - mv := mxj.Map(lstVal[0].(map[string]interface{})) - - // extract the 'int' values by 'name' attribute: "-name" - // interate over list of 'name' values of interest - var names = []string{"field1", "field2", "field3", "field4", "field5"} - for _, n := range names { - vals, verr := mv.ValuesForKey("*", "-name:"+n) - if verr != nil { - fmt.Println("verr:", verr.Error(), len(vals)) - return - } - - // values for simple elements have key '#text' - // NOTE: there can be only one value for key '#text' - fmt.Println(n, ":", vals[0].(map[string]interface{})["#text"]) - } -} diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts6.go b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts6.go deleted file mode 100644 index 56b3d29e2..000000000 --- a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/gonuts6.go +++ /dev/null @@ -1,43 +0,0 @@ -/* https://groups.google.com/forum/#!topic/golang-nuts/EMXHB1nJoBA - -package main - -import "fmt" -import "encoding/json" - -func main() { - var v struct { - DBInstances []struct { - Endpoint struct { - Address string - } - } - } - json.Unmarshal(s, &v) - fmt.Println(v.DBInstances[0].Endpoint.Address) -} -*/ - -package main - -import "fmt" -import "github.com/clbanning/mxj" - -func main() { - m, err := mxj.NewMapJson(s) - if err != nil { - fmt.Println("err:", err.Error()) - } - v, err := m.ValuesForKey("Address") - // v, err := m.ValuesForPath("DBInstances[0].Endpoint.Address") - if err != nil { - fmt.Println("err:", err.Error()) - } - if len(v) > 0 { - fmt.Println(v[0].(string)) - } else { - fmt.Println("No value.") - } -} - -var s = []byte(`{ "DBInstances": [ { "PubliclyAccessible": true, "MasterUsername": "postgres", "LicenseModel": "postgresql-license", "VpcSecurityGroups": [ { "Status": "active", "VpcSecurityGroupId": "sg-e72a4282" } ], "InstanceCreateTime": "2014-06-29T03:52:59.268Z", "OptionGroupMemberships": [ { "Status": "in-sync", "OptionGroupName": "default:postgres-9-3" } ], "PendingModifiedValues": {}, "Engine": "postgres", "MultiAZ": true, "LatestRestorableTime": "2014-06-29T12:00:34Z", "DBSecurityGroups": [ { "Status": "active", "DBSecurityGroupName": "production-dbsecuritygroup-q4f0ugxpjck8" } ], "DBParameterGroups": [ { "DBParameterGroupName": "default.postgres9.3", "ParameterApplyStatus": "in-sync" } ], "AutoMinorVersionUpgrade": true, "PreferredBackupWindow": "06:59-07:29", "DBSubnetGroup": { "Subnets": [ { "SubnetStatus": "Active", "SubnetIdentifier": "subnet-34e5d01c", "SubnetAvailabilityZone": { "Name": "us-east-1b", "ProvisionedIopsCapable": false } }, { "SubnetStatus": "Active", "SubnetIdentifier": "subnet-50759d27", "SubnetAvailabilityZone": { "Name": "us-east-1c", "ProvisionedIopsCapable": false } }, { "SubnetStatus": "Active", "SubnetIdentifier": "subnet-450a1f03", "SubnetAvailabilityZone": { "Name": "us-east-1d", "ProvisionedIopsCapable": false } } ], "DBSubnetGroupName": "default", "VpcId": "vpc-acb86cc9", "DBSubnetGroupDescription": "default", "SubnetGroupStatus": "Complete" }, "SecondaryAvailabilityZone": "us-east-1b", "ReadReplicaDBInstanceIdentifiers": [], "AllocatedStorage": 15, "BackupRetentionPeriod": 1, "DBName": "deis", "PreferredMaintenanceWindow": "fri:05:52-fri:06:22", "Endpoint": { "Port": 5432, "Address": "production.cfk8mskkbkeu.us-east-1.rds.amazonaws.com" }, "DBInstanceStatus": "available", "EngineVersion": "9.3.3", "AvailabilityZone": "us-east-1c", "DBInstanceClass": "db.m1.small", "DBInstanceIdentifier": "production" } ] }`) diff --git a/Godeps/_workspace/src/github.com/clbanning/mxj/examples/metrics_data.zip b/Godeps/_workspace/src/github.com/clbanning/mxj/examples/metrics_data.zip deleted file mode 100644 index 3868374914550ddff99b047e8da477fc0825c01d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 983854 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
W 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

7W)yr#KW5k;9+;JaxK2`X3$?J5-0gp_ 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

3&CwIkZI5B|q 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


9+!qM{1q0#*XOqJ7F}B)5*>v5&KOd_M7nbn}qFm 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%0DZP4Ygs>7}HL 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

b)vT=)S>6e|uu31ivc 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ð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